模块化之前的痛点

  1. 命名空间冲突
  2. 无法合理的管理项目的依赖和版本
  3. 无法方便的控制依赖的加载顺序
  4. **

    Javascript包管理规范

    CommonJS

    通过 require 来引入模块,通过 module.exports 定义模块的输出接口
    module.exports = … 只能输出一个,且后面的会覆盖上面的
    exports. … 可以输出多个
    运行阶段确定接口,运行时才会加载模块
    模块是对象,加载的是该对象
    加载的是整个模块,即将所有的接口全部加载进来
    输出是值的拷贝,即原来模块中的值改变不会影响已经加载的值

以同步的方式来引入模块
适用于服务器端
this 指向当前模块

ES6

使用 import 和 export 的形式来导入导出模块
export 可以输出多个,输出方式为 {}
export default 只能输出一个,可以与export 同时输出
解析阶段确定对外输出的接口,解析阶段生成接口
模块不是对象,加载的不是对象,是一个只读引用
等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值
可以单独加载其中的某个接口(方法)
静态分析,动态引用,输出的是值的引用,值改变,引用也改变
this 指向undefined 

AMD

用define()函数定义模块
异步加载的方式来加载模块
可并行加载多个依赖
缺点是浏览器没有原生支持AMD规范,需要先导入实现AMD规范的库才能使用
模块语句定义在回调函数里,等到加载完成后再执行回调函数

AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块
AMD 在依赖模块加载完成后就直接执行依赖模
require.js 实现了 AMD 规范

  1. define(["./a", "./b"], function(a, b) {
  2. // 依赖必须一开始就写好
  3. a.doSomething();
  4. b.doSomething();
  5. });

AMD规范允许输出的模块兼容CommonJS规范

  1. define(function (require, exports, module){
  2. var someModule = require("someModule");
  3. var anotherModule = require("anotherModule");
  4. someModule.doTehAwesome();
  5. anotherModule.doMoarAwesome();
  6. exports.asplode = function (){
  7. someModule.doTehAwesome();
  8. anotherModule.doMoarAwesome();
  9. };
  10. });

CMD

对依赖的处理不同
对依赖模块的执行时机不同
在依赖模块加载完成后并不执行,只是下载而已,等到所有的依赖模块都加载好后,进入回调函数逻辑
遇到 require 语句 的时候才执行对应的模块
模块的执行顺序和书写顺序保持一致
sea.js 实现了 CMD 规范

  1. define(function(require, exports, module) {
  2. // 依赖可以就近书写,控制模块的执行顺序
  3. var a = require("./a");
  4. a.doSomething();
  5. var b = require("./b");
  6. b.doSomething();
  7. // ...
  8. });

RequireJS

实现js文件的异步加载,避免网页失去响应
管理模块之间的依赖性,便于代码的编写和维护
动态创建 script 脚本来异步引入模块,然后对每个脚本的 load 事件进行监听,如果每个脚本都加载完成了,再调用回调函数

  1. node = document.createElement("script");
  2. node.id = modName;
  3. node.type = "text/javascript";
  4. node.charset = "utf-8";
  5. node.async = true;
  6. node.src = url;
  7. fs = document.getElementsByTagName("script")[0];
  8. fs.parentNode.insertBefore(node, fs);
  9. node.onload=function(){
  10. const moduleName=node.getAttribute('data-requiremodule')
  11. catch[moduleName]=getscriptData(moduleName)
  12. }

Webpack模块化机制

兼容所有模块化方案
静态解析,按需打包,动态加载