Skip to content

Commit ae10ff6

Browse files
committed
update webpack-code-splitting
1 parent da04e37 commit ae10ff6

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

tutorials/webpack-code-splitting/README.md

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Project
1616
|--b.js
1717
|--c.js
1818
|--d.js
19+
|--e.js
1920
|--page1.js
2021
|--page2.js
2122
|--page3.js
@@ -84,7 +85,7 @@ output: {
8485

8586
此处,我们将`entry`配置成一个stirng值,即一个文件路径。`page1.js`中引入了`a.js``b.js`模块,执行`npm start`进行打包,在`buildOutput`目录下生成打包文件`page1.bundle.js`,该文件就是一个入口chunk(entry chunk),即根据entry生成的打包文件。
8687

87-
打开`page1.bundle.js`文件我们可以看到包含很多类似于`__webpack_require__()`之类的函数,通过这些方法可以在浏览器中加载相应的模块资源,我们把这些方法叫做`webpack runtime`,即webpack运行时代码逻辑
88+
打开`page1.bundle.js`文件我们可以看到其中定义了`webpackJsonp()``__webpack_require__()`之类的函数,通过这些方法可以在浏览器中加载相应的模块资源,我们把这些在运行时Webpack加载资源的逻辑代码叫做`webpack runtime`。就像`require.js`用于加载AMD模块资源一样,`webpack runtime`是用于加载Webpack打包后的资源的,它是在浏览器环境中加载和使用Webpack资源的关键
8889

8990
所以
9091
```
@@ -144,7 +145,39 @@ output: {
144145
## 2. normal chunk
145146
通过上面的示例,我想大家已经明白了什么是entry chunk,下面开始今天的正题Code Splitting。
146147

147-
Webpack允许我们在代码中创建分离点,在分离点处将会产生一个新的chunk文件。
148+
Webpack允许我们在代码中创建分离点(Code Splitting Point),在分离点处将会产生一个新的normal chunk文件。
149+
150+
我们在`e.js`中用ES6语法定义了一个`Person`类,如下所示:
151+
```
152+
class Person {
153+
constructor(name, age) {
154+
this.name = name;
155+
this.age = age;
156+
}
157+
158+
setName(name) {
159+
this.name = name;
160+
}
161+
162+
getName() {
163+
return this.name;
164+
}
165+
166+
setAge(age) {
167+
this.age = age;
168+
}
169+
170+
getAge() {
171+
return this.age;
172+
}
173+
174+
toString() {
175+
return `name: ${this.name}, age: ${this.age}`;
176+
}
177+
}
178+
179+
export default Person;
180+
```
148181

149182
`page3.js`文件如下所示:
150183
```
@@ -154,7 +187,8 @@ import b from "./b.js";
154187
console.log("module a: ", a);
155188
console.log("module b: ", b);
156189
157-
require.ensure([], function() {
190+
//创建代码分离点
191+
require.ensure(["./c.js", "./d.js", "./e.js"], function() {
158192
const c = require("./c.js");
159193
const d = require("./d.js");
160194
const Person = require("./e.js");
@@ -163,4 +197,54 @@ require.ensure([], function() {
163197
console.log("module d: ", d);
164198
console.log("person: ", person.toString());
165199
}, "cde");
166-
```
200+
```
201+
202+
我们在`page3.js`中通过`require.ensure([], function(){}, chunkName)`创建了一个代码分离点,`require.ensure(dependencies, callback, chunkName)`方法能够保证`dependencies`这些依赖可以在`callback`回调中同步加载require,Webpack会将`c.js``d.js``e.js`一起打包形成一个新的normal chunk文件(这个文件有可能很大),在浏览器中,满足某些条件的情况下,我们的代码会运行到分离点处时,此时Webpack就会异步加载之前打包生成的normal chunk文件,这样就实现了将某些功能从首屏资源文件中拆分出去,在浏览器中根据用户操作按需动态加载资源文件,这样可以加快首屏显示的速度,提升用户体验。
203+
204+
`require.ensure(dependencies, callback, chunkName)`方法中的`dependencies`可以保留空数组[],Webpack一样能智能地分析`callback`回调方法,从中找出`callback`回调中需要同步加载的资源文件并打包成normal chunck。
205+
206+
`require.ensure(dependencies, callback, chunkName)`方法最后有一个可选的`chunkName`参数,通过该参数可以给新生成的normal chunk设置chunk name,给其设置chunk name有两个好处:
207+
- 可以通过`output.chunkName`配置为`[name]`设置生成的normal chunk的文件名
208+
- 具有相同chunk name的多个normal chunk会合并为一个文件
209+
210+
修改`webpack.config.js`,配置如下所示:
211+
```
212+
entry: "./src/page3.js",
213+
output: {
214+
path: path.join(__dirname, "buildOutput"),
215+
filename: "page3.bundle.js",
216+
chunkFilename: "[id].[name].js"
217+
}
218+
```
219+
220+
执行npm start进行打包,在`buildOutput`目录下生成打包文件`page3.bundle.js``1.cde.bundle.js`
221+
222+
`page3.bundle.js`包含了`webpack runtime`和代码分离点处callback回调内部的代码逻辑,但是不包含`c.js``d.js``e.js``1.cde.bundle.js`中包含了`c.js``d.js``e.js`的代码,不包含`webpack runtime`
223+
224+
225+
```
226+
page3.bundle.js = webpack runtime + 异步callback逻辑
227+
228+
1.cde.bundle.js = `c.js` + `d.js` + `e.js`
229+
230+
```
231+
232+
`page3.bundle.js`部分代码截图如下所示:
233+
<div align="center">
234+
<img src="https://rawgit.com/iSpring/babel-webpack-react-redux-tutorials/master/tutorials/webpack-code-splitting/images/page3.bundle.js.png" />
235+
</div>
236+
237+
从上面的例子中我们可以看到通过`require.ensure()`方法可以异步加载CommonJS和ES6模块资源文件。其实通过`require(dependencies, callback)`也可以异步加载AMD模块,例如:
238+
```
239+
require(["module-a", "module-b"], function(a, b) {
240+
// ...
241+
});
242+
```
243+
这种写法跟`require.js`中异步按需动态加载AMD模块的方式很类似,在此不再赘述。
244+
245+
## 3. 总结
246+
1. chunk分为entry chunk和normal chunk。
247+
248+
2. entry chunk是入口文件,它的名字一般通过`output.filename`指定。一般情况下,entry chunk = webpack runtime + modules.
249+
250+
3. 通过代码`require.ensure([], function(...){})``require([amd1, amd2], function(amd1, amd2){})`可以设置代码的分离点(Code Splitting Point),Webpack会将其创建一个新的normal chunk。一般情况下,normal chunk不包含webpack runtime,只包含一些modules代码。
Loading

0 commit comments

Comments
 (0)