@@ -35,6 +35,7 @@ contributors:
3535 - atesgoral
3636 - snitin315
3737 - artem-malko
38+ - Yucohny
3839translators :
3940 - QC-L
4041 - jacob-lcs
@@ -48,19 +49,19 @@ related:
4849 url : https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
4950---
5051
51- T> 本指南继续沿用 [ 起步] ( /guides/getting-started ) 中的示例代码。请确保你已熟悉这些指南中提供的示例以及[ 输出管理 ] ( /guides/output-management/ ) 章节。
52+ T> 本指南继续沿用 [ 起步] ( /guides/getting-started ) 中的示例代码。请确保你已熟悉这些指南中提供的示例以及 [ 管理输出 ] ( /guides/output-management/ ) 章节。
5253
53- 代码分离是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的 bundle,以及控制资源加载优先级 ,如果使用合理,会极大影响加载时间。
54+ 代码分离是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的 bundle、控制资源加载优先级 ,如果使用合理,会极大影响加载时间。
5455
5556常用的代码分离方法有三种:
5657
5758- ** 入口起点** :使用 [ ` entry ` ] ( /configuration/entry-context ) 配置手动地分离代码。
5859- ** 防止重复** :使用 [ Entry dependencies] ( /configuration/entry-context/#dependencies ) 或者 [ ` SplitChunksPlugin ` ] ( /plugins/split-chunks-plugin ) 去重和分离 chunk。
5960- ** 动态导入** :通过模块的内联函数调用来分离代码。
6061
61- ## 入口起点(entry point) $#entry-points$
62+ ## 入口起点 $#entry-points$
6263
63- 这是迄今为止最简单直观的分离代码的方式。不过,这种方式手动配置较多,并有一些隐患,我们将会解决这些问题 。先来看看如何从 main bundle 中分离 another module(另一个模块) :
64+ 这是迄今为止最简单直观的分离代码的方式。不过,这种方式手动配置较多,并有一些我们将会解决的隐患 。先来看看如何从 main bundle 中分离另一个模块 :
6465
6566** project**
6667
@@ -104,7 +105,7 @@ console.log(_.join(['Another', 'module', 'loaded!'], ' '));
104105 };
105106```
106107
107- 这将生成如下构建结果 :
108+ 构建后结果如下 :
108109
109110``` bash
110111...
@@ -124,13 +125,13 @@ webpack 5.4.0 compiled successfully in 245 ms
124125- 如果入口 chunk 之间包含一些重复的模块,那些重复模块都会被引入到各个 bundle 中。
125126- 这种方法不够灵活,并且不能动态地将核心应用程序逻辑中的代码拆分出来。
126127
127- 以上两点中,第一点对我们的示例来说无疑是个问题,因为之前我们在 ` ./src/index.js ` 中也引入过 ` lodash ` ,这样就在两个 bundle 中造成重复引用。在下一章节会移除重复的模块 。
128+ 以上两点中,第一点对我们的示例来说无疑是个问题,因为之前我们在 ` ./src/index.js ` 中也引入过 ` lodash ` ,这样就在两个 bundle 中造成重复引用。在下一章节会介绍如何移除重复的模块 。
128129
129- ## 防止重复(prevent duplication) $#prevent-duplication$
130+ ## 防止重复 $#prevent-duplication$
130131
131132### 入口依赖 $#entry-dependencies$
132133
133- 配置 [ ` dependOn ` option ] ( /configuration/entry-context/#dependencies ) 选项,这样可以在多个 chunk 之间共享模块:
134+ 配置 [ ` dependOn ` ] ( /configuration/entry-context/#dependencies ) 选项,这样可以在多个 chunk 之间共享模块:
134135
135136** webpack.config.js**
136137
@@ -159,7 +160,7 @@ webpack 5.4.0 compiled successfully in 245 ms
159160 };
160161```
161162
162- 如果我们要在一个 HTML 页面上使用多个入口时,还需设置 ` optimization.runtimeChunk: 'single' ` ,否则还会遇到[ 这里] ( https://bundlers.tooling.report/code-splitting/multi-entry/ ) 所述的麻烦。
163+ 如果我们要在一个 HTML 页面上使用多个入口时,还需设置 ` optimization.runtimeChunk: 'single' ` ,否则还会遇到 [ 这里] ( https://bundlers.tooling.report/code-splitting/multi-entry/ ) 所述的麻烦。
163164
164165** webpack.config.js**
165166
@@ -240,7 +241,7 @@ webpack 5.4.0 compiled successfully in 249 ms
240241 };
241242```
242243
243- 使用 [ ` optimization.splitChunks ` ] ( /plugins/split-chunks-plugin/#optimization-splitchunks ) 配置选项之后,现在应该可以看出, ` index.bundle.js ` 和 ` another.bundle.js ` 中已经移除了重复的依赖模块。需要注意的是,插件将 ` lodash ` 分离到单独的 chunk,并且将其从 main bundle 中移除,减轻了大小 。执行 ` npm run build ` 查看效果:
244+ 使用 [ ` optimization.splitChunks ` ] ( /plugins/split-chunks-plugin/#optimization-splitchunks ) 配置选项之后,将会发现 ` index.bundle.js ` 和 ` another.bundle.js ` 中已经移除了重复的依赖模块。需要注意的是,插件将 ` lodash ` 分离到单独的 chunk,并且将其从 main bundle 中移除,减轻了 bundle 大小 。执行 ` npm run build ` 查看效果:
244245
245246``` bash
246247...
@@ -260,13 +261,13 @@ webpack 5.4.0 compiled successfully in 241 ms
260261
261262以下是由社区提供,一些对于代码分离很有帮助的 plugin 和 loader:
262263
263- - [ ` mini-css-extract-plugin ` ] ( plugins/mini-css-extract-plugin ) : 用于将 CSS 从主应用程序中分离。
264+ - [ ` mini-css-extract-plugin ` ] ( plugins/mini-css-extract-plugin ) : 用于将 CSS 从主应用程序中分离。
264265
265- ## 动态导入(dynamic import) $#dynamic-imports$
266+ ## 动态导入 $#dynamic-imports$
266267
267- 当涉及到动态代码拆分时,webpack 提供了两个类似的技术。第一种,也是推荐选择的方式是 ,使用符合 [ ECMAScript 提案] ( https://github.com/tc39/proposal-dynamic-import ) 的 [ ` import() ` 语法] ( /api/module-methods/#import-1 ) 来实现动态导入。第二种,则是 webpack 的遗留功能,使用 webpack 特定的 [ ` require.ensure ` ] ( /api/module-methods/#requireensure ) 。让我们先尝试使用第一种……
268+ 当涉及到动态代码拆分时,webpack 提供了两个类似的技术。第一种,也是推荐选择的方式 ,使用符合 [ ECMAScript 提案] ( https://github.com/tc39/proposal-dynamic-import ) 的 [ ` import() ` 语法] ( /api/module-methods/#import-1 ) 实现动态导入。第二种则是 webpack 的遗留功能,使用 webpack 特定的 [ ` require.ensure ` ] ( /api/module-methods/#requireensure ) 。让我们先尝试使用第一种……
268269
269- W> ` import() ` 调用会在内部用到 [ promises ] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise ) 。如果在旧版本浏览器中(例如,IE 11)使用 ` import() ` ,记得使用一个 polyfill 库(例如 [ es6-promise] ( https://github.com/stefanpenner/es6-promise ) 或 [ promise-polyfill] ( https://github.com/taylorhakes/promise-polyfill ) ), 来 shim ` Promise ` 。
270+ W> ` import() ` 调用会在内部使用到 [ promise ] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise ) 。如果在旧版本浏览器中(例如,IE 11)使用 ` import() ` ,记得使用一个 polyfill 库(例如 [ es6-promise] ( https://github.com/stefanpenner/es6-promise ) 或 [ promise-polyfill] ( https://github.com/taylorhakes/promise-polyfill ) )来 shim ` Promise ` 。
270271
271272在我们开始之前,先从上述示例的配置中移除掉多余的 [ ` entry ` ] ( /concepts/entry-points/ ) 和 [ ` optimization.splitChunks ` ] ( /plugins/split-chunks-plugin/#optimization-splitchunks ) ,因为接下来的演示中并不需要它们:
272273
@@ -309,7 +310,7 @@ webpack-demo
309310|- /node_modules
310311```
311312
312- 现在,我们不再使用 statically import(静态导入) ` lodash ` ,而是通过 dynamic import(动态导入) 来分离出一个 chunk:
313+ 现在,我们不再静态导入 ` lodash ` ,而是通过动态导入来分离出一个 chunk:
313314
314315** src/index.js**
315316
@@ -320,7 +321,7 @@ webpack-demo
320321+ function getComponent() {
321322- const element = document.createElement('div');
322323
323- - // Lodash, now imported by this script
324+ - // lodash 现在使用 import 引入
324325- element.innerHTML = _.join(['Hello', 'webpack'], ' ');
325326+ return import('lodash')
326327+ .then(({ default: _ }) => {
@@ -356,7 +357,7 @@ cacheable modules 530 KiB
356357webpack 5.4.0 compiled successfully in 268 ms
357358```
358359
359- 由于 ` import() ` 会返回一个 promise,因此它可以和 [ ` async ` 函数] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function ) 一起使用。下面是如何通过 async 函数简化代码 :
360+ 由于 ` import() ` 会返回 promise,因此它可以和 [ ` async ` 函数] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function ) 一起使用。下面是使用 ` async ` 简化后的代码 :
360361
361362** src/index.js**
362363
@@ -384,18 +385,18 @@ webpack 5.4.0 compiled successfully in 268 ms
384385 });
385386```
386387
387- T> 在稍后示例中,可能会根据计算后的变量(computed variable)导入特定模块时 ,可以通过向 ` import() ` 传入一个 [ 动态表达式] ( /api/module-methods/#dynamic-expressions-in-import ) 。
388+ T> 在稍后示例中,当需要根据计算后的变量导入特定模块时 ,可以通过向 ` import() ` 传入一个 [ 动态表达式] ( /api/module-methods/#dynamic-expressions-in-import ) 实现 。
388389
389- ## 预获取/预加载模块(prefetch/preload module) $#prefetchingpreloading-modules$
390+ ## 预获取/预加载模块 $#prefetchingpreloading-modules$
390391
391- Webpack v4.6.0+ 增加了对预获取和预加载的支持 。
392+ Webpack v4.6.0+ 增加了对预获取(prefetch)和预加载(preload)的支持 。
392393
393- 在声明 import 时,使用下面这些内置指令,可以让 webpack 输出 " resource hint(资源提示)" ,来告知浏览器:
394+ 在声明 ` import ` 时,使用下面这些内置指令,可以让 webpack 输出“ resource hint” ,来告知浏览器:
394395
395- - ** prefetch** ( 预获取) :将来某些导航下可能需要的资源
396- - ** preload** ( 预加载) :当前导航下可能需要资源
396+ - ** prefetch** ( 预获取) :将来某些导航下可能需要的资源
397+ - ** preload** ( 预加载) :当前导航下可能需要资源
397398
398- 下面这个 prefetch 的简单示例中 ,有一个 ` HomePage ` 组件,其内部渲染一个 ` LoginButton ` 组件,然后在点击后按需加载 ` LoginModal ` 组件。
399+ 下面这个预获取的简单示例中 ,有一个 ` HomePage ` 组件,其内部渲染一个 ` LoginButton ` 组件,然后在点击后按需加载 ` LoginModal ` 组件。
399400
400401** LoginButton.js**
401402
@@ -406,18 +407,18 @@ import(/* webpackPrefetch: true */ './path/to/LoginModal.js');
406407
407408这会生成 ` <link rel="prefetch" href="login-modal-chunk.js"> ` 并追加到页面头部,指示着浏览器在闲置时间预取 ` login-modal-chunk.js ` 文件。
408409
409- T> 只要父 chunk 完成加载,webpack 就会添加 prefetch hint(预取提示) 。
410+ T> 只要父 chunk 完成加载,webpack 就会添加预获取提示 。
410411
411- 与 prefetch 指令相比,preload 指令有许多不同之处 :
412+ 与预获取指令相比,预加载指令有许多不同之处 :
412413
413- - preload chunk 会在父 chunk 加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载。
414- - preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载。
415- - preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻。
414+ - 预加载 chunk 会在父 chunk 加载时,以并行方式开始加载。预加载 chunk 会在父 chunk 加载结束后开始加载。
415+ - 预加载 chunk 具有中等优先级,并立即下载。预加载 chunk 在浏览器闲置时下载。
416+ - 预加载 chunk 会在父 chunk 中立即请求,用于当下时刻。预加载 chunk 会用于未来的某个时刻。
416417- 浏览器支持程度不同。
417418
418- 下面这个简单的 preload 示例中 ,有一个 ` Component ` ,依赖于一个较大的 library ,所以应该将其分离到一个独立的 chunk 中。
419+ 下面这个简单的预加载示例中 ,有一个 ` Component ` ,依赖于一个较大的库 ,所以应该将其分离到一个独立的 chunk 中。
419420
420- 我们假想这里的图表组件 ` ChartComponent ` 组件需要依赖一个体积巨大的 ` ChartingLibrary ` 库。它会在渲染时显示一个 ` LoadingIndicator(加载进度条) ` 组件,然后立即按需导入 ` ChartingLibrary ` :
421+ 假想这里的图表组件 ` ChartComponent ` 组件需要依赖一个体积巨大的 ` ChartingLibrary ` 库。它会在渲染时显示一个 ` LoadingIndicator ` 组件,然后立即按需导入 ` ChartingLibrary ` :
421422
422423** ChartComponent.js**
423424
@@ -426,7 +427,7 @@ T> 只要父 chunk 完成加载,webpack 就会添加 prefetch hint(预取提
426427import (/* webpackPreload: true */ ' ChartingLibrary' );
427428```
428429
429- 在页面中使用 ` ChartComponent ` 时,在请求 ChartComponent.js 的同时,还会通过 ` <link rel="preload"> ` 请求 charting-library-chunk。假定 page-chunk 体积比 charting-library-chunk 更小,也更快地被加载完成,页面此时就会显示 ` LoadingIndicator(加载进度条) ` ,等到 ` charting-library-chunk ` 请求完成,LoadingIndicator 组件才消失。这将会使得加载时间能够更短一点,因为只进行单次往返,而不是两次往返。 尤其是在高延迟环境下。
430+ 在页面中使用 ` ChartComponent ` 时,在请求 ` ChartComponent.js ` 的同时,还会通过 ` <link rel="preload"> ` 请求 ` charting-library-chunk ` 。假定 page-chunk 体积比 ` charting-library-chunk ` 更小,也更快地被加载完成,页面此时就会显示 ` LoadingIndicator ` ,等到 ` charting-library-chunk ` 请求完成,` LoadingIndicator ` 组件才消失。这将会使得加载时间能够更短一点,因为只进行单次往返,而不是两次往返, 尤其是在高延迟环境下。
430431
431432T> 不正确地使用 ` webpackPreload ` 会有损性能,请谨慎使用。
432433
@@ -439,7 +440,7 @@ const lazyComp = () =>
439440 // 例如,我们可以在网络错误的情况下重试请求
440441 });
441442```
442- 如果在 webpack 开始加载该脚本之前脚本加载失败(如果该脚本不在页面上,webpack 只是创建一个 script 标签来加载其代码),则该 catch 处理程序将不会启动,直到 [ chunkLoadTimeout] ( /configuration/output/#outputchunkloadtimeout ) 未通过。此行为可能是意料之外的。但这是可以解释的 - webpack 不能抛出任何错误,因为 webpack 不知道那个脚本失败了。Webpack 将在错误发生后立即将 onerror 处理脚本添加到 script 中。
443+ 如果在 webpack 开始加载该脚本之前脚本加载失败(如果该脚本不在页面上,webpack 只是创建一个 script 标签来加载其代码),则该 catch 处理程序将不会启动,直到 [ chunkLoadTimeout] ( /configuration/output/#outputchunkloadtimeout ) 未通过。此行为可能是意料之外的。但这是可以解释的 —— webpack 不能抛出任何错误,因为 webpack 不知道那个脚本失败了。webpack 将在错误发生后立即将 onerror 处理脚本添加到 script 中。
443444
444445为了避免上述问题,你可以添加自己的 onerror 处理脚本,将会在错误发生时移除该 script。
445446
@@ -451,18 +452,18 @@ const lazyComp = () =>
451452></script >
452453```
453454
454- 在这种情况下,错误的 script 将被删除。Webpack 将创建自己的 script,并且任何错误都将被处理而没有任何超时。
455+ 在这种情况下,错误的 script 将被删除。webpack 将创建自己的 script,并且任何错误都将被处理而没有任何超时。
455456
456- ## bundle 分析(bundle analysis) $#bundle-analysis$
457+ ## bundle 分析 $#bundle-analysis$
457458
458- 一旦开始分离代码,一件很有帮助的事情是,分析输出结果来检查模块在何处结束。 [ 官方分析工具] ( https://github.com/webpack/analyse ) 是一个不错的开始。还有一些其他社区支持的可选项:
459+ 一旦开始分离代码,一件很有帮助的事情是,分析输出结果来检查模块在何处结束。[ 官方分析工具] ( https://github.com/webpack/analyse ) 是一个不错的开始。还有一些其他社区支持的可选项:
459460
460- - [ webpack-chart] ( https://alexkuz.github.io/webpack-chart/ ) : webpack stats 可交互饼图。
461- - [ webpack-visualizer] ( https://chrisbateman.github.io/webpack-visualizer/ ) : 可视化并分析你的 bundle,检查哪些模块占用空间,哪些可能是重复使用的。
461+ - [ webpack-chart] ( https://alexkuz.github.io/webpack-chart/ ) : webpack stats 可交互饼图。
462+ - [ webpack-visualizer] ( https://chrisbateman.github.io/webpack-visualizer/ ) :分析并可视化 bundle,检查哪些模块占用空间,哪些可能是重复使用的。
462463- [ webpack-bundle-analyzer] ( https://github.com/webpack-contrib/webpack-bundle-analyzer ) :一个 plugin 和 CLI 工具,它将 bundle 内容展示为一个便捷的、交互式、可缩放的树状图形式。
463- - [ webpack bundle optimize helper] ( https://webpack.jakoblind.no/optimize ) :这个工具会分析你的 bundle,并提供可操作的改进措施,以减少 bundle 的大小。
464+ - [ webpack bundle optimize helper] ( https://webpack.jakoblind.no/optimize ) :这个工具会分析 bundle,并提供可操作的改进措施,以减少 bundle 的大小。
464465- [ bundle-stats] ( https://github.com/bundle-stats/bundle-stats ) :生成一个 bundle 报告(bundle 大小、资源、模块),并比较不同构建之间的结果。
465466
466467## 下一步 $#next-steps$
467468
468- 接下来,查看 [ 延迟加载] ( /guides/lazy-loading/ ) 来学习如何在实际一个真实应用程序中使用 ` import() ` 的具体示例,以及查看 [ 缓存] ( /guides/caching/ ) 来学习如何有效地分离代码。
469+ 接下来,查看 [ 延迟加载] ( /guides/lazy-loading/ ) 来学习如何在真实的应用程序中使用 ` import() ` 的具体示例,以及查看 [ 缓存] ( /guides/caching/ ) 来学习如何有效地分离代码。
0 commit comments