felix-cao / Blog

A little progress a day makes you a big success!
31 stars 4 forks source link

Webpack 入门一:模块化 #37

Open felix-cao opened 6 years ago

felix-cao commented 6 years ago

一、简述

前端开发有其自身的特点:

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

那么什么是模块呢?

在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块

每个模块具有比完整程序更小的接触面,使得校验、调试、测试轻而易举。 精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的

二、模块系统的演进

模块系统主要解决模块的定义、依赖和导出,先来看看已经存在的模块系统。

2.1、非模块

通过多个 script 标签引入多个 js 文件,也即通过文件的方式来管理模块。

<script src="Jquery.js"></script>
<script src="d3.js"></script>
<script src="moment.js"></script>
<script src="lodash.js"></script>

这种原始的方案有很多显而易见的弊端:

2.2、CommonJS 模块

CommonJS 的模块方案是通过 require 同步加载依赖的其他模块,通过 exportsmodule.exports 来暴露出需要的接口。 (了解更多请移步 CommonJS模块规范

这种原始的方案的优点:

这种原始的方案的弊端:

2.3、AMD 模块

AMD 模块,全称为 Asynchromous Module Defination,翻译过来就是异步模块规范,它是由 RequireJs 推动的。

AMD 方案只有一个主要接口 define(moduleName, dependencies, factory),他要在声明模块的时候指定所有的依赖 dependencies,并传入到 factory 中,对于依赖的模块异步加载并执行。

// 定义
define("mymodule", ["dep1", "dep2"], function(d1, d2) {
});

// 加载
require(["module", "../file"], function(module, file) {
});

这种原始的方案的优点:

这种原始的方案的弊端:

2.4、ES6 模块

ES6模块方案最大的特点就是静态化,静态化的优势在于可以在编译的时候确定模块的依赖关系以及输入输出的变量。上面提到的 CommonJS 模块和 AMD 模块都只能在运行时确定这些东西。

这种原始的方案的优点:

这种原始的方案的弊端:

三、webpack 的模块化

3.1、webpack 模块化机制

webpack 并不强制你使用某种模块化方案,而是通过兼容所有模块化方案让你无痛接入项目,当然这也是 webpack 牛逼的地方。 有了 webpack,你可以随意选择你喜欢的模块化方案,至于怎么处理模块之间的依赖关系及如何按需打包,放轻松,webpack 会帮你处理好的。

3.2、 webpack 的模块化有什么特点?

本来,模块化方案仅仅是针对 JS。但实际项目中,我们希望 css 也能被当做模块,进一步,css/less/sass 是不是也可以被当做模块,再进一步,html/image/template 是不是也可以被当做模块。

想到这些就觉得脑洞大开,不可思议!但是 webpack 居然做到了!webpack 提供的 loaders 可以对文件做预处理,从而实现了一切皆模块。

Reference