日记

日记

  • Diary
  • GitHub

›All Blog Posts

All Blog Posts

  • 再看高程3
  • 面试
  • 个人简历
  • react的高性能
  • webpack源码学习
  • 树莓派
  • 布局
  • 模块化
  • 攻击与安全
  • 异步
  • TODO
  • React状态管理比较
  • 性能优化
  • HTTP缓存
  • (译)JS中数据的改变与发现
  • CSS杂记
  • XML与SVG
  • 个人简历
  • Workspaces是什么
  • NPM包测试之低高级策略
  • 谈谈version
  • 减肥之道
  • 问题汇总
  • 一个nginx配置
  • 好用的工具
  • 好用的npm包
  • 流行框架学习对比

模块化

June 25, 2018

Shiyong Yin

无模块化的时代

开始的开始,我们都是孩子。

最开始是没有模块化这一说的,都是script标签异步引入。

CommonJS

服务端的JavaScript——Nodejs使用了CommonJS并将其发扬光大,这标志着JavaScript模块化正式登上历史的舞台。

  1. 定义模块
    • 每个文件就是一个模块,每个模块都是一个单独的作用域
  2. 模块输出
    • 模块只有一个出口module.exports
  3. 加载模块
    • require('lodash')

我们发现require是同步的。模块系统需要同步读取模块文件内容,并编译执行以得到模块接口。 这在服务器端实现很简单,也很自然,然而, 想在浏览器端实现问题却很多。

AMD

Asynchronous Module Definition

AMD规范的代表作就是requirejs。

requirejs解决了两个问题:

  1. 多依赖问题——多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
  2. 阻塞问题——js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长
// 定义模块 myModule.js
define(['dependency'], function(){
    var name = 'Byron';
    function printName(){
        console.log(name);
    }

    return {
        printName: printName
    };
});

// 加载模块
require(['myModule'], function (my){
  my.printName();
});

require()函数在加载依赖的函数的时候是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。

CMD

Common Module Definition

CMD规范的代表作就是seajs。

seajs解决的问题和requirejs是一样的。多依赖问题和阻塞问题。

// 定义模块  myModule.js
define(function(require, exports, module) {
  var $ = require('jquery.js')
  $('div').addClass('active');
});

// 加载模块
seajs.use(['myModule.js'], function(my){

});

seajs原理参阅:

  • https://www.cnblogs.com/ada-zheng/p/4330506.html
  • https://www.cnblogs.com/jfmblog/p/5650979.html

AMD与CMD区别

下面的例子一目了然

/** AMD写法 **/
define(["a", "b", "c", "d", "e", "f"], function(a, b, c, d, e, f) { 
     // 等于在最前面声明并初始化了要用到的所有模块
    a.doSomething();
    if (false) {
        // 即便没用到某个模块 b,但 b 还是提前执行了
        b.doSomething()
    } 
});

/** CMD写法 **/
define(function(require, exports, module) {
    var a = require('./a'); //在需要时申明
    a.doSomething();
    if (false) {
        var b = require('./b');
        b.doSomething();
    }
});

最明显的区别是

  • AMD依赖前置
  • CMD依赖就近

AMD在模块加载完成后就会执行该模块,所有模块加载完成进入回调函数,执行主逻辑。 这个就导致了,依赖执行的顺序和加载的顺序不一致。完全取决于哪个先下载下来。

CMD加载摸个依赖后并不执行,只是下载而已。所有依赖加载完成后进入主逻辑,遇到require才执行 对应的模块,这样模块的执行顺序和书写顺序完全一致。

ES6 Module

这个其实就是类似CommonJS了,同步的。

Recent Posts
  • 无模块化的时代
  • CommonJS
  • AMD
  • CMD
  • AMD与CMD区别
  • ES6 Module
Copyright © 2018-2019 Shiyong Yin