Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(cn): improve translations of cache #1834

Merged
merged 4 commits into from
Nov 24, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions src/content/guides/caching.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ contributors:
- AnayaDesign
- aholzner
- snitin315
- Yucohny
translators:
- QC-L
- jacob-lcs
- dear-lizhihua
- Yucohny
related:
- title: Issue 652
url: https://github.com/webpack/webpack.js.org/issues/652
---

T> 本指南继续沿用 [起步](/guides/getting-started)、[管理输出](/guides/output-management) 和 [代码分离](/guides/code-splitting) 中的代码示例。

接下来继续使用 webpack 打包模块化应用程序。在打包后,webpack 会生成一个可部署的 `/dist` 目录,然后就打包后的内容放置在此目录中。一旦 `/dist` 目录中的内容部署到服务器上,客户端(通常是浏览器)就能够访问此服务器以获取站点及其资源。而最后一步获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为 [缓存](<https://en.wikipedia.org/wiki/Cache_(computing)>) 的技术。命中缓存可以降低网络流量,使网站加载速度更快。然而,如果在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。由于缓存的存在,当你需要获取新的代码时,就会显得很棘手。
接下来继续使用 webpack 打包模块化应用程序。webpack 会在打包后生成可部署的 `/dist` 目录,并将打包后的内容放在此目录。一旦 `/dist` 目录中的内容部署到服务器上,客户端(通常是浏览器)就能够访问此服务器以获取站点及其资源。由于获取服务器资源是比较耗费时间的操作,因此浏览器使用了一种名为 [缓存](<https://en.wikipedia.org/wiki/Cache_(computing)>) 的技术。命中缓存可以降低网络流量,使网站加载速度更快。然而,如果在部署资源的最新版本时没有更改资源的文件名,浏览器可能会认为它没有被更新,从而使用它的缓存版本。由于缓存的存在,当需要获取新的代码时,就会显得很棘手。

此指南的重点在于通过必要的配置,确保 webpack 编译生成的文件能够被客户端缓存;而在文件内容变化后,能够请求到新的文件
这篇指南的重点在于通过必要配置确保 webpack 编译生成的文件能够被客户端缓存;当文件内容变化后,客户端又能够请求到新的文件

## 输出文件的文件名 $#output-filenames$

更改 `output.filename` 中的 [substitutions](/configuration/output/#outputfilename) 以定义输出文件的名称。webpack 提供了一种称为 **substitution(可替换模板字符串)** 的方式,通过带括号字符串来模板化文件名。其中,`[contenthash]` substitution 将根据资源内容创建唯一哈希值。当资源内容发生变化时,`[contenthash]` 也会发生变化。
更改 `output.filename` 中的 [substitutions](/configuration/output/#outputfilename) 以定义输出文件的名称。webpack 提供了一种称为 **可替换模板字符串(substitution)** 的方式,通过带括号字符串来模板化文件名。其中,`[contenthash]` 将根据资源内容创建唯一哈希值。当资源内容发生变化时,`[contenthash]` 也会发生变化。

这里使用 [起步](/guides/getting-started) 中的示例和 [管理输出](/guides/output-management) 中的 `plugins` 插件作为项目基础,所以不必手动维护 `index.html` 文件:

Expand Down Expand Up @@ -82,7 +82,7 @@ main.7e2c49a622975ebd9b7e.js 544 kB 0 [emitted] [big] main
...
```

可以看到,bundle 的名称是其内容通过哈希的映射。如果不做修改,再次运行构建,也许会认为文件名将保持不变。然而事实并非如此,试试再次构建脚本:
可以发现 bundle 的名称是其内容通过哈希的映射。也许会认为,如果不修改原始文件直接再次运行构建,文件名将保持不变。然而事实并非如此,试试再次构建脚本:

```bash
...
Expand All @@ -92,13 +92,13 @@ main.205199ab45963f6a62ec.js 544 kB 0 [emitted] [big] main
...
```

这是因为 webpack 在入口 chunk 中,包含了某些 boilerplate(引导模板),特别是 runtime 和 manifest。(译注:boilerplate 指 webpack 运行时的引导代码。)
再次执行构建后发现,尽管没有修改原始文件,bundle 的名称仍然发生了修改。这是因为 webpack 在入口 chunk 中包含了某些引导模板(boilerplate),特别是 runtime 和 manifest。

W> 输出可能会因当前的 webpack 版本而稍有差异。与旧版本相比,新版本未必持有同样的哈希机制,但我们仍然建议采取以下步骤以确保安全。

## 提取引导模板 $#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**

Expand Down Expand Up @@ -140,8 +140,7 @@ runtime.cc17ae2a94ec771e9221.js 1.42 KiB 0 [emitted] runtime
+ 1 hidden module
```

由于像 `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` 参数并执行构建:
由于像 `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**

Expand Down Expand Up @@ -247,11 +246,11 @@ webpack-demo
...
```

可以发现,三个文件的哈希值都发生了变化。这是因为每个 [`module.id`](/api/module-variables/#moduleid-commonjs) 会默认基于解析顺序(resolve order)增量。换言之,当解析顺序发生变化,ID 也会随之改变。简要概括便是:
可以发现,三个文件的哈希值都发生了变化。这是因为每个 [`module.id`](/api/module-variables/#moduleid-commonjs) 会默认基于解析顺序增加。换言之,当解析顺序发生变化,ID 也会随之改变。简要概括便是:

- `main` bundle 会随着自身的新增内容的修改,而发生变化
- `vendor` bundle 会随着自身的 `module.id` 的变化,而发生变化
- `manifest` runtime 会因为现在包含一个新模块的引用,而发生变化
- `main` bundle 会随着自身的新增内容的修改而发生变化
- `vendor` bundle 会随着自身的 `module.id` 的变化而发生变化
- `manifest` runtime 会因为现在包含一个新模块的引用而发生变化

上面的第一点与最后一点都是符合预期的行为,而 `vendor` 的哈希值发生变化是我们要修复的。试试将 [`optimization.moduleIds`](/configuration/optimization/#optimizationmoduleids) 设置为 `'deterministic'`:

Expand Down Expand Up @@ -342,4 +341,4 @@ Entrypoint main = runtime.725a1a51ede5ae0cfde0.js vendors.55e79e5927a639d21a1b.j

## 总结 $#conclusion$

缓存可能很复杂,但是从应用程序或站点用户可以获得的收益来看,这值得付出努力。想要了解更多信息,请查看下面 **进一步阅读** 部分。
缓存可能很复杂,但是从应用程序或站点用户可以获得的收益来看,这值得付出努力。想要了解更多信息,请查看下面 **延伸阅读** 部分。