- 虽然在做项目中不会刻意区分这些东西,但又貌似无处不在,因此感觉对他们是即熟悉又不熟悉。
- 该文章的绝大部分是参考WEB 前端模块化都有什么?,我按照我自己的理解整理出该文章
CommonJS
场景
非浏览起-同步
API
module.exports
:导出模块exports
:是module.exports的引用,建议在单一文件中做导出时只使用两者其一,主要是担心手误互相覆盖。require
:导入模块
特点
-
输出module.exports可以得知他本身是个对象,所以CommonJS导出的内容只能包含在一个对象中
// index.js console.log(module); // 输出 { id: '/Users/GG/Desktop/code/index.js', exports: {}, parent: { module }, // 调用该模块的模块,可以根据该属性查找调用链 filename: '/Users/x/Documents/code/demo/index.js', loaded: false, children: [...], paths: [...] }
-
导出的内容是值拷贝
// 值拷贝 vs 引用 // CommonJS let a = 1; exports.a = a; exports.add = () => { a++; }; const { add, a } = require('./a.js'); add(); console.log(a); // 1 // ES6 export const a = 1; export const add = () => { a++; }; import { a, add } from './a.js'; add(); console.log(a); // 2
ES6
场景
浏览器-异步
API
export
:导出模块default export
:默认导出的模块import
:导入模块
特点
-
ES6模块的加载是通过
静态解析
(说实话我不懂?),下面附上网上的一段解释:静态解析,什么是的静态解析呢?区别于 CommonJS 的模块实现,ES6 的模块并不是一个对象,而只是代码集合。也就是说,ES6 不需要和 CommonJS 一样,需要把整个文件加载进去,形成一个对象之后,才能知道自己有什么,而是在编写代码的过程中,代码是什么,它就是什么。
-
导出的内容是引用,回顾上面值拷贝拷贝的示例
-
相对于commonJS只能导出对象,ES6模块系统可以任意类型(至少我还没有碰到不能导出的类型)
AMD/CMD
因为基本已经过时,就不想做过多赘述,但为了避免以后某些场景被问到,还是写点什么吧
场景
- 两者都是用于浏览器异步场景
依赖方式
- AMD是依赖前置:当模块被加载就会执行
- CDM是就近依赖:当模块接在是不会被执行,碰到require时才会被执行
定义方式
通过下面代码也可以查看出前面提到依赖方式的差异
-
AMD
// hello.js define(function() { console.log('hello init'); return { getMessage: function() { return 'hello'; } }; }); // world.js define(function() { console.log('world init'); }); // main define(['./hello.js', './world.js'], function(hello) { return { sayHello: function() { console.log(hello.getMessage()); } }; }); // 输出 // hello init // world init
-
CMD
// hello.js define(function(require, exports) { console.log('hello init'); exports.getMessage = function() { return 'hello'; }; }); // world.js define(function(require, exports) { console.log('world init'); exports.getMessage = function() { return 'world'; }; }); // main define(function(require) { var message; if (true) { message = require('./hello').getMessage(); } else { message = require('./world').getMessage(); } }); // 输出 // hello init