@intlayer/docs 8.12.2 → 8.12.4-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/blog.cjs.map +1 -1
- package/dist/cjs/common.cjs.map +1 -1
- package/dist/cjs/doc.cjs.map +1 -1
- package/dist/cjs/frequentQuestions.cjs.map +1 -1
- package/dist/cjs/generated/blog.entry.cjs +1 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +1 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +1 -0
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +1 -0
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/cjs/legal.cjs.map +1 -1
- package/dist/esm/blog.mjs.map +1 -1
- package/dist/esm/common.mjs.map +1 -1
- package/dist/esm/doc.mjs.map +1 -1
- package/dist/esm/frequentQuestions.mjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/generated/legal.entry.mjs.map +1 -1
- package/dist/esm/legal.mjs.map +1 -1
- package/dist/types/blog.d.ts.map +1 -1
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/doc.d.ts.map +1 -1
- package/dist/types/frequentQuestions.d.ts.map +1 -1
- package/dist/types/legal.d.ts.map +1 -1
- package/docs/ar/bundle_optimization.md +250 -102
- package/docs/ar/configuration.md +10 -10
- package/docs/bn/bundle_optimization.md +252 -104
- package/docs/bn/configuration.md +10 -10
- package/docs/cs/bundle_optimization.md +253 -105
- package/docs/cs/configuration.md +10 -10
- package/docs/de/bundle_optimization.md +245 -97
- package/docs/de/configuration.md +10 -10
- package/docs/en/bundle_optimization.md +172 -49
- package/docs/en/configuration.md +10 -10
- package/docs/en-GB/bundle_optimization.md +230 -82
- package/docs/en-GB/configuration.md +10 -10
- package/docs/es/bundle_optimization.md +250 -102
- package/docs/es/configuration.md +10 -10
- package/docs/fr/bundle_optimization.md +223 -75
- package/docs/fr/configuration.md +10 -10
- package/docs/hi/bundle_optimization.md +253 -105
- package/docs/hi/configuration.md +10 -10
- package/docs/id/bundle_optimization.md +258 -110
- package/docs/id/configuration.md +10 -10
- package/docs/it/bundle_optimization.md +249 -103
- package/docs/it/configuration.md +10 -10
- package/docs/ja/bundle_optimization.md +245 -97
- package/docs/ja/configuration.md +10 -10
- package/docs/ko/bundle_optimization.md +253 -105
- package/docs/ko/configuration.md +10 -10
- package/docs/nl/bundle_optimization.md +249 -101
- package/docs/nl/configuration.md +10 -10
- package/docs/pl/bundle_optimization.md +258 -111
- package/docs/pl/configuration.md +10 -10
- package/docs/pt/bundle_optimization.md +256 -115
- package/docs/pt/configuration.md +10 -10
- package/docs/ru/bundle_optimization.md +253 -105
- package/docs/ru/configuration.md +10 -10
- package/docs/tr/bundle_optimization.md +255 -107
- package/docs/tr/configuration.md +10 -10
- package/docs/uk/bundle_optimization.md +250 -102
- package/docs/uk/configuration.md +10 -10
- package/docs/ur/bundle_optimization.md +257 -109
- package/docs/ur/configuration.md +10 -10
- package/docs/vi/bundle_optimization.md +259 -111
- package/docs/vi/configuration.md +10 -10
- package/docs/zh/bundle_optimization.md +260 -112
- package/docs/zh/configuration.md +10 -10
- package/docs/zh-TW/bundle_optimization.md +602 -0
- package/package.json +8 -8
package/docs/vi/configuration.md
CHANGED
|
@@ -679,16 +679,16 @@ routing: {
|
|
|
679
679
|
|
|
680
680
|
Khi sử dụng bộ nhớ lưu trữ trong cookie, bạn có thể thiết lập các thuộc tính bổ sung:
|
|
681
681
|
|
|
682
|
-
| Trường | Mô tả
|
|
683
|
-
| ---------- |
|
|
684
|
-
| `name` | Tên của cookie. Mặc định: `'INTLAYER_LOCALE'`
|
|
685
|
-
| `domain` | Tên miền của cookie. Mặc định: `undefined`
|
|
686
|
-
| `path` | Đường dẫn của cookie. Mặc định: `undefined`
|
|
687
|
-
| `secure` | Yêu cầu HTTPS. Mặc định: `undefined`
|
|
688
|
-
| `httpOnly` | Gờ (flag) HTTP-only. Mặc định: `undefined`
|
|
689
|
-
| `sameSite` | Chính sách SameSite.
|
|
690
|
-
| `expires` |
|
|
691
|
-
| `maxAge` | Thời gian tồn tại tính bằng giây kể từ khi tạo. Được ưu tiên hơn `expires`. Mặc định: `undefined`
|
|
682
|
+
| Trường | Mô tả | Kiểu dữ liệu |
|
|
683
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- |
|
|
684
|
+
| `name` | Tên của cookie. Mặc định: `'INTLAYER_LOCALE'` | `string` |
|
|
685
|
+
| `domain` | Tên miền của cookie. Mặc định: `undefined` | `string` |
|
|
686
|
+
| `path` | Đường dẫn của cookie. Mặc định: `undefined` | `string` |
|
|
687
|
+
| `secure` | Yêu cầu HTTPS. Mặc định: `undefined` | `boolean` |
|
|
688
|
+
| `httpOnly` | Gờ (flag) HTTP-only. Mặc định: `undefined` | `boolean` |
|
|
689
|
+
| `sameSite` | Chính sách SameSite. | `'strict'` | <br/> `'lax'` | <br/> `'none'` |
|
|
690
|
+
| `expires` | Số đại diện cho số ngày kể từ khi tạo; ngày (hoặc chuỗi ngày ISO) là ngày hết hạn tuyệt đối. Mặc định: `undefined` | `Date` | <br/> `number` | <br/> `string` |
|
|
691
|
+
| `maxAge` | Thời gian tồn tại tính bằng giây kể từ khi tạo. Được ưu tiên hơn `expires`. Mặc định: `undefined` | `number` |
|
|
692
692
|
|
|
693
693
|
#### Thuộc tính Lưu trữ (Storage Attributes)
|
|
694
694
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-11-25
|
|
3
|
-
updatedAt: 2026-
|
|
4
|
-
title: 优化 i18n
|
|
5
|
-
description:
|
|
3
|
+
updatedAt: 2026-06-07
|
|
4
|
+
title: 优化 i18n 打包体积与性能
|
|
5
|
+
description: 通过优化国际化(i18n)内容来减小应用程序包的大小。了解如何利用 Intlayer 实现字典的 tree shaking 和延迟加载(lazy loading)。
|
|
6
6
|
keywords:
|
|
7
|
-
-
|
|
7
|
+
- 打包优化
|
|
8
8
|
- 内容自动化
|
|
9
9
|
- 动态内容
|
|
10
10
|
- Intlayer
|
|
@@ -16,33 +16,36 @@ slugs:
|
|
|
16
16
|
- concept
|
|
17
17
|
- bundle-optimization
|
|
18
18
|
history:
|
|
19
|
+
- version: 8.12.0
|
|
20
|
+
date: 2026-06-07
|
|
21
|
+
changes: "为 Babel/Webpack 引入了 `intlayerPurgeBabelPlugin` 和 `intlayerMinifyBabelPlugin`,明确了插件管线"
|
|
19
22
|
- version: 8.7.0
|
|
20
23
|
date: 2026-04-08
|
|
21
|
-
changes: "
|
|
24
|
+
changes: "向构建配置中添加了 `minify` 和 `purge` 选项"
|
|
22
25
|
---
|
|
23
26
|
|
|
24
|
-
# 优化 i18n
|
|
27
|
+
# 优化 i18n 打包体积与性能
|
|
25
28
|
|
|
26
|
-
依赖 JSON 文件的传统 i18n
|
|
29
|
+
依赖 JSON 文件的传统 i18n 解决方案中最常见的挑战之一是管理内容体积。如果开发者没有手动将内容拆分到各个命名空间(namespaces),用户通常会为了查看一个页面而下载所有页面、甚至是所有语言的翻译。
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
例如,一个应用有 10 个页面并被翻译成了 10 种语言,可能导致用户为了这 10 个页面下载所有的内容,尽管他们只想要**一个页面**的内容(当前语言版本的当前页面)。这不仅会造成带宽浪费,也会导致更慢的加载时间。
|
|
29
32
|
|
|
30
|
-
**Intlayer
|
|
33
|
+
**Intlayer 通过在构建时(build-time)进行优化来解决这一问题。** 它可以分析你的代码以检测每个组件实际使用了哪些字典,并只将必要的内容注入到你的打包结果(bundle)中。
|
|
31
34
|
|
|
32
35
|
## 目录
|
|
33
36
|
|
|
34
37
|
<TOC />
|
|
35
38
|
|
|
36
|
-
##
|
|
39
|
+
## 分析你的包大小
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
分析你的打包结果是找出“臃肿”的 JSON 文件和考虑进行代码分割(code-splitting)的首要步骤。这些工具可以生成你应用程序编译代码的树状可视视图(treemap),让你能够清楚地看到究竟是哪些库占据了最多的空间。
|
|
39
42
|
|
|
40
43
|
<Tabs>
|
|
41
44
|
<Tab value="vite">
|
|
42
45
|
|
|
43
46
|
### Vite / Rollup
|
|
44
47
|
|
|
45
|
-
Vite
|
|
48
|
+
Vite 在底层使用了 Rollup。插件 `rollup-plugin-visualizer` 能够生成一个交互式 HTML 文件,展示依赖图(graph)中每个模块的体积。
|
|
46
49
|
|
|
47
50
|
```bash
|
|
48
51
|
npm install -D rollup-plugin-visualizer
|
|
@@ -55,7 +58,7 @@ import { visualizer } from "rollup-plugin-visualizer";
|
|
|
55
58
|
export default defineConfig({
|
|
56
59
|
plugins: [
|
|
57
60
|
visualizer({
|
|
58
|
-
open: true, //
|
|
61
|
+
open: true, // 自动在浏览器中打开报告
|
|
59
62
|
filename: "stats.html",
|
|
60
63
|
gzipSize: true,
|
|
61
64
|
brotliSize: true,
|
|
@@ -69,7 +72,7 @@ export default defineConfig({
|
|
|
69
72
|
|
|
70
73
|
### Next.js (Turbopack)
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
对于使用了 App Router 和 Turbopack 的项目,Next.js 提供了一个内置的实验性分析器,它不需要额外的依赖。
|
|
73
76
|
|
|
74
77
|
```bash packageManager='npm'
|
|
75
78
|
npx next experimental-analyze
|
|
@@ -92,7 +95,7 @@ bun next experimental-analyze
|
|
|
92
95
|
|
|
93
96
|
### Next.js (Webpack)
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
如果你在 Next.js 中使用的是默认的 Webpack 打包器,请使用官方的 bundle analyzer。你可以通过在构建期间设置一个环境变量来触发它。
|
|
96
99
|
|
|
97
100
|
```bash packageManager='npm'
|
|
98
101
|
npm install -D @next/bundle-analyzer
|
|
@@ -116,11 +119,11 @@ const withBundleAnalyzer = require("@next/bundle-analyzer")({
|
|
|
116
119
|
});
|
|
117
120
|
|
|
118
121
|
module.exports = withBundleAnalyzer({
|
|
119
|
-
//
|
|
122
|
+
// 你的 Next.js 配置
|
|
120
123
|
});
|
|
121
124
|
```
|
|
122
125
|
|
|
123
|
-
|
|
126
|
+
**用法:**
|
|
124
127
|
|
|
125
128
|
```bash
|
|
126
129
|
ANALYZE=true npm run build
|
|
@@ -129,9 +132,9 @@ ANALYZE=true npm run build
|
|
|
129
132
|
</Tab>
|
|
130
133
|
<Tab value="Webpack (CRA / Angular / etc)">
|
|
131
134
|
|
|
132
|
-
###
|
|
135
|
+
### 纯 Webpack
|
|
133
136
|
|
|
134
|
-
|
|
137
|
+
针对 Create React App (ejected)、Angular 或是自定义 Webpack 的设置,使用业界标准的 `webpack-bundle-analyzer`。
|
|
135
138
|
|
|
136
139
|
```bash packageManager='npm'
|
|
137
140
|
npm install -D webpack-bundle-analyzer
|
|
@@ -166,29 +169,66 @@ export default {
|
|
|
166
169
|
</Tab>
|
|
167
170
|
</Tabs>
|
|
168
171
|
|
|
169
|
-
##
|
|
172
|
+
## 它是如何运作的
|
|
170
173
|
|
|
171
|
-
Intlayer
|
|
174
|
+
Intlayer 使用一种**基于组件的方法(per-component approach)**。与全局 JSON 文件不同,你的内容会在组件旁边或是组件内部进行定义。在构建流程中,Intlayer 将会:
|
|
172
175
|
|
|
173
|
-
1.
|
|
174
|
-
2.
|
|
175
|
-
3.
|
|
176
|
+
1. **分析**你的代码以寻找 `useIntlayer` 的调用。
|
|
177
|
+
2. **构建**对应的字典内容。
|
|
178
|
+
3. **替换** `useIntlayer` 调用为依据你的配置进行优化后的代码。
|
|
176
179
|
|
|
177
|
-
|
|
180
|
+
这样能够确保:
|
|
178
181
|
|
|
179
|
-
-
|
|
180
|
-
-
|
|
182
|
+
- 如果一个组件未被导入,它的内容将不会包含在打包产物中(Dead Code Elimination / 死代码消除)。
|
|
183
|
+
- 如果一个组件被延迟加载,其内容同样会被延迟加载。
|
|
181
184
|
|
|
182
|
-
##
|
|
185
|
+
## 插件参考
|
|
186
|
+
|
|
187
|
+
Intlayer 的构建优化被划分为若干个职责单一的插件。了解它们各自的用途可以防止在配置它们时产生困惑。
|
|
188
|
+
|
|
189
|
+
### Babel 插件 (`@intlayer/babel`)
|
|
190
|
+
|
|
191
|
+
这些被直接运用在基于 Webpack 设置的 `babel.config.js` 当中(比如使用了 Babel 的 Next.js、CRA,或是自定义的 Webpack 等)。
|
|
192
|
+
|
|
193
|
+
| 插件 | 功能说明 |
|
|
194
|
+
| :---------------------------- | :--------------------------------------------------------------------------------------------------- |
|
|
195
|
+
| `intlayerExtractBabelPlugin` | 扫描 `.content.ts` 文件并把编译好的字典写入 `.intlayer/` |
|
|
196
|
+
| `intlayerOptimizeBabelPlugin` | 将 `useIntlayer('key')` 重写为 `useDictionary(hash)` 并注入匹配对应字典的 `import` 语句 |
|
|
197
|
+
| `intlayerPurgeBabelPlugin` | 扫描所有源代码文件,从已编译的 `.intlayer/**/*.json` 字典文件中删除**未被使用的内容字段** |
|
|
198
|
+
| `intlayerMinifyBabelPlugin` | **重命名内容字段的键(keys)** 为简短的字母别名(例如 `title` 变成 `a`),作用范围包括 JSON 与源代码 |
|
|
199
|
+
|
|
200
|
+
> **插件的执行顺序很重要。** 在你的 `babel.config.js` 里,purge 和 minify 的插件必须放置在 optimize 插件**之前**。优化步骤(optimize)会把 `useIntlayer('key')` 替换为模糊的 `useDictionary(hash)`,此举抹除了能够让 purge 和 minify 识别哪些字段被使用过的字典 key 信息。
|
|
201
|
+
|
|
202
|
+
每一个 Babel 插件都有对应的选项助手(options helper),该助手会在配置加载时读取一遍 `intlayer.config.ts`,并返回预解析的值:
|
|
203
|
+
|
|
204
|
+
| 选项助手 | 配套插件 |
|
|
205
|
+
| :--------------------------- | :---------------------------- |
|
|
206
|
+
| `getExtractPluginOptions()` | `intlayerExtractBabelPlugin` |
|
|
207
|
+
| `getOptimizePluginOptions()` | `intlayerOptimizeBabelPlugin` |
|
|
208
|
+
| `getPurgePluginOptions()` | `intlayerPurgeBabelPlugin` |
|
|
209
|
+
| `getMinifyPluginOptions()` | `intlayerMinifyBabelPlugin` |
|
|
210
|
+
|
|
211
|
+
### Vite 插件 (`vite-intlayer`)
|
|
212
|
+
|
|
213
|
+
Vite 用户**不需要直接对它们进行配置**。当你在 `vite.config.ts` 里调用 `withIntlayer()` 时,它们会自动生效。只需要在 `intlayer.config.ts` 中设定 `build.purge` 和 `build.minify`,即可开启相应的功能,且不需要额外的插件注册过程。
|
|
214
|
+
|
|
215
|
+
| 内部 Vite 插件 | 等效行为 |
|
|
216
|
+
| :---------------- | :---------------------------------------------------------------------------------- |
|
|
217
|
+
| Usage analyzer | 等同于 `intlayerPurgeBabelPlugin` 的分析步骤 |
|
|
218
|
+
| Dictionary prune | 等同于 `intlayerPurgeBabelPlugin` 的 JSON 写入步骤 |
|
|
219
|
+
| Dictionary minify | 等同于 `intlayerMinifyBabelPlugin` 的 JSON 写入步骤 |
|
|
220
|
+
| Babel transform | 等同于 `intlayerMinifyBabelPlugin` 的代码重命名步骤 + `intlayerOptimizeBabelPlugin` |
|
|
221
|
+
|
|
222
|
+
## 各平台配置指南
|
|
183
223
|
|
|
184
224
|
<Tabs>
|
|
185
225
|
<Tab value="nextjs">
|
|
186
226
|
|
|
187
227
|
### Next.js
|
|
188
228
|
|
|
189
|
-
Next.js
|
|
229
|
+
Next.js 需要依靠 `@intlayer/swc` 插件来进行优化步骤(导入重写),因为 Next.js 采用 SWC 作为编译器。
|
|
190
230
|
|
|
191
|
-
>
|
|
231
|
+
> 该插件并未默认安装,因为 SWC 插件在 Next.js 当中目前仍处于实验阶段。未来这部分有可能会发生改变。
|
|
192
232
|
|
|
193
233
|
```bash packageManager="npm"
|
|
194
234
|
npm install -D @intlayer/swc
|
|
@@ -206,21 +246,63 @@ pnpm add -D @intlayer/swc
|
|
|
206
246
|
bun add -d @intlayer/swc
|
|
207
247
|
```
|
|
208
248
|
|
|
209
|
-
|
|
249
|
+
安装完毕后,Intlayer 将会自动侦测并使用该插件。
|
|
250
|
+
|
|
251
|
+
至于**清除(purge)和最小化(minify)**步骤(即字段移除和字段重命名),请连同 `@intlayer/babel` 一并安装并加入 Babel 插件。由于 Next.js 依靠 SWC 处理代码转化,但仍会评估 `babel.config.js` 以决定插件配置,因此上述 Babel 插件能够在进入 SWC 前作为预处理步骤得以执行。
|
|
252
|
+
|
|
253
|
+
```bash packageManager="npm"
|
|
254
|
+
npm install -D @intlayer/babel
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
```javascript fileName="babel.config.js"
|
|
258
|
+
const {
|
|
259
|
+
intlayerPurgeBabelPlugin,
|
|
260
|
+
intlayerMinifyBabelPlugin,
|
|
261
|
+
getPurgePluginOptions,
|
|
262
|
+
getMinifyPluginOptions,
|
|
263
|
+
} = require("@intlayer/babel");
|
|
264
|
+
|
|
265
|
+
module.exports = {
|
|
266
|
+
presets: ["next/babel"],
|
|
267
|
+
plugins: [
|
|
268
|
+
// Purge: 移除 .intlayer/**/*.json 里未被使用的内容字段
|
|
269
|
+
[intlayerPurgeBabelPlugin, getPurgePluginOptions()],
|
|
270
|
+
// Minify: 对 JSON 以及源代码里的内容字段的键(keys)进行重命名
|
|
271
|
+
[intlayerMinifyBabelPlugin, getMinifyPluginOptions()],
|
|
272
|
+
// 注意: 在这里不需要使用 intlayerOptimizeBabelPlugin,因为
|
|
273
|
+
// @intlayer/swc 已经处理了 useIntlayer → useDictionary 的重写过程。
|
|
274
|
+
],
|
|
275
|
+
};
|
|
276
|
+
```
|
|
210
277
|
|
|
211
278
|
</Tab>
|
|
212
279
|
<Tab value="vite">
|
|
213
280
|
|
|
214
281
|
### Vite
|
|
215
282
|
|
|
216
|
-
Vite
|
|
283
|
+
Vite 使用了包含在 `vite-intlayer` 依赖当中的 `@intlayer/babel` 插件。整个优化管线 —— 包括导入重写、清除和压缩 —— 是默认开启的,且无需任何额外的插件注册。
|
|
284
|
+
|
|
285
|
+
在 `intlayer.config.ts` 里设定相对应的标志来开启 purge 以及 minify:
|
|
286
|
+
|
|
287
|
+
```typescript fileName="intlayer.config.ts"
|
|
288
|
+
import type { IntlayerConfig } from "intlayer";
|
|
289
|
+
|
|
290
|
+
const config: IntlayerConfig = {
|
|
291
|
+
build: {
|
|
292
|
+
purge: true, // 将未被使用的字段从打好的 JSON 包中移除
|
|
293
|
+
minify: true, // 将字段名重命名为简短的别名
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
export default config;
|
|
298
|
+
```
|
|
217
299
|
|
|
218
300
|
</Tab>
|
|
219
301
|
<Tab value="webpack">
|
|
220
302
|
|
|
221
|
-
### Webpack
|
|
303
|
+
### Webpack (以及配置了 Babel 的 Next.js)
|
|
222
304
|
|
|
223
|
-
|
|
305
|
+
安装 `@intlayer/babel`:
|
|
224
306
|
|
|
225
307
|
```bash packageManager="npm"
|
|
226
308
|
npm install -D @intlayer/babel
|
|
@@ -238,73 +320,101 @@ pnpm add -D @intlayer/babel
|
|
|
238
320
|
bun add -d @intlayer/babel
|
|
239
321
|
```
|
|
240
322
|
|
|
241
|
-
|
|
323
|
+
在 `babel.config.js` 里按照正确的顺序添加所有四个插件:
|
|
324
|
+
|
|
325
|
+
```javascript fileName="babel.config.js"
|
|
242
326
|
const {
|
|
243
|
-
|
|
327
|
+
intlayerExtractBabelPlugin,
|
|
328
|
+
intlayerPurgeBabelPlugin,
|
|
329
|
+
intlayerMinifyBabelPlugin,
|
|
244
330
|
intlayerOptimizeBabelPlugin,
|
|
331
|
+
getExtractPluginOptions,
|
|
332
|
+
getPurgePluginOptions,
|
|
333
|
+
getMinifyPluginOptions,
|
|
334
|
+
getOptimizePluginOptions,
|
|
245
335
|
} = require("@intlayer/babel");
|
|
246
336
|
|
|
247
337
|
module.exports = {
|
|
248
|
-
plugins: [
|
|
338
|
+
plugins: [
|
|
339
|
+
// Extract: 编译 .content.ts 文件 → .intlayer/**/*.json
|
|
340
|
+
[intlayerExtractBabelPlugin, getExtractPluginOptions()],
|
|
341
|
+
|
|
342
|
+
// Purge: 从 .intlayer/**/*.json 移除不必要的字段
|
|
343
|
+
// (读取 intlayer.config.ts 内的 build.purge 配置)
|
|
344
|
+
[intlayerPurgeBabelPlugin, getPurgePluginOptions()],
|
|
345
|
+
|
|
346
|
+
// Minify: 压缩并重命名 JSON + 源代码里的字段名
|
|
347
|
+
// (读取 intlayer.config.ts 内的 build.minify 配置)
|
|
348
|
+
[intlayerMinifyBabelPlugin, getMinifyPluginOptions()],
|
|
349
|
+
|
|
350
|
+
// Optimize: 重写 useIntlayer('key') → useDictionary(hash)
|
|
351
|
+
// 它必须位于末尾,因为该操作会抹去原本的 dictionary 键名。
|
|
352
|
+
[intlayerOptimizeBabelPlugin, getOptimizePluginOptions()],
|
|
353
|
+
],
|
|
249
354
|
};
|
|
250
355
|
```
|
|
251
356
|
|
|
252
357
|
</Tab>
|
|
253
358
|
</Tabs>
|
|
254
359
|
|
|
255
|
-
##
|
|
360
|
+
## 配置选项
|
|
256
361
|
|
|
257
|
-
|
|
362
|
+
你可通过在你的 `intlayer.config.ts` 里的 `build` 属性来控制 Intlayer 怎样去优化你的代码包。
|
|
258
363
|
|
|
259
364
|
```typescript fileName="intlayer.config.ts"
|
|
260
365
|
import { Locales, type IntlayerConfig } from "intlayer";
|
|
261
366
|
|
|
262
367
|
const config: IntlayerConfig = {
|
|
263
368
|
internationalization: {
|
|
264
|
-
locales: [Locales.ENGLISH, Locales.
|
|
369
|
+
locales: [Locales.ENGLISH, Locales.CHINESE],
|
|
265
370
|
defaultLocale: Locales.ENGLISH,
|
|
266
371
|
},
|
|
267
372
|
dictionary: {
|
|
268
373
|
importMode: "dynamic",
|
|
269
374
|
},
|
|
270
375
|
build: {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
* 指示构建是否应检查 TypeScript 类型
|
|
283
|
-
*/
|
|
284
|
-
checkTypes: false;
|
|
376
|
+
// 决定在构建时是否直接用直引字典覆盖 useIntlayer() 的调用。
|
|
377
|
+
// undefined = 自动(在生产环境中开启),true = 始终开启,false = 始终关闭。
|
|
378
|
+
optimize: undefined,
|
|
379
|
+
|
|
380
|
+
// 将已编译字典里的字段键名改写为简短的字母名称(例如:title → a)。
|
|
381
|
+
// 这将缩小 JSON 的体积;前提条件是启用了 optimize。
|
|
382
|
+
minify: true,
|
|
383
|
+
|
|
384
|
+
// 将未曾在代码里真正访问过的内容字段移除。
|
|
385
|
+
// 前提条件是启用了 optimize。
|
|
386
|
+
purge: true,
|
|
285
387
|
},
|
|
286
388
|
};
|
|
287
389
|
|
|
288
390
|
export default config;
|
|
289
391
|
```
|
|
290
392
|
|
|
291
|
-
>
|
|
393
|
+
> 在大多数情况之下,推荐为 `optimize` 保留它的默认值(`undefined`)。
|
|
292
394
|
|
|
293
|
-
>
|
|
395
|
+
> 请参阅配置参考资料以了解所有的选项:[配置说明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)
|
|
294
396
|
|
|
295
397
|
### 构建选项
|
|
296
398
|
|
|
297
|
-
|
|
399
|
+
| 属性 | 类型 | 默认值 | 详细说明 |
|
|
400
|
+
| :------------- | :--------------------- | :---------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
401
|
+
| **`optimize`** | `boolean \| undefined` | `undefined` | 用于开启 import 语句的重写。`undefined` = 仅在打包成生产环境模式时生效。当设定为 `false` 的时候,同样会导致 purge 以及 minify 均一并被关闭。 |
|
|
402
|
+
| **`minify`** | `boolean` | `false` | 用于对已编译好的 JSON 档案里的内容键名改写成短的单字母名称。同理也会一并将源代码里相关访问属性同样改名。仅当 `optimize` 为 `false` 时无效。 |
|
|
403
|
+
| **`purge`** | `boolean` | `false` | 用于移除无论如何也不会被调用的且静态的源文件的内容字段,从 JSON 输出中去除掉。仅当 `optimize` 为 `false` 时无效。 |
|
|
404
|
+
|
|
405
|
+
### 压缩 / Minification (重命名字段键值)
|
|
298
406
|
|
|
299
|
-
|
|
300
|
-
| :------------- | :-------- | :---------- | :-------------------------------------------------------------------------------------------------------------------------------------- |
|
|
301
|
-
| **`optimize`** | `boolean` | `undefined` | 控制是否启用构建优化。如果为 `true`,Intlayer 使用优化后的注入替换字典调用。如果为 `false`,则禁用优化。建议在生产环境中设置为 `true`。 |
|
|
302
|
-
| **`minify`** | `boolean` | `false` | 是否压缩字典以减小构建Bundle 大小。 |
|
|
303
|
-
| **`purge`** | `boolean` | `false` | 是否清除字典中未使用的键。 |
|
|
407
|
+
`build.minify` **并非**压缩你的 JavaScript —— 那是你的打包器应该处理的工作。它的工作,是把编译后的字典对应的 JSON 文件的每一个自定义内容的字段,全用短位的字母标识来替代,借此将其体积进行压缩:
|
|
304
408
|
|
|
305
|
-
|
|
409
|
+
```
|
|
410
|
+
// Minify 之前
|
|
411
|
+
{ "title": "Hello", "subtitle": "World" }
|
|
412
|
+
|
|
413
|
+
// Minify 之后
|
|
414
|
+
{ "a": "Hello", "b": "World" }
|
|
415
|
+
```
|
|
306
416
|
|
|
307
|
-
|
|
417
|
+
该重新命名的方法同样也会应用到那些处于代码里的属性名访问阶段,所以在最终编译好的结果里,`content.title` 便会演变为 `content.a`。它们在运行时的实际表现完全一致。
|
|
308
418
|
|
|
309
419
|
```typescript fileName="intlayer.config.ts"
|
|
310
420
|
import type { IntlayerConfig } from "intlayer";
|
|
@@ -318,11 +428,13 @@ const config: IntlayerConfig = {
|
|
|
318
428
|
export default config;
|
|
319
429
|
```
|
|
320
430
|
|
|
321
|
-
>
|
|
431
|
+
> 如果在 `optimize` 被设为 `false`、又或是启用了可视化编辑器也就是当 `editor.enabled` 设定为了 `true` 时(由于编辑器需要保留字段名称以便做后续处理),重命名这个操作都将会被跳过。
|
|
322
432
|
|
|
323
|
-
|
|
433
|
+
> 同理,如果是利用了 `importMode: 'fetch'` 来载入字段时此过程同样不适用。因为它们的内容会以原始命名由后端 API 所提供,对客户端内容随意重命名会破坏客户端与服务端的匹配契约。
|
|
324
434
|
|
|
325
|
-
|
|
435
|
+
### 字段清除 / Purging (去掉未被引用的字段内容)
|
|
436
|
+
|
|
437
|
+
`build.purge` 能自动分析究竟哪些字段真真切切地被你的源代码所引用,进而只把实际引用过的数据予以保留,把其他的垃圾数据从编译生成的 JSON 里排除掉。
|
|
326
438
|
|
|
327
439
|
```typescript fileName="intlayer.config.ts"
|
|
328
440
|
import type { IntlayerConfig } from "intlayer";
|
|
@@ -336,34 +448,50 @@ const config: IntlayerConfig = {
|
|
|
336
448
|
export default config;
|
|
337
449
|
```
|
|
338
450
|
|
|
339
|
-
|
|
451
|
+
**示例说明:** 我们有一个包含五个不同字段数据的字典,但是代码实际就用到了里边的俩:
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
// Purge 执行前
|
|
455
|
+
{ "title": "…", "subtitle": "…", "cta": "…", "footer": "…", "badge": "…" }
|
|
456
|
+
|
|
457
|
+
// Purge 之后(这里仅仅只用到了 title 与 subtitle)
|
|
458
|
+
{ "title": "…", "subtitle": "…" }
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
> 与前边提到的类似,当 `optimize` 是 `false` 或是开启了可视化编辑器(`editor.enabled` 取值 `true`) 时,它会选择跳过对数据的清除操作。
|
|
462
|
+
|
|
463
|
+
> 当检测到某份代码因为异常无法顺利解析、又或者当把由 `useIntlayer` 输出的值以静态解析器难以预测分析的模式在不同组件中来回丢(比如被打包成对象传入等而未被进行解构)的时候,它同样会跳过,以此保守地保留整部字典的全部信息,避免意外发生。
|
|
340
464
|
|
|
341
|
-
###
|
|
465
|
+
### 导入模式(Import Mode)
|
|
342
466
|
|
|
343
|
-
|
|
467
|
+
对于包含多个页面和地区规模比较大的应用程序来说,你的 JSON 可能会占去绝大一部分包(Bundle)的内容。所以,你可以凭借着 `importMode` 这个参数让 Intlayer 来调整对字典内容本身的实际拉取行为。
|
|
344
468
|
|
|
345
|
-
|
|
469
|
+
### 全局定义
|
|
470
|
+
|
|
471
|
+
该参数可以经由你本身的 `intlayer.config.ts` 这个文件在全局进行指定。
|
|
346
472
|
|
|
347
473
|
```typescript fileName="intlayer.config.ts"
|
|
348
474
|
import type { IntlayerConfig } from "intlayer";
|
|
349
475
|
|
|
350
476
|
const config: IntlayerConfig = {
|
|
351
|
-
|
|
352
|
-
|
|
477
|
+
dictionary: {
|
|
478
|
+
importMode: "dynamic", // 默认为 'static'
|
|
353
479
|
},
|
|
354
480
|
};
|
|
355
481
|
|
|
356
482
|
export default config;
|
|
357
483
|
```
|
|
358
484
|
|
|
359
|
-
|
|
485
|
+
### 为字典独立配置
|
|
486
|
+
|
|
487
|
+
我们也可以在这其中部分独立词典原本配置内的 `.content.{{ts|tsx|js|jsx|mjs|cjs|json|jsonc|json5|md|mdx|yaml|yml}}` 把该参数改写成另外想要的规则。
|
|
360
488
|
|
|
361
489
|
```ts
|
|
362
490
|
import { type Dictionary, t } from "intlayer";
|
|
363
491
|
|
|
364
492
|
const appContent: Dictionary = {
|
|
365
493
|
key: "app",
|
|
366
|
-
importMode: "dynamic", //
|
|
494
|
+
importMode: "dynamic", // 将原本的模式改写
|
|
367
495
|
content: {
|
|
368
496
|
// ...
|
|
369
497
|
},
|
|
@@ -372,83 +500,103 @@ const appContent: Dictionary = {
|
|
|
372
500
|
export default appContent;
|
|
373
501
|
```
|
|
374
502
|
|
|
375
|
-
| 属性 |
|
|
376
|
-
| :--------------- | :--------------------------------- | :--------- |
|
|
377
|
-
| **`importMode`** | `'static'`, `'dynamic'`, `'fetch'` | `'static'` |
|
|
503
|
+
| 属性 | 取值类型 | 默认设置 | 描述说明 |
|
|
504
|
+
| :--------------- | :--------------------------------- | :--------- | :------------------------------------------------------------------------------------------------- |
|
|
505
|
+
| **`importMode`** | `'static'`, `'dynamic'`, `'fetch'` | `'static'` | **已被弃用**: 建议调整为 `dictionary.importMode`。这决定了应当怎样加载各项字典。(细节参考下文)。 |
|
|
378
506
|
|
|
379
|
-
`importMode`
|
|
380
|
-
您可以在 `intlayer.config.ts` 文件的 `dictionary` 对象下全局定义它,或者在字典的 `.content.ts` 文件中覆盖它。
|
|
507
|
+
这处 `importMode` 设置用于指挥组件拉取各项内容的真实手段。要么被指定在了全局 `intlayer.config.ts` 中的 `dictionary` 里,要不便以 `content.ts` 形式来分别定制。
|
|
381
508
|
|
|
382
|
-
### 1.
|
|
509
|
+
### 1. 静态模式(Static Mode - `default`)
|
|
383
510
|
|
|
384
|
-
|
|
511
|
+
在这个默认设定下,Intlayer 自动把全部 `useIntlayer` 变成了 `useDictionary` 以做到将所需的翻译数据无缝拼接入 JavaScript 包内。
|
|
385
512
|
|
|
386
|
-
-
|
|
387
|
-
-
|
|
388
|
-
-
|
|
513
|
+
- **优势(Pros):** 即时就能被加载(属于同步型),由于没有水合(hydration)从而意味着额外的零请求。
|
|
514
|
+
- **缺点(Cons):** 但这个包同样也就塞满了给该组件用的**各种不同可用语言的对应版本**,这非常占空间。
|
|
515
|
+
- **最佳应用场合:** 单页应用(SPA)。
|
|
389
516
|
|
|
390
|
-
|
|
517
|
+
**代码在转换之后的图示(举例):**
|
|
391
518
|
|
|
392
519
|
```tsx
|
|
393
|
-
//
|
|
520
|
+
// 这是你的原本代码
|
|
394
521
|
const content = useIntlayer("my-key");
|
|
395
522
|
|
|
396
|
-
//
|
|
523
|
+
// (静态) 优化图解。
|
|
524
|
+
// 仅为了解释说明而列,出于优化实际上的最终输出略有差别
|
|
397
525
|
const content = useDictionary({
|
|
398
526
|
key: "my-key",
|
|
399
527
|
content: {
|
|
400
528
|
nodeType: "translation",
|
|
401
529
|
translation: {
|
|
402
530
|
en: "My title",
|
|
403
|
-
|
|
531
|
+
zh: "我的标题",
|
|
404
532
|
},
|
|
405
533
|
},
|
|
406
534
|
});
|
|
407
535
|
```
|
|
408
536
|
|
|
409
|
-
### 2.
|
|
537
|
+
### 2. 动态模式(Dynamic Mode)
|
|
410
538
|
|
|
411
|
-
|
|
539
|
+
在这一设定之下,Intlayer 自动把全部 `useIntlayer` 全给变成了 `useDictionaryAsync`。这个操作能将拉取行文变成动态 `import()`(这和 Suspense 的表现接近),并有针对性地对当地所在的特殊语言去单独异步请求其实际数据。
|
|
412
540
|
|
|
413
|
-
-
|
|
414
|
-
-
|
|
415
|
-
-
|
|
541
|
+
- **优势(Pros):** **支持基于地区语言所实施的代码树抖动分离(Tree shaking)。** 说白了就是,正在浏览英语界面的使用者**仅仅**会只被发送那部分英文对应的词典内容,法文或是其他国家的数据都不会加载。
|
|
542
|
+
- **缺点(Cons):** 这个阶段下,将会让组件因数据要求而针对各项水合需求(hydration)各自产生不同种的调用申请(拉取各部件内容)。
|
|
543
|
+
- **最佳应用场合:** 内容巨大且充斥了长文博客的复杂平台、亦或是本身涵盖了大量的翻译种类因而在包(bundle)体积极为严格的情况下使用。
|
|
416
544
|
|
|
417
|
-
|
|
545
|
+
**代码在转换之后的图示(举例):**
|
|
418
546
|
|
|
419
547
|
```tsx
|
|
420
|
-
//
|
|
548
|
+
// 这是你的原本代码
|
|
421
549
|
const content = useIntlayer("my-key");
|
|
422
550
|
|
|
423
|
-
//
|
|
551
|
+
// (动态) 优化图解。
|
|
552
|
+
// 仅为了解释说明而列,出于优化实际上的最终输出略有差别
|
|
424
553
|
const content = useDictionaryAsync({
|
|
425
554
|
en: () =>
|
|
426
555
|
import(".intlayer/dynamic_dictionary/my-key/en.json").then(
|
|
427
556
|
(mod) => mod.default
|
|
428
557
|
),
|
|
429
|
-
|
|
430
|
-
import(".intlayer/dynamic_dictionary/my-key/
|
|
558
|
+
zh: () =>
|
|
559
|
+
import(".intlayer/dynamic_dictionary/my-key/zh.json").then(
|
|
431
560
|
(mod) => mod.default
|
|
432
561
|
),
|
|
433
562
|
});
|
|
434
563
|
```
|
|
435
564
|
|
|
436
|
-
>
|
|
565
|
+
> 使用了 `importMode: 'dynamic'` 这个方案之时,如果某一页刚好凑齐了 100 个包含了 `useIntlayer` 内容的部件时,浏览器就有极大的概率朝着服务器丢过去多达 100 种不重样的 fetch 请求。如果意在免于这样的连环「瀑布效应」,尝试尽可能去少写单个的独立 `.content` (尝试着每几块凑一起合并起来比如每一个大的分块区共享其内容字典,而非是切得那么碎,比如连每一个单小按钮都设单独请求。)如果把多个带有单独名字 `.content` 内容给附加上相同的 Key 名称,程序依然能够很轻易将这些零散碎落的数据融合成单独庞大且统一的一本完整的字典对象里去。
|
|
566
|
+
|
|
567
|
+
### 3. Fetch 模式(Fetch Mode)
|
|
568
|
+
|
|
569
|
+
行为跟 Dynamic 有所重叠,不过最优先则是朝 Intlayer Live Sync API 请求其词典内容。假如获取数据时遭到拦截或者内容不属于实时的数据内容体系的话,接下来便将其作为兜底顺延递回之前的动切请求。
|
|
437
570
|
|
|
438
|
-
|
|
571
|
+
**代码在转换之后的图示(举例):**
|
|
439
572
|
|
|
440
|
-
|
|
573
|
+
```tsx
|
|
574
|
+
// 这是你的原本代码
|
|
575
|
+
const content = useIntlayer("my-key");
|
|
576
|
+
|
|
577
|
+
// 能够将它(Fetch)看成这类实现
|
|
578
|
+
const content = useDictionaryAsync({
|
|
579
|
+
en: () =>
|
|
580
|
+
fetch("https://intlayer.my-domain.com/dictionary/my-key/en").then((res) =>
|
|
581
|
+
res.json()
|
|
582
|
+
),
|
|
583
|
+
zh: () =>
|
|
584
|
+
fetch("https://intlayer.my-domain.com/dictionary/my-key/zh").then((res) =>
|
|
585
|
+
res.json()
|
|
586
|
+
),
|
|
587
|
+
});
|
|
588
|
+
```
|
|
441
589
|
|
|
442
|
-
>
|
|
590
|
+
> 如果还需要获得对于 CMS 获取方面的认知的话:可以去查看 [CMS 说明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_CMS.md)
|
|
443
591
|
|
|
444
|
-
>
|
|
592
|
+
> 此模式同样会一如既往地因为 JSON 内容会直接借由后端直接输送而不遭受 purge 跟 minify 等等这几类数据剔除方案的干扰。
|
|
445
593
|
|
|
446
|
-
##
|
|
594
|
+
## 概要: 静态 和 动态
|
|
447
595
|
|
|
448
|
-
|
|
|
449
|
-
|
|
|
450
|
-
| **JS
|
|
451
|
-
|
|
|
452
|
-
|
|
|
453
|
-
|
|
|
454
|
-
|
|
|
596
|
+
| 模式特征 | 静态模式(Static Mode) | 动态模式(Dynamic Mode) |
|
|
597
|
+
| :------------------------- | :----------------------------------------------------------- | :---------------------------------------- |
|
|
598
|
+
| **JS 产生的 Bundle 体积** | 庞大(包含了供各个不同组件使用时调用的其他全部外语语系信息) | 小巧(内容直接为空、只有代码框架) |
|
|
599
|
+
| **最初加载所需时间** | 极速(毕竟那些所需信息一开始都已经存在于包(Bundle)里面了) | 略需等待(拉取 JSON 所需消耗时间) |
|
|
600
|
+
| **附带发生的网络请求** | 无,无需任何等待直接 0 次 | 取决字典请求次数(一次 Key 取出就是一回) |
|
|
601
|
+
| **树抖动(Tree Shaking)** | 按单一组件的级别而做分割 | 依组件级别外加依据地区与语种去实施拆分 |
|
|
602
|
+
| **最佳应用与方案环境** | 普通交互式元件内容或单一界面的轻型程序等 | 极其充满内容的纯文区块或极其繁多的语系 |
|