侧边栏壁纸
  • 累计撰写 47 篇文章
  • 累计创建 2 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

工程化:CommonJS、AMD、CMD和ES6 Module

一直以来,前端工程师们都在探索如何做到 JavaScript 模块化,其中以 CommonJS,AMD,CMD 为代表。
直到 ES6 Module 的出现,才从语言层面上解决了 JS 模块化的问题。

优势

避免命名冲突
依赖管理
提供可维护性和代码复用

CommonJS(面对浏览器之外的模块化规范)

CommonJS 是针对服务器或桌面应用环境下的 JavaScript 开发(非浏览器),其被 Node.js 采用为默认的模块化规范

CommonJS 有两个弊端,使其不适合浏览器环境开发:

  1. 无法处理非 JavaScript 资源(比如 CSS,图片等)。
  2. 模块是同步阻塞式加载,无法实现按需加载(像 Node.js 主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式。)。
// foobar.js
//私有变量
var test = 123;
 
//公有方法
function foobar () {
 
    this.foo = function () {
        // do someing ...
    }
    this.bar = function () {
        //do someing ...
    }
}
 
//exports对象上的方法和变量是公有的var foobar = new foobar();
exports.foobar = foobar;

// main.js
//require方法默认读取js文件,所以可以省略js后缀
var test = require('./foobar').foobar;
 
test.bar();
AMD & CMD(针对浏览器的模块化规范)

在 CommonJS 基础上,还扩展了以下功能:

  1. 可以处理 JavaScript 以外的资源。
  2. 可按需加载,可并行加载。

AMD 是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义";CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。

//AMD
define(['./a','./b'], function (a, b) {
 
    //依赖一开始就写好
    a.test();
    b.test();
});
 
//CMD
define(function (requie, exports, module) {
    //依赖可以就近书写
    var a = require('./a');
    a.test();
    ...
    //软依赖
    if (status) {
        var b = requie('./b');
        b.test();
    }
});

上面的例子可以看出两者的区别:
对于依赖的模块 AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。
CMD 推崇依赖就近,AMD 推崇依赖前置

ES6 Module - 规范的静态模块体系

ES6 Module 是语言层面的规范,与应用场景无关,完全可以取代现有的 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
目前受限与浏览器的实现程度,针对浏览器的模块化仍然需要构建工具进行编译。

ES6 Module 与 CommonJS 类似,是一种静态模块规范,不支持异步加载。 不过,结合其他框架或者构建工具(比如 React 的 lazy load,webpack 的 require.ensure)可以实现按需加载和异步加载。

// react lazy loader
const Home = React.lazy(() => import('./pages/Home'));
const Page1 = React.lazy(() => import('./pages/Page1'));
const Page2 = React.lazy(() => import('./pages/Page2'));

// webpack
window.onload =require.ensure([], require => {
  const b = require('./module.a.js');
  b()
}, 'async')
0

评论区