【译】webpack文档翻译 动机
转载请注明来源(sunshine-boy)
动机
如今的网站正在演变成网页app:
·越来越多的js被使用
·现代浏览器正在提供一个更大范围的接口
·完整的页面重新加载更少->甚至更多的代码在一个页面里
导致的结果是,更多的代码在客户端
一个庞大的代码库需要被管理。模块系统提供 分离你的代码库为模块 的选择。
模块系统风格
目前有多个关于如何定义依赖和输出值(export values)的标准
·<script> 标签风格(没有模块系统)
·commonJs
·AMD 和一些衍生品
·ES6 模块
·更多...
<script> -标签风格
如果你没有使用一个模块系统,这是你如何处理模块化的代码库
<script src="module1.js"></script> <script src="module2.js"></script> <script src="libraryA.js"></script> <script src="module3.js"></script>
模块输出一个接口给global对象,例如,输出给window对象(译注:nodejs中为global对象)
。模块可以通过全局对象访问依赖的接口
常见的问题
·在global对象中冲突
·加载模块的顺序很重要
·开发者不得不解决模块的依赖/库
·在一个大项目中,这个列表可以变得真的很长并且难以管理
commonJs:同步的require
该风格使用一个同步的require方法来加载一个依赖并返回一个输出接口。一个模块可以通过增加exports对象的属性来输出,或通过设置module.exports的值
require("module"); require("../file.js"); exports.doStuff = function() {}; module.exports = someValue;
它被nodejs在服务端使用
优点
·服务端的模块可以被重用
·已经有非常多的模块用这种风格来写(npm)
·非常简单和容易使用
缺点
·阻塞调用(Blocking calls)在网络的应用并不好,网络请求是异步的。
·没有多个模块的并行require
实现
·nodejs -服务端
·browserify
·modules-webmake -编译为1个bundle文件
·wreq -客户端
AMD:异步的require
异步的模块定义
其他的模块系统(对于浏览器环境)使用同步的require时出现问题,所以推出了异步的版本(和一种定义模块和输出值的方式):
require(["module", "../file"], function(module, file) { /* ... */ }); define("mymodule", ["dep1", "dep2"], function(d1, d2) { return someExportedValue; });
优点
·适应网络的异步请求风格
·并行加载多个模块
缺点
·代码开销。更加难以阅读与编写
·似乎是某种变通方法
实现
·require.js -客户端
·curl -客户端
阅读更多有关commonJs和AMD
ES6 模块
ECMAScript6增加了一些js的语言结构,它们形成了另外一种模块系统
import "jquery"; export function doStuff() {} module "localModule" {}
优点
·静态分析非常容易
·ES标准面向未来
缺点
·原生的浏览器支持需要一些时间(译注:使用babel来解决兼容性问题)
·这种风格的模块目前很少
中立方案
让开发者决定他们的模块风格。允许已存在的代码库和包工作。让增加自定义模块风格变得简单。
传输
模块应该在客户端被执行,所以他们必须从服务端传输到浏览器。
->在传输模块时有两个极端:
·一个模块一个请求
·优点:只有被请求的模块会被传输
·缺点:过多的请求意味着更多的开销
·缺点:因为请求延迟,导致应用启动缓慢
·所有模块在一个请求里
·优点:更少的请求开销,更少的延迟
·缺点:不被请求的模块也被传输了
分块传输
一个更加灵活的传输将更好。两种极端情况的妥协在绝大多数情况中更好。
在编译所有模块时:把模块集合分离成多个更小的批量(块)
这将允许多个更小更快的请求。最初没有被请求的块(模块)可以在需求时被加载。这加速了初始加载,但让你放置更多的代码当它将真正被使用时.
分离点取决于开发者
->一个巨大的代码库是可能的
注意:这个想法来自Google的GWT
阅读更多有关Code Splitting
为什么只有js?
为什么一个模块系统应该只帮助js开发者?还有很多其他资源需要被管理
·stylesheets(样式表)
·图片
·网页字体
·html模块
·等等。
或 翻译/处理:
·coffeescript->javascript
·elm->javascript
·less stylesheets->css stylesheets
·jade templates->生成html的javascript
·i18n files->某物
·等等。
这应该简单得像这样:
require("./style.css"); require("./style.less"); require("./template.jade"); require("./image.png");
阅读更多有关 Using loaders 和 Loaders
静态分析
当编译所有这些模块时,一个静态分析尝试去寻找模块的依赖。
传统情况下,这将只会找到没有表达式的简单东西,但require("./template/" + templateName + ".jade")是一个常见的构造。许多库是用不同的风格写得,他们中某些的写法非常诡异。
策略
一个聪明的解析器应该允许绝大多数已存在的代码运行。如果某个开发者做了一些奇怪的事,解析器应该去寻找最佳的解决方案。
posted on 2016-06-28 15:27 sunshine-boy 阅读(201) 评论(1) 编辑 收藏 举报