Open felix-cao opened 6 years ago
前端开发有其自身的特点:
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
webpack
JavaScript
module bundler
dependency graph
bundle
那么什么是模块呢?
在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块
每个模块具有比完整程序更小的接触面,使得校验、调试、测试轻而易举。 精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的
模块系统主要解决模块的定义、依赖和导出,先来看看已经存在的模块系统。
通过多个 script 标签引入多个 js 文件,也即通过文件的方式来管理模块。
script
js
<script src="Jquery.js"></script> <script src="d3.js"></script> <script src="moment.js"></script> <script src="lodash.js"></script>
这种原始的方案有很多显而易见的弊端:
CommonJS 的模块方案是通过 require 同步加载依赖的其他模块,通过 exports 或 module.exports 来暴露出需要的接口。 (了解更多请移步 CommonJS模块规范)
CommonJS
require
exports
module.exports
这种原始的方案的优点:
这种原始的方案的弊端:
AMD 模块,全称为 Asynchromous Module Defination,翻译过来就是异步模块规范,它是由 RequireJs 推动的。
AMD
Asynchromous Module Defination
RequireJs
AMD 方案只有一个主要接口 define(moduleName, dependencies, factory),他要在声明模块的时候指定所有的依赖 dependencies,并传入到 factory 中,对于依赖的模块异步加载并执行。
define(moduleName, dependencies, factory)
dependencies
factory
// 定义 define("mymodule", ["dep1", "dep2"], function(d1, d2) { }); // 加载 require(["module", "../file"], function(module, file) { });
ES6模块方案最大的特点就是静态化,静态化的优势在于可以在编译的时候确定模块的依赖关系以及输入输出的变量。上面提到的 CommonJS 模块和 AMD 模块都只能在运行时确定这些东西。
ES5
webpack 并不强制你使用某种模块化方案,而是通过兼容所有模块化方案让你无痛接入项目,当然这也是 webpack 牛逼的地方。 有了 webpack,你可以随意选择你喜欢的模块化方案,至于怎么处理模块之间的依赖关系及如何按需打包,放轻松,webpack 会帮你处理好的。
js/css/
本来,模块化方案仅仅是针对 JS。但实际项目中,我们希望 css 也能被当做模块,进一步,css/less/sass 是不是也可以被当做模块,再进一步,html/image/template 是不是也可以被当做模块。
JS
css
css/less/sass
html/image/template
想到这些就觉得脑洞大开,不可思议!但是 webpack 居然做到了!webpack 提供的 loaders 可以对文件做预处理,从而实现了一切皆模块。
loaders
一、简述
前端开发有其自身的特点:
本质上,
webpack
是一个现代JavaScript
应用程序的静态模块打包器(module bundler
)。当webpack
处理应用程序时,它会递归地构建一个依赖关系图(dependency graph
),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle
。那么什么是模块呢?
在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块
每个模块具有比完整程序更小的接触面,使得校验、调试、测试轻而易举。 精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的
二、模块系统的演进
模块系统主要解决模块的定义、依赖和导出,先来看看已经存在的模块系统。
2.1、非模块
通过多个
script
标签引入多个js
文件,也即通过文件的方式来管理模块。这种原始的方案有很多显而易见的弊端:
script
标签的顺序,多页应用更惨。2.2、CommonJS 模块
CommonJS
的模块方案是通过require
同步加载依赖的其他模块,通过exports
或module.exports
来暴露出需要的接口。 (了解更多请移步 CommonJS模块规范)这种原始的方案的优点:
这种原始的方案的弊端:
2.3、AMD 模块
AMD
模块,全称为Asynchromous Module Defination
,翻译过来就是异步模块规范,它是由RequireJs
推动的。AMD
方案只有一个主要接口define(moduleName, dependencies, factory)
,他要在声明模块的时候指定所有的依赖dependencies
,并传入到factory
中,对于依赖的模块异步加载并执行。这种原始的方案的优点:
这种原始的方案的弊端:
2.4、ES6 模块
ES6模块方案最大的特点就是静态化,静态化的优势在于可以在编译的时候确定模块的依赖关系以及输入输出的变量。上面提到的
CommonJS
模块和AMD
模块都只能在运行时确定这些东西。这种原始的方案的优点:
这种原始的方案的弊端:
ES5
。三、webpack 的模块化
3.1、webpack 模块化机制
webpack
并不强制你使用某种模块化方案,而是通过兼容所有模块化方案让你无痛接入项目,当然这也是webpack
牛逼的地方。 有了webpack
,你可以随意选择你喜欢的模块化方案,至于怎么处理模块之间的依赖关系及如何按需打包,放轻松,webpack
会帮你处理好的。3.2、 webpack 的模块化有什么特点?
js/css/
图片/字体都是模块。JavaScript
的多种模块风格,无痛迁移老项目。本来,模块化方案仅仅是针对
JS
。但实际项目中,我们希望css
也能被当做模块,进一步,css/less/sass
是不是也可以被当做模块,再进一步,html/image/template
是不是也可以被当做模块。想到这些就觉得脑洞大开,不可思议!但是
webpack
居然做到了!webpack
提供的loaders
可以对文件做预处理,从而实现了一切皆模块。Reference