From 67ebda45b71f65fb28a6351fcf0524a7dc0b1587 Mon Sep 17 00:00:00 2001 From: Yucohny <79147654+Yucohny@users.noreply.github.com> Date: Mon, 24 Jul 2023 19:39:26 +0800 Subject: [PATCH] docs(cn): review and update --- src/content/guides/caching.mdx | 55 +++++++++++++++++----------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/content/guides/caching.mdx b/src/content/guides/caching.mdx index 3edc58001538..4fd80ec5963d 100644 --- a/src/content/guides/caching.mdx +++ b/src/content/guides/caching.mdx @@ -14,6 +14,7 @@ contributors: - AnayaDesign - aholzner - snitin315 + - Yucohny translators: - QC-L - jacob-lcs @@ -25,15 +26,15 @@ related: T> 本指南继续沿用 [起步](/guides/getting-started)、[管理输出](/guides/output-management) 和 [代码分离](/guides/code-splitting) 中的代码示例。 -以上,我们使用 webpack 来打包我们的模块化后的应用程序,webpack 会生成一个可部署的 `/dist` 目录,然后把打包后的内容放置在此目录中。只要 `/dist` 目录中的内容部署到 server 上,client(通常是浏览器)就能够访问此 server 的网站及其资源。而最后一步获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为 [缓存]() 的技术。可以通过命中缓存,以降低网络流量,使网站加载速度更快,然而,如果我们在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。由于缓存的存在,当你需要获取新的代码时,就会显得很棘手。 +接下来继续使用 webpack 打包模块化应用程序。在打包后,webpack 会生成一个可部署的 `/dist` 目录,然后就打包后的内容放置在此目录中。一旦 `/dist` 目录中的内容部署到服务器上,客户端(通常是浏览器)就能够访问此服务器以获取站点及其资源。而最后一步获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为 [缓存]() 的技术。命中缓存可以降低网络流量,使网站加载速度更快。然而,如果在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。由于缓存的存在,当你需要获取新的代码时,就会显得很棘手。 -此指南的重点在于通过必要的配置,以确保 webpack 编译生成的文件能够被客户端缓存,而在文件内容变化后,能够请求到新的文件。 +此指南的重点在于通过必要的配置,确保 webpack 编译生成的文件能够被客户端缓存;而在文件内容变化后,能够请求到新的文件。 -## 输出文件的文件名(output filename) $#output-filenames$ +## 输出文件的文件名 $#output-filenames$ -我们可以通过替换 `output.filename` 中的 [substitutions](/configuration/output/#outputfilename) 设置,来定义输出文件的名称。webpack 提供了一种使用称为 **substitution(可替换模板字符串)** 的方式,通过带括号字符串来模板化文件名。其中,`[contenthash]` substitution 将根据资源内容创建出唯一 hash。当资源内容发生变化时,`[contenthash]` 也会发生变化。 +更改 `output.filename` 中的 [substitutions](/configuration/output/#outputfilename) 以定义输出文件的名称。webpack 提供了一种称为 **substitution(可替换模板字符串)** 的方式,通过带括号字符串来模板化文件名。其中,`[contenthash]` substitution 将根据资源内容创建唯一哈希值。当资源内容发生变化时,`[contenthash]` 也会发生变化。 -这里使用 [起步](/guides/getting-started) 中的示例和 [管理输出](/guides/output-management) 中的 `plugins` 插件来作为项目基础,所以我们依然不必手动地维护 `index.html` 文件: +这里使用 [起步](/guides/getting-started) 中的示例和 [管理输出](/guides/output-management) 中的 `plugins` 插件作为项目基础,所以不必手动维护 `index.html` 文件: **project** @@ -71,7 +72,7 @@ webpack-demo }; ``` -使用此配置,然后运行我们的 build script `npm run build`,产生以下输出: +调整配置后构建脚本,将会看到像下面一样的输出: ```bash ... @@ -81,7 +82,7 @@ main.7e2c49a622975ebd9b7e.js 544 kB 0 [emitted] [big] main ... ``` -可以看到,bundle 的名称是它内容(通过 hash)的映射。如果我们不做修改,然后再次运行构建,我们以为文件名会保持不变。然而,如果我们真的运行,可能会发现情况并非如此: +可以看到,bundle 的名称是其内容通过哈希的映射。如果不做修改,再次运行构建,也许会认为文件名将保持不变。然而事实并非如此,试试再次构建脚本: ```bash ... @@ -91,13 +92,13 @@ main.205199ab45963f6a62ec.js 544 kB 0 [emitted] [big] main ... ``` -这也是因为 webpack 在入口 chunk 中,包含了某些 boilerplate(引导模板),特别是 runtime 和 manifest。(译注:boilerplate 指 webpack 运行时的引导代码) +这是因为 webpack 在入口 chunk 中,包含了某些 boilerplate(引导模板),特别是 runtime 和 manifest。(译注:boilerplate 指 webpack 运行时的引导代码。) -W> 输出可能会因当前的 webpack 版本而稍有差异。与旧版本相比,新版本不一定有完全相同的问题,但我们仍然推荐的以下步骤,确保结果可靠。 +W> 输出可能会因当前的 webpack 版本而稍有差异。与旧版本相比,新版本未必持有同样的哈希机制,但我们仍然建议采取以下步骤以确保安全。 -## 提取引导模板(extracting boilerplate) $#extracting-boilerplate$ +## 提取引导模板 $#extracting-boilerplate$ -正如我们在 [代码分离](/guides/code-splitting) 中所学到的,[`SplitChunksPlugin`](/plugins/split-chunks-plugin/) 可以用于将模块分离到单独的 bundle 中。webpack 还提供了一个优化功能,可使用 [`optimization.runtimeChunk`](/configuration/optimization/#optimizationruntimechunk) 选项将 runtime 代码拆分为一个单独的 chunk。将其设置为 `single` 来为所有 chunk 创建一个 runtime bundle: +正如我们在 [代码分离](/guides/code-splitting) 中所学到的,[`SplitChunksPlugin`](/plugins/split-chunks-plugin/) 可以用于将模块分离到单独的 bundle 中。webpack 还提供了一个优化功能,可以使用 [`optimization.runtimeChunk`](/configuration/optimization/#optimizationruntimechunk) 选项将 runtime 代码拆分为一个单独的 chunk。将其设置为 `single` 以为所有 chunk 创建一个 runtime bundle: **webpack.config.js** @@ -123,7 +124,7 @@ W> 输出可能会因当前的 webpack 版本而稍有差异。与旧版本相 }; ``` -再次构建,然后查看提取出来的 `runtime` bundle: +更改配置后再次构建,查看提取出来的 `runtime` bundle: ```bash Hash: 82c9c385607b2150fab2 @@ -139,8 +140,8 @@ runtime.cc17ae2a94ec771e9221.js 1.42 KiB 0 [emitted] runtime + 1 hidden module ``` -将第三方库(library)(例如 `lodash` 或 `react`)提取到单独的 `vendor` chunk 文件中,是比较推荐的做法,这是因为,它们很少像本地的源代码那样频繁修改。因此通过实现以上步骤,利用 client 的长效缓存机制,命中缓存来消除请求,并减少向 server 获取资源,同时还能保证 client 代码和 server 代码版本一致。 -这可以通过使用 [SplitChunksPlugin 示例 2](/plugins/split-chunks-plugin/#split-chunks-example-2) 中演示的 [`SplitChunksPlugin`](/plugins/split-chunks-plugin/) 插件的 [`cacheGroups`](/plugins/split-chunks-plugin/#splitchunkscachegroups) 选项来实现。我们在 `optimization.splitChunks` 添加如下 `cacheGroups` 参数并构建: +由于像 `lodash` 或 `react` 这样的第三方库很少像本地源代码一样频繁修改,因此通常推荐将第三方库提取到单独的 `vendor` chunk 中。这一步将减少客户端对服务器的请求,同时保证自身代码与服务器一致。 +可以通过使用 [SplitChunksPlugin 示例 2](/plugins/split-chunks-plugin/#split-chunks-example-2) 中演示的 [`SplitChunksPlugin`](/plugins/split-chunks-plugin/) 插件的 [`cacheGroups`](/plugins/split-chunks-plugin/#splitchunkscachegroups) 选项来实现。试试在 `optimization.splitChunks` 添加如下 `cacheGroups` 参数并执行构建: **webpack.config.js** @@ -187,9 +188,9 @@ vendors.a42c3ca0d742766d7a28.js 69.4 KiB 1 [emitted] vendors ... ``` -现在,我们可以看到 `main` 不再含有来自 `node_modules` 目录的 `vendor` 代码,并且体积减少到 `240 bytes`! +现在,可以看到 `main` 不再含有来自 `node_modules` 目录的 `vendor` 代码,并且体积减少到 `240 bytes`! -## 模块标识符(module identifier) $#module-identifiers$ +## 模块标识符 $#module-identifiers$ 在项目中再添加一个模块 `print.js`: @@ -224,7 +225,7 @@ webpack-demo function component() { const element = document.createElement('div'); - // lodash 是由当前 script 脚本 import 进来的 + // lodash 现在使用 import 引入 element.innerHTML = _.join(['Hello', 'webpack'], ' '); + element.onclick = Print.bind(null, 'Hello webpack!'); @@ -234,7 +235,7 @@ webpack-demo document.body.appendChild(component()); ``` -再次运行构建,然后我们期望的是,只有 `main` bundle 的 hash 发生变化,然而…… +通常我们会期望,当再次执行构建后,只有 `main` bundle 的哈希值会发生变化,然而…… ```bash ... @@ -246,13 +247,13 @@ webpack-demo ... ``` -……我们可以看到这三个文件的 hash 都变化了。这是因为每个 [`module.id`](/api/module-variables/#moduleid-commonjs) 会默认地基于解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变。简要概括: +可以发现,三个文件的哈希值都发生了变化。这是因为每个 [`module.id`](/api/module-variables/#moduleid-commonjs) 会默认基于解析顺序(resolve order)增量。换言之,当解析顺序发生变化,ID 也会随之改变。简要概括便是: - `main` bundle 会随着自身的新增内容的修改,而发生变化。 - `vendor` bundle 会随着自身的 `module.id` 的变化,而发生变化。 - `manifest` runtime 会因为现在包含一个新模块的引用,而发生变化。 -第一个和最后一个都是符合预期的行为,`vendor` hash 发生变化是我们要修复的。我们将 [`optimization.moduleIds`](/configuration/optimization/#optimizationmoduleids) 设置为 `'deterministic'`: +上面的第一点与最后一点都是符合预期的行为,而 `vendor` 的哈希值发生变化是我们要修复的。试试将 [`optimization.moduleIds`](/configuration/optimization/#optimizationmoduleids) 设置为 `'deterministic'`: **webpack.config.js** @@ -288,7 +289,7 @@ webpack-demo }; ``` -现在,不论是否添加任何新的本地依赖,对于前后两次构建,`vendor` hash 都应该保持一致: +现在,不论是否添加任何新的本地依赖,对于前后两次构建,`vendor` 的哈希值都应保持一致: ```bash ... @@ -301,7 +302,7 @@ Entrypoint main = runtime.725a1a51ede5ae0cfde0.js vendors.55e79e5927a639d21a1b.j ... ``` -然后,修改 `src/index.js`,临时移除额外的依赖: +接下来修改 `src/index.js` 临时移除额外的依赖: **src/index.js** @@ -313,7 +314,7 @@ Entrypoint main = runtime.725a1a51ede5ae0cfde0.js vendors.55e79e5927a639d21a1b.j function component() { const element = document.createElement('div'); - // lodash 是由当前 script 脚本 import 进来的 + // lodash 现在使用 import 引入 element.innerHTML = _.join(['Hello', 'webpack'], ' '); - element.onclick = Print.bind(null, 'Hello webpack!'); + // element.onclick = Print.bind(null, 'Hello webpack!'); @@ -324,7 +325,7 @@ Entrypoint main = runtime.725a1a51ede5ae0cfde0.js vendors.55e79e5927a639d21a1b.j document.body.appendChild(component()); ``` -最后,再次运行我们的构建: +最后,再次执行构建: ```bash ... @@ -337,8 +338,8 @@ Entrypoint main = runtime.725a1a51ede5ae0cfde0.js vendors.55e79e5927a639d21a1b.j ... ``` -我们可以看到,这两次构建中,`vendor` bundle 文件名称,都是 `55e79e5927a639d21a1b`。 +可以看到,在这两次构建中,`vendor` bundle 的文件名称都是 `55e79e5927a639d21a1b`。 -## 结论 $#conclusion$ +## 总结 $#conclusion$ -缓存可能很复杂,但是从应用程序或站点用户可以获得的收益来看,这值得付出努力。想要了解更多信息,请查看下面 *进一步阅读* 部分。 +缓存可能很复杂,但是从应用程序或站点用户可以获得的收益来看,这值得付出努力。想要了解更多信息,请查看下面 **进一步阅读** 部分。