模块化(CommonJs、AMD、CMD、UMD)发展历史和优缺点

全文主要整理自摘自《Webpack国语指南》(好文,建议直接去看,以下但对拖欠系列文章被的《历史前进》篇幅进行备份——也整理了点其它情节)

模块化

模块化是外常讲了,这里不开阐述。

模块化管理亟待持有:

    1. 定义封装的模块。

    2. 概念新模块对另模块的倚重。

    3. 可是针对其余模块的引入支持。

如通用,则须使产生规范化,因此等同系列之标准应运而生。

现状

陪伴在走互联的大潮,当今更进一步多的网站曾起网页模式发展到了 Webapp
模式。它们运行于当代之高级浏览器里,使用 HTML5、 CSS3、 ES6
等创新的技艺来开丰富的效应,网页都不仅仅是水到渠成浏览的核心需要,并且webapp通常是一个单页面应用,每一个视图通过异步的道加载,这致使页面初始化和采用过程遭到会加载越来越多的
JavaScript 代码,这给前端开发的流程与资源集团带来了高大的挑战。

前端开发和任何开支工作的基本点分,首先是前者是根据多语言、多层次之编码和团伙工作,其次前端产品的交由是根据浏览器,这些资源是经增量加载的点子运行至浏览器端,如何以支付条件集团好这些碎片化的代码和资源,并且保证她们以浏览器端快速、优雅的加载与翻新,就用一个模块化系统,这个可以被之模块化系统是前者工程师多年来一直追之难题。

模块系统的形成

模块系统首要解决模块的定义、依赖与导出,先来探视就存在的模块系统。

<script>标签

<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="libraryA.js"></script>
<script src="module3.js"></script>

就是最为老的 JavaScript
文件加载方式,如果将各级一个文本作为是一个模块,那么她们的接口通常是暴露于全局意图域下,也便是概念在 window 对象吃,不同模块的接口调用都是一个意域中,一些犬牙交错的框架,会下命名空间的概念来集团这些模块的接口,典型的例子如 YUI 库。

这种原始之加载方式暴露了部分明白的流弊:

  • 大局意图域下容易导致变量冲突
  • 文本只能按照 <script> 的书顺序进行加载
  • 开发人员必须主观解决模块和代码库的负关系
  • 当大型项目中各种资源难以管理,长期积累的题材造成代码库混乱不堪

CommonJS

历史

  2009年1月,Mozilla 的工程师 Kevin Dangoor
创建了之类型,当时底讳是 ServerJS。其是为在浏览器环境外构建
JavaScript 生态系统为对象一旦有的项目,比如在服务器和桌面环境中。

  2009年8月,这个类型改名为 CommonJS,以显示其 API 的再常见实用性。

  2013年5月,Node.js 的担保管理器 NPM 的撰稿人 Isaac Z. Schlueter
说 CommonJS 已经不合时宜,Node.js
的水源开发者现已废弃了拖欠专业。

定义

  服务器端的 Node.js
遵循 CommonJS规范,该标准的核心思想是允许模块通过 require 方法来一起加载所而乘之其它模块,然后通过 exports 或 module.exports 来导出需要暴露的接口。

  require("module");
  require("../file.js");
  exports.doStuff = function() {};
  module.exports = someValue;

优点:

  • 服务器端模块便于重用
  • NPM 中已有靠近20万只可行使模块包
  • 简单易行并易使

缺点:

  • 齐的模块加载方式不抱在浏览器环境遭到,同步意味着阻塞加载,浏览器资源是异步加载的
  • 匪可知非阻塞的交互加载多个模块

实现:

  • 劳务器端的 Node.js
  • Browserify,浏览器端的 CommonJS
    实现,可以动用 NPM 的模块,但是编译打包后的文件体积可能非常特别
  • modules-webmake,类似Browserify,还不如
    Browserify 灵活
  • wreq,Browserify 的前身

 

AMD

AMD(异步模块定义)是吧浏览器环境设计之,因为 CommonJS
模块系统是同台加载的,当前浏览器环境还没未雨绸缪好合加载模块的基准。

AMD 定义了平等仿照 JavaScript 模块依赖异步加载标准,来解决并加载的题目。

