记得某次考试,出国N年老师出的卷子全是英语,坑的英语不好的我们不要不要的。幸亏上了专业英语课。最重要的是专业英语对于我们很重要,比如webpack,一堆博客都是几小时入门,如何会用webpack,当你想用它的某种特性,比如异步加载moudle,用到require.ensure,或者一些很细节的api,一些遇到的问题,都是中文网站,博客解决不了的。曾经嘲笑那些学视频的自认为大神前端,你找个webpack中文详细教学视频看看。
[笑哭].这次,我们来copy一下webpack官网,学一下英语。
开始的motivition,why we do it.web app 能做很多事,我们能在浏览器里用js做更多的事…致使客户端有n多代码,我们需要一种代码加载,模块加载的东西。
Module systems offer the option to split your code base into modules.模块系统提供一个选项去把代码划分到模块里。
There are multiple(多重的;多个的;复杂的;多功能的;) standards for (标准)how to define dependencies and export values:下面列举了模块的标准,amd,cmd,es6的import等。
This is the way you would handle a modularized(模块化的)code base if you didn’t use a module system.
<script src="module1.js"></script> <script src="module2.js"></script> <script src="libraryA.js"></script> <script src="module3.js"></script>
他们共同的问题Common problems
- Conflicts in the global object.全局对象的冲突
- Order of loading is important.加载的顺序
- Developers have to resolve dependencies of modules/libraries.开发者需要解决模块和库的依赖问题
- In big projects the list can get really long and difficult to manage.大工程的list很大很难管理
CommonJs: synchronous(同步) require cmd的同步加载
AMD: asynchronous require amd的异步加载
他们的Pros(优点)Cons(缺点)就不写了。
ES6的模块加载机制
import "jquery"; export function doStuff() {} module "localModule" {}
Pros
- Static analysis is easy 静态分析是很容易的
- Future-proof as ES standard 是未来的标准
Cons
- Native browser support will take time 本地浏览器支持还需要一段时间
- Very few modules in this style 还很少有模块是es6版的
TRANSFERRING
Modules should be executed on the client, so they must be transferred from the server to the browser.
There are two extremes on how to transfer modules: 模块应该在客户端执行,所以他们必须要从服务器端转换到浏览器,这有怎样转换模块的两个极端。
- 1 request per module 每个模块一个需求
- all modules in one request 所有模块都用一个需求
Both are used in the wild, but both are suboptimal: 这俩都是野办法,用的都是(次优的)不咋样。
- 1 request per module
- Pro: only required modules are transferred 只有加载的模块被转换了
- Con: many requests means much overhead 更多的请求意味着更多的开销
- Con: slow application startup, because of request latency 这个app启动很慢,因为请求的延迟
- all modules in one request
- Pro: less request overhead, less latency 更少的请求开销和延迟
- Con: not (yet) required modules are transferred too 未请求的模块也被转换了
Chunked transferring 分块转换(chunk)
A more flexible transferring would be better. A compromise between the extremes is better in most cases.一个更加复杂的转换可能是更好的,在大多数情况下,极端之间的妥协是更好的。
→ While compiling all modules: Split the set of modules into multiple smaller batches (chunks). 编译所有模块的时候,把这个模块切分到一些更小的分支,也就是每个chunk
We get multiple smaller requests. Chunks with modules that are not required initially(最初)are only requested on demand(需求), The initial request doesn’t contain your complete code base and is smaller.我们得到一些更小的请求,modules的chunks没有加载最初的,仅加载了需要的chunk,初始请求不包含你完整的代码库,它更小。
The “split points” are up to the developer and optional.划分成chunk这点是开发者可选的。
→ A big code base is possible!
Note: The idea is from Google’s GWT.
Read more about Code Splitting.
WHY ONLY JAVASCRIPT?
Why should a module system only help the developer with JavaScript? There are many other static resources that need to be handled:为啥模块系统只能服务于js开发者?这里这些静态资源都需要被处理。
- stylesheets
- images
- webfonts
- html for templating
- etc.
And also:
- coffeescript → javascript
- elm → javascript
- less stylesheets → css stylesheets
- jade templates → javascript which generates html
- i18n files → something
- etc.
This should be as easy as:
require("./style.css"); require("./style.less"); require("./template.jade"); require("./image.png");
Read more about Using loaders and Loaders.
STATIC ANALYSIS
When compiling all the modules a static analysis tries to find dependencies.当编译所有模块的时候,静态分析试着去寻找依赖。
Traditionally this could only find simple stuff without expression, but i.e. require("./template/" + templateName + ".jade")
is a common construct.
传统上只能找到简单的依赖但是不被解析。但是ie里面require("./template/" + templateName + ".jade")是公认的结构
Many libraries are written in different styles. Some of them are very weird…许多库都用不同方式写,而许多都是很奇怪的。。。