AMD、CMD、CommonJS和ES Module
AMD,异步模块加载机制。具体实现RequireJS,依赖前置,提前执行
//a.js
//define可以传入三个参数,分别是字符串-模块名、数组-依赖模块、函数-回调函数
define(function(){
return 1;
})
// b.js
//数组中声明需要加载的模块,可以是模块名、js文件路径
require(['a'], function(a){
console.log(a);// 1
});
CMD,具体实现SeaJS,依赖就近,只有到require时依赖模块才执行
CommonJS,NodeJS和Webpack的实现
- 所有代码都运行在模块作用域,不会污染全局作用域
- 模块是同步加载的,即只有加载完成,才能执行后面的操作
- 模块在首次执行后就会缓存,再次加载只返回缓存结果
//a.js
module.exports = function () {
console.log("hello world")
}
//b.js
var a = require('./a');
a();//"hello world"
//或者
//a2.js
exports.num = 1;
exports.obj = {xx: 2};
//b2.js
var a2 = require('./a2');
console.log(a2);//{ num: 1, obj: { xx: 2 } }
ES6 Module
//a.js
var name = 'lin';
var age = 13;
var job = 'ninja';
export { name, age, job};
//b.js
import { name, age, job} from './a.js';
console.log(name, age, job);// lin 13 ninja
//或者
//a2.js
export default function () {
console.log('default ');
}
//b2.js
import customName from './a2.js';
customName(); // 'default'
浏览器加载
默认情况
浏览器是同步加载JavaScript
脚本,即渲染引擎遇到<script>
标签就会停下来,等到执行完脚本,再继续向下渲染。如果是外部脚本,还必须加入脚本下载的时间
<script>
标签打开defer
或async
属性,脚本就会异步加载。defer
是“渲染完再执行”,async
是“下载完就执行”
加载ESM
<script type="module" src="./foo.js"></script>
<!-- 等同于 -->
<script type="module" src="./foo.js" defer></script>
CommonJS和ES Module的区别
-
CommonJS 模块的
require()
是同步加载模块,ES6 模块的import
命令是异步加载 -
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口
因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。
而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用
模块加载
Node.js v13.2 版本开始,Node.js 已经默认打开了 ES6 模块支持
.mjs文件总是以 ES6 模块加载,.cjs文件总是以 CommonJS 模块加载
.js文件的加载取决于package.json里面type字段的设置
cjs加载esm
(async () => {
await import('./my-app.mjs');
})();
esm加载cjs
// 正确
import packageMain from 'commonjs-package';
// 报错
import { method } from 'commonjs-package';
参考
阮一峰ECMScript6中Module的加载
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!