Asynchronous Module
Definition 规范其实仅仅来一个重要接口 define(id?, dependencies?, factory),它若于声明模块的时候指定所有的负 dependencies,并且还要当形参传到 factory 中,对于因之模块提前实施,依赖前置。

define("module", ["dep1", "dep2"], function(d1, d2) {
  return someExportedValue;
});
require(["module", "../file"], function(module, file) { /* ... */ });

优点:

  • 可当浏览器环境面临异步加载模块
  • 足并行加载多个模块

缺点:

  • 加强了开发成本,代码的看和开比较不方便,模块定义方式的语义不尽如人意
  • 勿入通用的模块化思维方式,是平栽妥协的实现

实现:

  • RequireJS
  • curl

CMD

Common Module
Definition 规范及
AMD 很一般,尽量保障简单,并和 CommonJS 和 Node.js 的 Modules
规范保障了十分怪的兼容性。

define(function(require, exports, module) {
  var $ = require('jquery');
  var Spinning = require('./spinning');
  exports.doSomething = ...
  module.exports = ...
})

优点:

  • 凭借就近,延迟执行
  • 得生易当 Node.js 中运作

缺点:

  • 依靠 SPM 打包,模块的加载逻辑偏重

实现:

  • Sea.js
  • coolie

UMD

Universal Module
Definition 规范类于兼容 CommonJS 和 AMD
的语法糖,是模块定义之跨平台解决方案。

ES6 模块

EcmaScript6 标准增加了 JavaScript 语言层面的模块体系定义。ES6
模块的统筹思想,是尽量的静态化,使得编译时就是能够确定模块的负关系,以及输入和输出的变量。CommonJS
和 AMD 模块,都只好在运转时规定这些东西。

import "jquery";
export function doStuff() {}
module "localModule" {}

优点:

  • 善进行静态分析
  • 面向未来的 EcmaScript 标准

缺点:

  • 原生浏览器端还没有落实该专业
  • 新的命令字,新本子的 Node.js才支撑

实现:

  • Babel

但愿之模块系统

好兼容多种模块风格,尽量可以使用已有些代码,不仅仅只是 JavaScript
模块化,还有 CSS、图片、字体等资源也待模块化。

前端模块加载

前端模块要当客户端着推行,所以他们要增量加载到浏览器中。

模块的加载与导,我们先是会想到两种最的法门,一栽是每个模块文件还单身请求,另一样栽是把有模块于包改成一个文书然后就请一软。显而易见,每个模块都提倡单独的求造成了央次数过多,导致应用启动速度缓慢;一赖呼吁加载所有模块导致流量浪费、初始化过程慢。这简单种植艺术还未是好之化解方案,它们过于简单粗暴。

分块传输,按需进行懒加载,在其实用到一些模块的时更增量更新,才是比较合理之模块加载方案。

如果实现模块的照需加载,就需一个针对普代码库中之模块进行静态分析、编译打包的长河。

怀有资源且是模块

每当面的分析过程遭到,我们涉的模块仅仅是指JavaScript模块文件。然而,在前端开发过程遭到还干到样式、图片、字体、HTML
模板等等众多底资源。这些资源还见面因为各种方言的款型在,比如
coffeescript、 less、 sass、众多的模板库、多语言体系(i18n)等等。

一经她们还可以当模块,并且都得以通过require的措施来加载,将带优雅的付出体验,发展历史比如:

require("./style.css");
require("./style.less");
require("./template.jade");
require("./image.png");

这就是说什么样完成让 require 能加载各种资源也?

静态分析

在编译的时,要针对合代码进行静态分析,分析出各个模块的项目和她凭借关系,然后拿不同种类的模块提交给适配的加载器来处理。比如一个因此
LESS 写的体模块,可以预先用 LESS 加载器将它改变成为一个CSS 模块,在经 CSS
模块把他插入到页面的 <style> 标签中执行。Webpack
就是于这样的需中冒出。

再就是,为了能使曾有的各种框架、库和已勾勒好的文件,我们尚需一个模块加载的匹配策略,来避免再次写有的模块。

那么接下,让咱开 Webpack 的神奇的一起吧。

发表评论

电子邮件地址不会被公开。 必填项已用*标注