一、AMD, CommonJS, CMD, UMD, ES6 分析
插一句:Rollup 是一个打包ES Module 的工具
-
CommonJS 主要运行于服务器
-
该规范指出:一个文件就是一个模块
-
nodejs是主要实践者
-
同步加载,在服务器端没问题,在浏览器端异步加载是更好的方案
-
有四个主要的环境变量:
- module
- exports:module.exports 命令用于规范模块的对外接口,输出后就不能改变
- require:用于输入其他模块提供的功能
- global
// 模块 a.js const name = 'qiufeng' module.exports = { name, github: 'https://github.com/hua1995116' } // 模块 b.js // 引用核心模块或者第三方包模块,不需要写完整路径 const path = require('path'); // 引用自定义模块可以省略.js const { name, github } = require('./a'); console.log(name, github, path.basename(github)); // 输出 qiufeng https://github.com/hua1995116 hua1995116 -
-
AMD(Asynchronous Module Definition)异步加载模块
-
异步模式加载模块,模块的加载不影响后边语句的执行,所有依赖这个模块的语句,都在回调函数里。
-
requireJS是最佳实践者
-
依赖前置,提前执行
-
语法不直观, 没用commonJS便于书写
-
主要命令:
- define:是全局函数,用来定义模块, define(id?, dependencies?, factory)
- require:用于输入其他模块提供的功能
- define.amd:是一个对象,此属性的存在来表明函数遵循AMD规范
- return:规范模块的对外接口
文件名: foo.js define(['jquery'], function ($) { // 方法 function myFunc(){}; // 暴露公共方法 return myFunc; }); ------------------------------------------------------------------------------------- // model1.js define(function () { console.log('model1 entry'); return { getHello: function () { return 'model1'; } }; }); // model2.js define(function () { console.log('model2 entry'); return { getHello: function () { return 'model2'; } }; }); // main.js define(function (require) { var model1 = require('./model1'); console.log(model1.getHello()); var model2 = require('./model2'); console.log(model2.getHello()); }); <script src="https://cdn.bootcss.com/require.js/2.3.6/require.min.js"></script> <script> requirejs(['main']); </script> // 输出结果 // model1 entry // model2 entry // model1 // model2 -
-
CMD(Common Module Definition)通用模块定义
- Sea.js 是主要实践者
- 依赖就近、延迟执行
-
UMD:是AMD和CommonJS的统一规范,可用于多种场景,用法如下
(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD define(['jquery'], factory); } else if (typeof exports === 'object') { // Node, CommonJS之类的 module.exports = factory(require('jquery')); } else { // 浏览器全局变量(root 即 window) root.returnExports = factory(root.jQuery); } }(this, function ($) { // 方法 function myFunc(){}; // 暴露公共方法 return myFunc; })); -
ESM(ES Modules)是ES6提出的标准模块系统
- 因为是标准,未来很多浏览器支持
- 兼容在node环境下运行
- 模块的导入导出,通过 import / export来确定。 可以和commonJS模块混合使用
- ESM 输出的是值的引用,输出接口动态绑定, 而CommonJS输出的是值的拷贝
- ESM 模块编译时执行, 而CommonJS模块总是在运行时加载
-
ES6 模块编译时执行会导致有以下两个特点
- import 优先执行。
- export 命令会有变量声明提前的效果。
二、 import 和 require的区别
-
出现的事件地点不同。
- require/exports 2009 CommonJS
- import/export 2015 ES6
-
不同端的使用限制
- require/exports原生浏览器不支持,但可以使用webpack打包工具转换。
- import/export
-
require/exports 运行时动态加载,import/export 是静态编译
-
前者值的拷贝,后者值的引用