提高历史与优缺点

全文首要整理自摘自《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

历史

  二〇〇九年四月,Mozilla 的工程师 Kevin Dangoor
成立了这一个项目,当时的名字是 ServerJS。其是以在浏览器环境之外构建
JavaScript 生态系统为目标而爆发的花色,比如在服务器和桌面环境中。

  二零零六年1四月,这么些类型改名为 CommonJS,以体现其 API 的更广泛实用性。

  二零一三年九月,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) { /* ... */ });

优点:

  • 适合在浏览器环境中异步加载模块
  • 可以相互加载多少个模块

缺点:

  • 增长了开发成本,代码的读书和书写比较劳碌,模块定义模式的语义不顺手
  • 不符合通用的模块化思维方法,是一种妥协的兑现

实现:

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 打包,模块的加载逻辑偏重

实现:

UMD

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

ES6 模块

EcmaScript6 标准扩充了 JavaScript 语言层面的模块体系定义。ES6
模块
的筹划思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和出口的变量。CommonJS
和 AMD 模块,都不得不在运作时规定那么些东西。

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

优点:

  • 容易举行静态分析
  • 面向将来的 EcmaScript 标准

缺点:

  • 原生浏览器端还未曾兑现该标准
  • 全新的命令字,新版的 Node.js才支撑

实现:

盼望的模块系统

可以配合多种模块风格,尽量可以采纳已有的代码,不仅仅只是 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 的神奇之旅吧。

发表评论

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