[译]开启webpack之旅( 一 ):动机

原文地址css

现今Web网页正逐步向Web App进化,主要体如今:html

  • 愈来愈多依赖JavaScript的使用。node

  • 现代浏览器提供了多样化的接口。jquery

  • 更多的局部加载代替全局刷新,甚至单个页面代码量的提高。webpack

所以,客户端将承载大量代码!
大量的底层代码须要被组织。而模块系统则提供了一个能够将底层代码分割成不一样模块的方式。git

常见的模块系统风格

对于如何定义依赖与引用,存在许多不一样的标准:github

  • <script>标签(即不使用模块系统)web

  • CommonJSnpm

  • AMD及其衍生segmentfault

  • ES6模块

  • 其余

<script>标签

下面用一个例子来展现若是你不使用模块系统,你提交的底层代码模块化结构是这样的:

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

模块向全局对象(即window对象)暴露一个接口,模块经过全局对象访问依赖的接口。

缺点:

  • 全局空间的污染

  • 须要合理的加载顺序

  • 开发者要解决模块/库的依赖

  • 大型项目中列表冗长且难以管理

CommonJs:同步调用

CommonJs采用require方法同步调用依赖并返回暴露的接口。一个模块能够经过添加暴露对象的属性或设定module.exports的值被暴露出来。

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

该方法以经过node.js被使用于服务端。

优点

  • 服务端模块能够被复用

  • 有大量现成的模块(如npm)

  • 简单且易于使用

不足

  • 阻塞式并不能很好地适用于互联网,网络环境须要异步调用

  • 没法平行加载多个模块

具体应用

AMD:异步调用

异步模块的定义
在客户端其余同步模块系统有着一样的问题,下面介绍一种异步的版本,包括其如何定义变量与暴露值:

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

优点

  • 知足客户端异步调用风格

  • 可平行加载多个模块

不足

  • 头部声明不利于阅读和编写

  • 看上去像是一种妥协

具体应用

ES6模块

EcmaScript6向JavaScript添加了许多语言结构,所以造成了另外一种模块系统。

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

优点

  • 易于静态解析

  • 将来将成为ES标准

不足

  • 还有待浏览器支持

  • 因为比较新,这种方式的实现较少

客观的意见

应然开发者本身选择模块风格,使已存在的代码与库能够正常工做,以简单的方式添加习惯的模块风格。

加载

因为模块须要在客户端执行,所以须要在客户端加载服务端模块。
如下是两种比较极端的模块加载:

  • 一个模块写一个加载

  • 全部模块写在一个加载中
    二者都应用普遍,但都有所不足:

  • 一个模块写一个加载

    • 优点:只有一个模块须要加载

    • 不足:越多模块意味着越多的顶部声明

    • 不足:因为须要较长的加载时间,应用启动较慢

  • 全部模块写一个加载

    • 优点:更少的顶部声明,更快的加载

    • 不足:不须要的模块也同时被加载

分块加载

一种更灵活的加载彷佛更好。一种介于这两种极端中间的方式对大多数状况来的更好。
当编译全部模块时:把模块的集合拆分红许多更小的chunk(块)。
这能实现更小更快的加载。由模块组成的chunks在初始化的时候并不会被加载。当须要使用模块时,才加载块,这加快了应用加载的速度。
如何分割模块集合取决于开发者。

这让组织大量代码成为可能!
注意:这一想法来源于Google’s GWT
了解更多关于代码拆分

为什么只提到JavaScript

有许多其余资源如样式、图片、字体、HTML 模板也须要处理,为什么只说起JavaScript?也还有其余须要编译的资源:coffee script,elm,less,jade,i18n等。
若是把他们都当作chunk(块)事情就变得很简单:

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

了解更多关于使用加载

静态解析

当编译全部这些模块时,静态解析会试图找到它的依赖。
一般,只能解析一些简单的格式,但像("./template/" + templateName + ".jade") 又是一种常见的书写格式。
而且多数库都采用不一样的写法,有些写法时很奇特的…

策略

一款好的语法分析程序能够是大多数现存代码正常运行。若是开发者风格奇特,它也会试图去找到最合适的解决方法。

译者注:这个系列会试图将webpack的官方文档都翻译一遍,未翻译的连接,翻译后会改为相应中文翻译页面。

相关文章
相关标签/搜索