* module对象的属性:
1. id: 模块的标识符,通常是带有绝对路径的模块文件名
2. filename: 模块的文件名,带有绝对路径
3. loaded:布尔值,表示模块是否已经被加载完成成
4. parent:一个对象,表示调用该模块的模块
5. children:一个数组,表示该模块要用到的其它模块
6. exports:一个对象,表示模块对外输出的值它使用module.exports导出一个模块,通过require导入模块。
// CommonJS
// a.js
let a = 1;
let b = 2;
module.exports = {
x: a,
y: b
}
// or
exports.x = a;
exports.y = b;
// b.js
const a = require('./a')
console.log(a); // { a: 1, b: 2 }
直到2015,es6定义了js模块标准(ESM),使之有了模块的概念。
// a.js
// 这种是静态导入
import {a, b} from './b.js'
console.log(a) // 1
console.log(b); // 2
// b.js
let a = 1;
let b = 2;
export { a, b }
<!-- 静态导入的html -->
<body>
<!-- 不能通过打开本地文件的形式打开html,会提示跨域,要通过服务器的方式打开 -->
<!-- 可以安装插件:Live Server,然后右击以“live server方式”打开文件 -->
<script src="./a.js" type="module"></script>
</body>
ESM对比commonjs的优势:
es6目前已经得到大多现代浏览器支持,但在应用中还需要等待一段时间,原因:
所以就诞生了模块打包工具(module bundle):
比较出名的:
在ES6模块出现之前,AMD(异步模块定义)是一种很热门地浏览器模块化方案。
1. 第1个为id,模块的名称;
2. 第2个为数组,它定义了所依赖的模块,依赖的模块必须根据模块工厂函数优先级执行,并且执行的结果应该按照数组中的位置顺序以参数的形式传入工厂函数中
3. 第3个factory为模块初始化要执行的函数或对象。如果是函数,则是单例模式,只会被执行一次;如果是对象,则此对象为模块的输出值。
define(id?, dependencies?, factory)
// 比如:
// 1. 定义了一个叫alpha的模块
// 2. 它依赖了require,exports,beta三个模块
// 3. 它导出了verb函数
define("alpha", ["require", "exports", "beta"], function(require, exports, beta) {
exports.verb = function() {
return beta.verb();
}
})
CMD(common module definition,通用模块定义),它是基于浏览器环境制定的模块规范。
define(fatory)
// 如果参数是函数
// 第1个参数为require,用来引用其它模块,也可以调用require.async函数来异步调用模块
// 第2个参数为exports,是个对象,当定义模块时,需要通过向参数exports添加属性来导出模块API
// 第3个参数module是一个对象,它包含3个属性:uri模块完整的路径;dependencies,模块的依赖;exports,模块需要被导出的API,作用同第二个参数
define(function(require, exports, module) {
// 导入的模块
var add = require('math').add;
// 定义导出的对象
exports.increment = function(val) {
return add(val, 1)
}
// 定义当前模块的信息,比如模块id名称
module.id = "increment"
})
universal module definition
统一模块标准,它不是模块管理规范,而是带有前后端同构思想的模块封装工具。通过UMD可以在不同环境选择对应的模块规范。比如nodejs使用commonjs,在浏览器下支持AMD的,采用AMD模块,否则导出为全局函数。
它的实现原理:
function test() {
let a = 1;
let b = 2;
return { a, b}
}
// AMD规范环境
if(typeof define === 'function' && define.amd) {
define(test)
// 如果commonjs环境
}else if(typeof module === 'object' && typeof module.exports === "object") {
module.exports = test()
// 不使用任何模块系统,直接挂载到全局window上
}else {
window.test = test;
}
// 以上可以优化成:
(function(root, callback) {
// AMD规范环境
if(typeof define === 'function' && define.amd) {
define(callback)
// 如果commonjs环境
}else if(typeof module === 'object' && typeof module.exports === "object") {
module.exports = callback()
// 不使用任何模块系统,直接挂载到全局this上,因为全局变量不一定就是window,也有可能是global,所以用this指向当前全局环境
}else {
root.test = callback;
}
})(this, function() {
let a = 1;
let b = 2;
return { a, b}
})
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。