标签:name CMD 导出 AMD module js 模块 && import
概述
- 主流的前端开发范式之一
- 主流的代码组织方式,划分模块,单独维护,降低成本
模块化规范
模块化标准 + 模块化加载器
CommonJS规范 node提出的一种约定
- 一个文件是一个模块
- 每个模块都有单独的作用域
- 通过module.exports导出成员
- 通过require函数载入模块
CommonJS是以同步模式加载模块,浏览器端支持不好
AMD(Asynchronous Module Definition) 异步的模块定义规范
Require.js 实现了AMD规范,是一种模块加载器
// 定义一个模块
define('module1',['jquery','./module2'],function($,module2){
return {
start:function(){
$("body").animate({margin: '200px'})
module2()
}
}
})
// 载入一个模块
require(['./module1'],function(module1){
module1.start()
})
大多数第三方库都支持AMD规范
- AMD使用相对复杂
- 模块JS文件请求频繁
Sea.js + CMD 淘宝推出的,后来被AMD兼容
// CMD 规范 (类似CommonJS规范)
define(function(require,exports,module){
// 通过 require 引入依赖
var $ = require('jquery')
// 通过exports 或者module.exports对外暴露成员
module.exports = function(){
console.log('module 2 ~')
$('body').append('<p>module2</p>')
}
})
模块化标准实现规范
NodeJS 中一般 CommonJS
浏览器一般 ES Modules规范
commonJS是NodeJS中内置模块,直接使用导出就可以
ES Module 是ES2015 新增,开始兼容问题很多,是在语言层面实现模块化,随着webpack等打包工具,成为最广泛的模块标准
ES Module
基本特性
ES中采用严格模式,忽略 ‘use strict’
每个ES Module 都是运行在单独的私有作用域
ESM 是通过Cors 的方式请求JS模块的
ESM 的script 标签会延迟执行脚本 相当于添加了difine属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESModule.html</title>
</head>
<body>
<!-- 通过script 添加type = module 的属性,可以实现ES Module的标准执行其中JS代码 -->
<script type="module">
console.log('module1')
</script>
<!-- 1. ES中采用严格模式,忽略 'use strict' -->
<script type="module">
console.log(this)
</script>
<!-- 2. 每个ES Module 都是运行在单独的作用域 -->
<script type="module">
console.log(this)
var foo = 100;
</script>
<script type="module">
console.log(foo) //访问不到,没有全局变量污染
</script>
<!-- 3. ESM 是通过Cors 的方式请求JS模块的 -->
<script type="module" src="https://libs.baidu.com/hquery/2.0.0/jquery.min.js"></script>
<!-- 4. ESM 的script 标签会延迟执行脚本 相当于添加了difine属性 -->
<script>
// script 不添加module 会阻塞代码运行
// 添加之后会先加载代码再执行JS模块
</script>
</body>
</html>
ES Module导出
利用export关键词
export var name = 'foo module'
import {name} from './module.js'
// 导出多个
var names = 'names';
function hello(){
console.log('hello')
}
class Person{}
export {name,hello,Person}
//导出从命名
export {
name as fooName
}
import {fooName} from './module.js'
// defalut 关键词
export {
name as default // 默认导出成员
}
import {default as fooName} from './module.js' // 引入时候需要从命名
export default name // 会将 name 作为当前模块的默认导出
import fooName from './module.js' // 直接接受模块导出的默认成员,可随意取名fooName
注意项
var name = 'kack'
var age = 18
var obj = {name,age}
export {name,age} //导出的不是字面量对象,引入时候不是对象结构,导出的是对应的引用关系
// 如果导出对象,需要使用 export default ,之后可跟对象或者变量
export default {name,age}
import 的用法
import {name} from './module.js'
// from 后跟的必须是完整的路径,不能节省扩展名
console.log(name)
// 打包工商使用时才可省略扩展名
// ./ 路径不可省略
// 或者完整的路径
import {names} from 'http://loaclhost:3000/import.js'
// 只执行而不是提取某个成员,{}可为空
import {} from './module'
// 获取所有的导出成员 ,通过as 放在特殊成员之中
import * as obj from './require'
console.log(obj)
// import 只能出现在顶层,不能被包裹在作用域内
if(true){
import {name} from './require' //错误
}
// 只能通过导入函数方式,动态加载模块
import('./require') // 返回一个promise
.then(res=>console.log(res))
// 导入default需要重新命名
import {name ,age, default as newName} from './require'
// 或者
import newName,{name ,age} from './require'
导出导入成员
例如项目中多个组件,可以新建一个公共部分接受所有成员,导出
使用时节省导出
import {Button, Avatar} from './components.js'
浏览器环境 Polyfill
Polyfill兼容方案
是一个ES Module 的loader
npm install browser-es-module-loader
引入网页中
<script src="dist/babel-browser-build.js"></script>
<script src="dist/browser-es-module-loader.js"></script>
ES Module in Node.js 支持情况
node版本>8.5
node环境可以直接原生方式实现
ES Module CommonJS
common.js
CommonJS 只能导出一个默认成员
module.exports = {foo:'commonjs'}
exports.foo = 'commonjs'
//node原生 commonJS 不允许通过require 方式载入 ES Module
module.js
ES Module 中可以导入 CommonJS 模块
import mod from './common.js'
console.log(mod) //可以
不能直接提取成员,import不是对导出成员的结构
import {mod} from './common.js'
console.log(mod) //失败
- ES Module 中可以导入 CommonJS模块
- CommonJS 中不能导入 ES Module
- CommonJS 始终只会导出一个默认成员
- 注意import不是结构导出对象
标签:name,CMD,导出,AMD,module,js,模块,&&,import 来源: https://blog.csdn.net/qq_38074118/article/details/111563993
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。