@modern-js/main-doc 2.40.0 → 2.42.0
Sign up to get free protection for your applications and to get access to all the features.
- package/docs/en/apis/app/commands.mdx +3 -1
- package/docs/en/community/contributing-guide.mdx +10 -0
- package/docs/en/configure/app/output/enable-inline-route-manifests.mdx +14 -4
- package/docs/en/configure/app/tools/bundler-chain.mdx +0 -4
- package/docs/en/guides/advanced-features/build-performance.mdx +156 -0
- package/docs/en/guides/advanced-features/optimize-bundle.mdx +115 -0
- package/docs/en/guides/advanced-features/rspack-start.mdx +1 -1
- package/docs/en/guides/advanced-features/source-build.mdx +161 -0
- package/docs/en/guides/advanced-features/testing.mdx +2 -2
- package/docs/en/guides/advanced-features/using-storybook.mdx +1 -1
- package/docs/en/guides/advanced-features/web-server.mdx +1 -1
- package/docs/en/guides/get-started/introduction.mdx +8 -13
- package/docs/en/guides/get-started/tech-stack.mdx +1 -1
- package/docs/en/guides/troubleshooting/builder.mdx +550 -21
- package/docs/en/guides/troubleshooting/hmr.mdx +148 -0
- package/docs/zh/apis/app/commands.mdx +3 -1
- package/docs/zh/community/contributing-guide.mdx +10 -0
- package/docs/zh/configure/app/output/enable-inline-route-manifests.mdx +6 -6
- package/docs/zh/configure/app/tools/bundler-chain.mdx +0 -4
- package/docs/zh/guides/advanced-features/build-performance.mdx +156 -0
- package/docs/zh/guides/advanced-features/optimize-bundle.mdx +115 -0
- package/docs/zh/guides/advanced-features/rspack-start.mdx +1 -1
- package/docs/zh/guides/advanced-features/source-build.mdx +161 -0
- package/docs/zh/guides/advanced-features/testing.mdx +1 -1
- package/docs/zh/guides/advanced-features/using-storybook.mdx +1 -1
- package/docs/zh/guides/advanced-features/web-server.mdx +1 -1
- package/docs/zh/guides/get-started/introduction.mdx +8 -15
- package/docs/zh/guides/get-started/tech-stack.mdx +1 -1
- package/docs/zh/guides/topic-detail/generator/plugin/structure.md +1 -1
- package/docs/zh/guides/troubleshooting/builder.mdx +553 -20
- package/docs/zh/guides/troubleshooting/hmr.mdx +148 -0
- package/package.json +8 -8
- package/rspress.config.ts +8 -4
- package/src/components/SolutionCards/index.module.scss +4 -0
- package/src/components/SolutionCards/index.tsx +5 -1
- package/src/pages/index.tsx +0 -10
@@ -7,7 +7,7 @@ sidebar_position: 1
|
|
7
7
|
|
8
8
|
**Modern.js 是字节跳动 Web 工程体系的开源版本**,它提供多个解决方案,来帮助开发者解决不同研发场景下的问题。
|
9
9
|
|
10
|
-
目前 Modern.js
|
10
|
+
目前 Modern.js 包含两个解决方案,分别面向 Web 应用开发场景 和 npm 包开发场景:
|
11
11
|
|
12
12
|
import { SolutionCards } from '@site/src/components/SolutionCards';
|
13
13
|
|
@@ -23,32 +23,21 @@ import { SolutionCards } from '@site/src/components/SolutionCards';
|
|
23
23
|
description: '易用、高性能的 npm 包开发方案',
|
24
24
|
link: 'http://modernjs.dev/module-tools/',
|
25
25
|
},
|
26
|
-
{
|
27
|
-
title: 'Modern.js Builder',
|
28
|
-
description: '基于 Rspack 的 Web 构建工具',
|
29
|
-
link: 'http://modernjs.dev/builder/',
|
30
|
-
},
|
31
26
|
]}
|
32
27
|
/>
|
33
28
|
|
34
|
-
作为 Modern.js 工程体系的一部分,以上每个解决方案都可以被单独使用,并且各自部署了独立的文档站点。开发者可以按需选择其中的一个或多个解决方案来使用。
|
35
|
-
|
36
29
|
## 关于文档
|
37
30
|
|
38
31
|
**当前文档站对应的是 Modern.js 框架**,适用于开发 Web 应用。
|
39
32
|
|
40
|
-
- 如果你需要开发一个 npm 包,请移步 [Modern.js Module](https://modernjs.dev/module-tools)
|
41
|
-
-
|
33
|
+
- 如果你需要开发一个 npm 包,请移步 [Modern.js Module 文档](https://modernjs.dev/module-tools)。
|
34
|
+
- 如果你需要一个构建工具来打包 Web 应用,请移步 [Rsbuild 文档](https://rsbuild.dev/)。
|
35
|
+
- 如果你需要开发一个文档站点,推荐使用 [Rspress 文档](https://rspress.dev/)。
|
42
36
|
|
43
37
|
:::tip
|
44
38
|
由于 Modern.js 框架的使用最为广泛,在本文档站中,我们会省略「框架」,直接称其为 Modern.js。
|
45
39
|
:::
|
46
40
|
|
47
|
-
Modern.js 也可以与以下解决方案结合使用:
|
48
|
-
|
49
|
-
- 如果你需要开发一个文档站点,推荐使用 [Rspress](https://rspress.dev/) 文档。
|
50
|
-
- 如果你需要引入微前端架构,推荐使用 [Garfish](https://garfishjs.org/)。
|
51
|
-
|
52
41
|
## Modern.js 框架
|
53
42
|
|
54
43
|
**Modern.js 框架是一个基于 React 的渐进式 Web 开发框架**。在字节跳动内部,我们将 Modern.js 封装为上层框架,并支撑了数千个 Web 应用的研发。
|
@@ -86,6 +75,10 @@ Umi 是中文社区中非常流行的 React 框架,也是蚂蚁集团的底层
|
|
86
75
|
|
87
76
|
此外,Modern.js 的服务端能力更加丰富,包括完备的 SSR 能力、一体化 BFF 开发能力和自定义 Web Server 支持。这些能力经过了字节跳动大量线上应用的验证,可以直接用于生产环境。
|
88
77
|
|
78
|
+
### Remix
|
79
|
+
|
80
|
+
请参考 [Modern.js vs Remix](https://github.com/web-infra-dev/modern.js/discussions/4872)。
|
81
|
+
|
89
82
|
## 下一步
|
90
83
|
|
91
84
|
如果你希望了解如何使用 Modern.js 框架,可以尝试 [创建第一个应用](/tutorials/first-app/c01-start),或是阅读 [快速上手](/guides/get-started/quick-start)。
|
@@ -14,7 +14,7 @@ Modern.js 框架默认集成了一些社区中流行的库和开发工具。
|
|
14
14
|
|
15
15
|
Modern.js 使用 [React 18](https://react.dev/) 来构建用户界面,同时也兼容 React 17。
|
16
16
|
|
17
|
-
Modern.js 底层的
|
17
|
+
Modern.js 底层的 Rsbuild 支持构建 Vue 应用,如果你需要使用 Vue,可以参考[「Rsbuild - Vue」](https://rsbuild.dev/zh/guide/framework/vue3)。
|
18
18
|
|
19
19
|
---
|
20
20
|
|
@@ -99,7 +99,7 @@ export default function (context: IPluginContext) {
|
|
99
99
|
|
100
100
|
## templates
|
101
101
|
|
102
|
-
`templates` 目录存在当前定制化方式的模板文件,支持 [Handlebars](https://handlebarsjs.com/) 和 [EJS](https://ejs.co/)
|
102
|
+
`templates` 目录存在当前定制化方式的模板文件,支持 [Handlebars](https://handlebarsjs.com/) 和 [EJS](https://ejs.co/) 格式,将根据模板文件后缀使用不同的渲染引擎执行渲染,如果无后缀,将会直接复制模板文件到目标目录。
|
103
103
|
|
104
104
|
如果模板文件为 `js`、`ts` 或者 `json` 文件,推荐直接使用 `.handlebars` 或者 `.ejs` 后缀,可避免项目 eslint 报错和在 Monorepo 中项目识别问题。
|
105
105
|
|
@@ -6,34 +6,567 @@ sidebar_position: 3
|
|
6
6
|
|
7
7
|
如果你遇到了构建相关的问题,可以参考以下文档:
|
8
8
|
|
9
|
-
|
9
|
+
### 如何配置组件库按需引入?
|
10
10
|
|
11
|
-
|
11
|
+
如果需要配置组件库的按需引入,你可以通过 [source.transformImport](/configure/app/source/transform-import.html) 配置,这个配置的能力等价于 [babel-plugin-import](https://www.npmjs.com/package/babel-plugin-import)。
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
```ts
|
14
|
+
export default {
|
15
|
+
source: {
|
16
|
+
transformImport: [
|
17
|
+
{
|
18
|
+
libraryName: 'xxx-components',
|
19
|
+
libraryDirectory: 'es',
|
20
|
+
style: true,
|
21
|
+
},
|
22
|
+
],
|
23
|
+
},
|
24
|
+
};
|
25
|
+
```
|
16
26
|
|
17
|
-
|
27
|
+
---
|
28
|
+
|
29
|
+
### 如何在编译过程中进行 ESLint 代码校验?
|
30
|
+
|
31
|
+
出于编译性能的考虑,Modern.js 默认不会在编译过程中进行 ESLint 校验,如果需要该功能,可以手动安装并注册社区中的 [eslint-webpack-plugin](https://github.com/webpack-contrib/eslint-webpack-plugin)。
|
32
|
+
|
33
|
+
注册该插件的示例代码如下:
|
34
|
+
|
35
|
+
```js
|
36
|
+
import ESLintPlugin from 'eslint-webpack-plugin';
|
37
|
+
|
38
|
+
export default {
|
39
|
+
tools: {
|
40
|
+
bundlerChain(chain) {
|
41
|
+
chain.plugin('eslint-plugin').use(ESLintPlugin, [
|
42
|
+
{
|
43
|
+
extensions: ['.js', '.ts', '.jsx', 'tsx', '.mjs'],
|
44
|
+
},
|
45
|
+
]);
|
46
|
+
},
|
47
|
+
},
|
48
|
+
};
|
49
|
+
```
|
50
|
+
|
51
|
+
> 更详细的用法请参考 [eslint-webpack-plugin](https://github.com/webpack-contrib/eslint-webpack-plugin) 文档。
|
52
|
+
|
53
|
+
---
|
54
|
+
|
55
|
+
### 如何配置静态资源的 CDN 路径?
|
56
|
+
|
57
|
+
如果需要将 JS、CSS 等静态资源上传到 CDN 使用,那么可以通过 [output.assetPrefix](/configure/app/output/asset-prefix.html) 配置来设置静态资源的 URL 前缀。
|
58
|
+
|
59
|
+
```js
|
60
|
+
export default {
|
61
|
+
output: {
|
62
|
+
assetPrefix: 'https://cdn.example.com/assets/',
|
63
|
+
},
|
64
|
+
};
|
65
|
+
```
|
66
|
+
|
67
|
+
---
|
68
|
+
|
69
|
+
### 如何清空 webpack 编译缓存?
|
70
|
+
|
71
|
+
默认情况下,Modern.js 的 webpack 编译缓存生成在 `./node_modules/.cache/webpack` 目录下。
|
72
|
+
|
73
|
+
如果需要清空本地的编译缓存,可以执行以下命令:
|
74
|
+
|
75
|
+
```bash
|
76
|
+
rm -rf ./node_modules/.cache
|
77
|
+
```
|
78
|
+
|
79
|
+
---
|
80
|
+
|
81
|
+
### 如何移除代码中的 console?
|
82
|
+
|
83
|
+
在生产环境构建时,我们可以移除代码中的 `console`,从而避免开发环境的日志被输出到生产环境。
|
84
|
+
|
85
|
+
Modern.js 默认提供了移除 console 的配置项,请查看 [performance.removeConsole](/configure/app/performance/remove-console.html)。
|
86
|
+
|
87
|
+
---
|
88
|
+
|
89
|
+
### 如何查看最终生成的 webpack / Rspack 配置?
|
90
|
+
|
91
|
+
Modern.js 提供 [inspect 命令](/apis/app/commands.html) 用于查看项目最终生成的 Modern.js 配置以及 webpack / Rspack 配置。
|
92
|
+
|
93
|
+
```bash
|
94
|
+
➜ npx modern inspect
|
95
|
+
|
96
|
+
Inspect config succeed, open following files to view the content:
|
97
|
+
|
98
|
+
- Builder Config: /root/my-project/dist/builder.config.js
|
99
|
+
- Rspack Config (web): /root/my-project/dist/rspack.config.web.js
|
100
|
+
```
|
101
|
+
|
102
|
+
---
|
103
|
+
|
104
|
+
### 如何忽略特定 warning 日志?
|
105
|
+
|
106
|
+
默认情况下,Modern.js 会打印构建过程产生的所有 error 和 warning 日志。
|
107
|
+
|
108
|
+
如果遇到由于三方包产生大量 warning 日志,暂时又无法处理,希望忽略的情况。可通过 webpack / Rspack 提供的构建配置忽略特定 warning 日志。
|
109
|
+
|
110
|
+
```ts
|
111
|
+
export default {
|
112
|
+
tools: {
|
113
|
+
bundlerChain: chain => {
|
114
|
+
chain.ignoreWarnings([/Using \/ for division outside of calc()/]);
|
115
|
+
},
|
116
|
+
},
|
117
|
+
};
|
118
|
+
```
|
119
|
+
|
120
|
+
详细信息可参考: [ignoreWarnings](https://webpack.js.org/configuration/other-options/#ignorewarnings)。
|
121
|
+
|
122
|
+
---
|
123
|
+
|
124
|
+
### webpack 编译出现 'compilation' argument 报错?
|
125
|
+
|
126
|
+
如果编译时出现以下报错,通常是由于项目中安装了错误的 webpack 版本,或者安装了多个 webpack 版本引起:
|
127
|
+
|
128
|
+
```bash
|
129
|
+
TypeError: The 'compilation' argument must be an instance of Compilation
|
130
|
+
```
|
131
|
+
|
132
|
+
webpack 版本问题有以下几种情况:
|
133
|
+
|
134
|
+
1. 项目的 package.json 中直接声明了 webpack 依赖,并且与 Modern.js 依赖的 webpack 版本范围不同,无法匹配到同一个版本。
|
135
|
+
2. 项目里安装的多个 npm 包都依赖了 webpack,并且它们依赖的 webpack 版本范围不同,无法匹配到同一个版本。
|
136
|
+
3. 由于包管理器的 lock 机制,导致 lock 文件中产生了多个 webpack 版本。
|
137
|
+
|
138
|
+
如果是第一种情况,建议从项目的 package.json 中移除 webpack 依赖。因为 Modern.js 默认封装了 webpack 相关能力,并且会在 [tools.webpack](/configure/app/tools/webpack.html) 配置项中传入 webpack 对象。因此在大多数情况下,不建议在项目中额外安装 webpack 依赖。
|
139
|
+
|
140
|
+
如果是第二种情况,建议看看能否升级某个 npm 包,使其依赖的 webpack 版本范围与 Modern.js 保持一致。也可以通过包管理器的能力来手动统一版本,比如使用 [yarn resolutions](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/) 或 [pnpm overrides](https://pnpm.io/package_json#pnpmoverrides)。
|
141
|
+
|
142
|
+
如果是第三种情况,可以使用第二种情况中提到的两种方法,也可以尝试删除 lock 文件后重新安装来解决。
|
143
|
+
|
144
|
+
:::tip
|
145
|
+
删除 lock 文件会使项目中的依赖版本自动升级到指定范围下的最新版,请进行充分的测试。
|
146
|
+
:::
|
147
|
+
|
148
|
+
---
|
149
|
+
|
150
|
+
### 编译产物中存在未编译的 ES6+ 代码?
|
151
|
+
|
152
|
+
默认情况下,Modern.js 不会通过 `babel-loader` 或 `ts-loader` 来编译 `node_modules` 下的文件。如果项目引入的 npm 包中含有 ES6+ 语法,会被打包进产物中。
|
153
|
+
|
154
|
+
遇到这种情况时,可以通过 [source.include](/configure/app/source/include.html) 配置项来指定需要额外进行编译的目录或模块。
|
155
|
+
|
156
|
+
---
|
157
|
+
|
158
|
+
### 在 Monorepo 中引用其他模块,代码没有被正确编译?
|
159
|
+
|
160
|
+
出于编译性能的考虑,默认情况下,Modern.js 不会编译 `node_modules` 下的文件,也不会编译当前工程目录外部的文件。
|
161
|
+
|
162
|
+
因此,当你引用其他子项目的源代码时,可能会遇到类似 `You may need an additional loader to handle the result of these loaders.` 的报错。
|
163
|
+
|
164
|
+
这个问题有以下解决方法:
|
165
|
+
|
166
|
+
1. 你可以开启源码构建模式来编译 monorepo 中的其他子项目,参考[「源码构建模式」](/guides/advanced-features/source-build.html)。
|
167
|
+
2. 你可以添加 `source.include` 配置项,指定需要额外进行编译的目录或模块,参考 [source.include 用法介绍](/configure/app/source/include.html)。
|
168
|
+
3. 你可以预先构建需要引用的子项目,生成对应的构建产物,并在当前项目引用构建产物,而不是引用源代码。
|
169
|
+
|
170
|
+
---
|
171
|
+
|
172
|
+
### 编译时报错 `You may need additional loader`?
|
173
|
+
|
174
|
+
如果编译过程中遇到了以下报错提示,表示存在个别文件无法被正确编译。
|
175
|
+
|
176
|
+
```bash
|
177
|
+
Module parse failed: Unexpected token
|
178
|
+
File was processed with these loaders:
|
179
|
+
* some-loader/index.js
|
180
|
+
|
181
|
+
You may need an additional loader to handle the result of these loaders.
|
182
|
+
```
|
183
|
+
|
184
|
+
解决方法:
|
185
|
+
|
186
|
+
- 如果是引用了当前工程外部的 `.ts` 文件,或者是 node_modules 下的 `.ts` 文件,请添加 [source.include](/configure/app/source/include.html) 配置项,指定需要额外进行编译的文件。
|
187
|
+
- 如果是引用了 Modern.js 不支持的文件格式,请自行配置对应的 webpack loader 进行编译。
|
188
|
+
|
189
|
+
---
|
190
|
+
|
191
|
+
### 编译时报错 `Error: [object Object] is not a PostCSS plugin` ?
|
192
|
+
|
193
|
+
目前,Modern.js 使用的是 v8 版本的 PostCSS。如果编译过程中遇到了 `Error: [object Object] is not a PostCSS plugin` 报错提示,通常是由于引用到了错误的 PostCSS 版本导致,常见的如 `cssnano` 中 `postcss` (peerDependencies) 版本不符合预期。
|
194
|
+
|
195
|
+
可以通过 `npm ls postcss` 查找 `UNMET PEER DEPENDENCY` 的依赖,然后在 package.json 中通过指定 PostCSS 版本等方式安装正确的依赖版本即可。
|
196
|
+
|
197
|
+
```
|
198
|
+
npm ls postcss
|
199
|
+
|
200
|
+
├─┬ css-loader@6.3.0
|
201
|
+
│ └── UNMET PEER DEPENDENCY postcss@8.3.9
|
202
|
+
├─┬ css-minimizer-webpack-plugin@3.0.0
|
203
|
+
│ └── UNMET PEER DEPENDENCY postcss@8.3.9
|
204
|
+
```
|
205
|
+
|
206
|
+
---
|
207
|
+
|
208
|
+
### 打开页面后报错,提示 exports is not defined?
|
209
|
+
|
210
|
+
如果编译正常,但是打开页面后出现 `exports is not defined` 报错,通常是因为在项目中使用 Babel 编译了一个 CommonJS 模块,导致 Babel 出现异常。
|
211
|
+
|
212
|
+
在正常情况下,Modern.js 是不会使用 Babel 来编译 CommonJS 模块的。如果项目中使用了 [source.include](/configure/app/source/include.html) 配置项,则可能会把一些 CommonJS 模块加入到 Babel 编译中。
|
213
|
+
|
214
|
+
该问题有两种解决方法:
|
215
|
+
|
216
|
+
1. 避免将 CommonJS 模块加入到 Babel 编译中。
|
217
|
+
2. 将 Babel 的 `sourceType` 配置项设置为 `unambiguous`,示例如下:
|
218
|
+
|
219
|
+
```js
|
220
|
+
export default {
|
221
|
+
tools: {
|
222
|
+
babel(config) {
|
223
|
+
config.sourceType = 'unambiguous';
|
224
|
+
},
|
225
|
+
},
|
226
|
+
};
|
227
|
+
```
|
228
|
+
|
229
|
+
将 `sourceType` 设置为 `unambiguous` 可能会产生一些其他影响,请参考 [Babel 官方文档](https://babeljs.io/docs/en/options#sourcetype)。
|
230
|
+
|
231
|
+
---
|
232
|
+
|
233
|
+
### 编译时报错 "Error: ES Modules may not assign module.exports or exports.\*, Use ESM export syntax"?
|
234
|
+
|
235
|
+
如果编译时出现以下报错,通常也是因为在项目中使用 Babel 编译了一个 CommonJS 模块,解决方法与上述的 `exports is not defined` 问题一致。
|
236
|
+
|
237
|
+
```bash
|
238
|
+
Error: ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: 581
|
239
|
+
```
|
240
|
+
|
241
|
+
更多信息请参考 issue:[babel#12731](https://github.com/babel/babel/issues/12731)。
|
242
|
+
|
243
|
+
---
|
18
244
|
|
19
|
-
|
245
|
+
### 编译时报错 "export 'foo' (imported as 'foo') was not found in './utils'"?
|
20
246
|
|
21
|
-
|
22
|
-
- 如何在编译过程中进行 ESLint 代码校验?
|
23
|
-
- 如何配置静态资源的 CDN 路径?
|
247
|
+
如果编译的过程中出现此报错,说明代码中引用了一个不存在的导出。
|
24
248
|
|
25
|
-
|
249
|
+
比如以下例子,`index.ts` 中引用了 `utils.ts` 中的 `foo` 变量, 但 `utils.ts` 实际上只导出了 `bar` 变量。
|
26
250
|
|
27
|
-
|
251
|
+
```ts
|
252
|
+
// utils.ts
|
253
|
+
export const bar = 'bar';
|
254
|
+
|
255
|
+
// index.ts
|
256
|
+
import { foo } from './utils';
|
257
|
+
```
|
258
|
+
|
259
|
+
在这种情况下,Modern.js 会抛出以下错误:
|
260
|
+
|
261
|
+
```bash
|
262
|
+
Compile Error:
|
263
|
+
File: ./src/index.ts
|
264
|
+
export 'foo' (imported as 'foo') was not found in './utils' (possible exports: bar)
|
265
|
+
```
|
266
|
+
|
267
|
+
当你遇到该问题时,首先需要检查相关代码里 import / export 的内容是否正确,并修正相关错误。
|
268
|
+
|
269
|
+
常见的错误写法有:
|
270
|
+
|
271
|
+
- 引入了不存在的变量:
|
272
|
+
|
273
|
+
```ts
|
274
|
+
// utils.ts
|
275
|
+
export const bar = 'bar';
|
276
|
+
|
277
|
+
// index.ts
|
278
|
+
import { foo } from './utils';
|
279
|
+
```
|
280
|
+
|
281
|
+
- re-export 了一个类型,但是没有添加 `type` 修饰符,导致 babel 等编译工具无法识别到类型导出,导致编译异常。
|
282
|
+
|
283
|
+
```ts
|
284
|
+
// utils.ts
|
285
|
+
export type Foo = 'bar';
|
286
|
+
|
287
|
+
// index.ts
|
288
|
+
export { Foo } from './utils'; // 错误写法
|
289
|
+
export type { Foo } from './utils'; // 正确写法
|
290
|
+
```
|
291
|
+
|
292
|
+
在个别情况下,以上报错是由第三方依赖引入的,你无法直接修改它。此时,如果你确定该问题不影响你的应用,那么可以添加以下配置,将 `error` 日志修改为 `warn` 级别:
|
293
|
+
|
294
|
+
```ts
|
295
|
+
export default {
|
296
|
+
tools: {
|
297
|
+
webpackChain(chain) {
|
298
|
+
chain.module.parser.merge({
|
299
|
+
javascript: {
|
300
|
+
exportsPresence: 'warn',
|
301
|
+
},
|
302
|
+
});
|
303
|
+
},
|
304
|
+
},
|
305
|
+
};
|
306
|
+
```
|
307
|
+
|
308
|
+
同时,你需要尽快联系第三方依赖的开发者来修复相应的问题。
|
309
|
+
|
310
|
+
> 你可以查看 webpack 的文档来了解 [module.parser.javascript.exportsPresence](https://webpack.js.org/configuration/module/#moduleparserjavascriptexportspresence) 的更多细节。
|
311
|
+
|
312
|
+
---
|
313
|
+
|
314
|
+
### 编译进度条卡死,但终端无 Error 日志?
|
315
|
+
|
316
|
+
当编译进度条卡死,但终端无 Error 日志时,通常是因为编译过程中出现了异常。在某些情况下,当 Error 被 webpack 或其他模块捕获后,错误日志不会被正确输出。最为常见的场景是 Babel 配置出现异常,抛出 Error 后被 webpack 捕获,而 webpack 在个别情况下吞掉了 Error。
|
317
|
+
|
318
|
+
**解决方法:**
|
319
|
+
|
320
|
+
如果你修改 Babel 配置后出现此问题,建议检查是否有以下错误用法:
|
321
|
+
|
322
|
+
1. 配置了一个不存在的 plugin 或 preset,可能是名称拼写错误,或是未正确安装。
|
323
|
+
|
324
|
+
```ts
|
325
|
+
// 错误示例
|
326
|
+
export default {
|
327
|
+
tools: {
|
328
|
+
babel(config, { addPlugins }) {
|
329
|
+
// 该插件名称错误,或者未安装
|
330
|
+
addPlugins('babel-plugin-not-exists');
|
331
|
+
},
|
332
|
+
},
|
333
|
+
};
|
334
|
+
```
|
335
|
+
|
336
|
+
2. 是否配置了多个 babel-plugin-import,但是没有在数组的第三项声明每一个 babel-plugin-import 的名称。
|
337
|
+
|
338
|
+
```ts
|
339
|
+
// 错误示例
|
340
|
+
export default {
|
341
|
+
tools: {
|
342
|
+
babel(config, { addPlugins }) {
|
343
|
+
addPlugins([
|
344
|
+
[
|
345
|
+
'babel-plugin-import',
|
346
|
+
{ libraryName: 'antd', libraryDirectory: 'es' },
|
347
|
+
],
|
348
|
+
[
|
349
|
+
'babel-plugin-import',
|
350
|
+
{ libraryName: 'antd-mobile', libraryDirectory: 'es' },
|
351
|
+
],
|
352
|
+
]);
|
353
|
+
},
|
354
|
+
},
|
355
|
+
};
|
356
|
+
```
|
357
|
+
|
358
|
+
```ts
|
359
|
+
// 正确示例
|
360
|
+
export default {
|
361
|
+
tools: {
|
362
|
+
babel(config, { addPlugins }) {
|
363
|
+
addPlugins([
|
364
|
+
[
|
365
|
+
'babel-plugin-import',
|
366
|
+
{ libraryName: 'antd', libraryDirectory: 'es' },
|
367
|
+
'antd',
|
368
|
+
],
|
369
|
+
[
|
370
|
+
'babel-plugin-import',
|
371
|
+
{ libraryName: 'antd-mobile', libraryDirectory: 'es' },
|
372
|
+
'antd-mobile',
|
373
|
+
],
|
374
|
+
]);
|
375
|
+
},
|
376
|
+
},
|
377
|
+
};
|
378
|
+
```
|
379
|
+
|
380
|
+
除了上述原因外,还有一种可能会导致 Babel 编译卡死,就是使用 Babel 编译了一个超过 1 万行的大型 JS 文件(通常是使用 `source.include` 编译了 node_modules 中的某个大文件)。
|
381
|
+
|
382
|
+
当 Babel 编译大文件时,Modern.js 内置的 babel-plugin-styled-components 会卡死,社区中已有 [相关 issue](https://github.com/styled-components/babel-plugin-styled-components/issues/374)。
|
383
|
+
|
384
|
+
未来 Modern.js 会考虑移除内置的 babel-plugin-styled-components。在当前版本里,你可以将 [tools.styledComponents](/configure/app/tools/styled-components.html) 设置为 `false` 来移除该插件。
|
385
|
+
|
386
|
+
```ts title="modern.config.ts"
|
387
|
+
export default {
|
388
|
+
tools: {
|
389
|
+
styledComponents: false,
|
390
|
+
},
|
391
|
+
};
|
392
|
+
```
|
393
|
+
|
394
|
+
---
|
395
|
+
|
396
|
+
### webpack 编译缓存未生效,应该如何排查?
|
397
|
+
|
398
|
+
Modern.js 默认开启了 webpack 的持久化缓存。
|
399
|
+
|
400
|
+
首次编译完成后,会自动生成缓存文件,并输出到 `./node_modules/.cache/webpack` 目录下。执行第二次编译时,会命中缓存,并大幅度提高编译速度。
|
401
|
+
|
402
|
+
当 `package.json` 等配置文件被修改时,缓存会自动失效。
|
403
|
+
|
404
|
+
如果项目中 webpack 编译缓存一直未生效,可以添加以下配置进行排查:
|
405
|
+
|
406
|
+
```ts
|
407
|
+
export default {
|
408
|
+
tools: {
|
409
|
+
webpack(config) {
|
410
|
+
config.infrastructureLogging = {
|
411
|
+
...config.infrastructureLogging,
|
412
|
+
debug: /webpack\.cache/,
|
413
|
+
};
|
414
|
+
},
|
415
|
+
},
|
416
|
+
};
|
417
|
+
```
|
418
|
+
|
419
|
+
添加以上配置后,webpack 会输出日志用于 debug,请参考 `PackFileCacheStrategy` 相关的日志来了解缓存失效的原因。
|
420
|
+
|
421
|
+
---
|
422
|
+
|
423
|
+
### 打包后发现 tree shaking 没有生效?
|
424
|
+
|
425
|
+
Modern.js 在生产构建时会默认开启 webpack 的 tree shaking 功能,tree shaking 是否能够生效,取决于业务代码能否满足 webpack 的 tree shaking 条件。
|
426
|
+
|
427
|
+
如果你遇到了 tree shaking 不生效的问题,可以检查下相关 npm 包的 `sideEffects` 配置是否正确,如果你不了解 `sideEffects` 的作用,或是对 tree shaking 背后的原理感兴趣,可以阅读以下两篇文档:
|
428
|
+
|
429
|
+
- [webpack 官方文档 - Tree Shaking](https://webpack.docschina.org/guides/tree-shaking/)
|
430
|
+
- [Tree Shaking 问题排查指南](https://bytedance.feishu.cn/docs/doccn8E1ldDct5uv1EEDQs8Ycwe)
|
431
|
+
|
432
|
+
如果你是 npm 包的开发者,可以阅读这篇文章:
|
433
|
+
|
434
|
+
- [如何编写一个友好支持 Tree-shaking 的库](https://zhuanlan.zhihu.com/p/594124786)
|
435
|
+
|
436
|
+
---
|
437
|
+
|
438
|
+
### 打包时出现 JavaScript heap out of memory?
|
439
|
+
|
440
|
+
该报错表示打包过程中出现了内存溢出问题,大多数情况下是由于打包的内容较多,超出了 Node.js 默认的内存上限。
|
441
|
+
|
442
|
+
如果出现 OOM 问题,最简单的方法是通过增加内存上限来解决,Node.js 提供了 `--max-old-space-size` 选项来对此进行设置。你可以在 CLI 命令前添加 [NODE_OPTIONS](https://nodejs.org/api/cli.html#node_optionsoptions) 来设置此参数。
|
443
|
+
|
444
|
+
比如,在 `modern build` 命令前添加参数:
|
445
|
+
|
446
|
+
```diff title="package.json"
|
447
|
+
{
|
448
|
+
"scripts": {
|
449
|
+
- "build": "modern build"
|
450
|
+
+ "build": "NODE_OPTIONS=--max_old_space_size=16384 modern build"
|
451
|
+
}
|
452
|
+
}
|
453
|
+
```
|
454
|
+
|
455
|
+
如果你执行的是其他命令,比如 `modern deploy`,请在对应的命令前添加参数。
|
456
|
+
|
457
|
+
`max_old_space_size` 参数的值代表内存上限大小(MB),一般情况下设置为 `16384`(16GB)即可。
|
458
|
+
|
459
|
+
Node.js 官方文档中有对以下参数更详细的解释:
|
460
|
+
|
461
|
+
- [NODE_OPTIONS](https://nodejs.org/api/cli.html#node_optionsoptions)
|
462
|
+
- [--max-old-space-size](https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-megabytes)
|
463
|
+
|
464
|
+
除了增加内存上限,通过开启一些编译策略来提升构建效率也是一个解决方案,请参考 [提升构建性能](/guides/advanced-features/build-performance.html)。
|
465
|
+
|
466
|
+
如果以上方式无法解决你的问题,可能是项目中某些异常逻辑导致了内存非正常溢出。你可以排查近期的代码变更,定位问题的根因。如果无法定位,请联系我们进行排查。
|
467
|
+
|
468
|
+
---
|
469
|
+
|
470
|
+
### 打包时出现 Can't resolve 'core-js/modules/xxx.js'?
|
471
|
+
|
472
|
+
如果你在打包时出现了类似下面的报错,表示项目中的 [core-js](https://github.com/zloirock/core-js) 无法被正确引用。
|
473
|
+
|
474
|
+
```text
|
475
|
+
Module not found: Can't resolve 'core-js/modules/es.error.cause.js'
|
476
|
+
```
|
477
|
+
|
478
|
+
通常来说,你无须在项目中安装 `core-js`,因为 Modern.js 已经内置了一份 `core-js` v3。
|
479
|
+
|
480
|
+
如果出现 `core-js` 找不到的报错,可能有以下几个原因:
|
481
|
+
|
482
|
+
1. 项目里覆盖了 Babel 配置的 `plugins`,导致内置的 `babelPluginLockCorejsVersion` 无法正确生效。这种情况将 `tools.babel` 更改为函数用法即可:
|
483
|
+
|
484
|
+
```ts
|
485
|
+
// 错误用法,会覆盖 Modern.js 默认的 Babel 插件
|
486
|
+
export default {
|
487
|
+
tools: {
|
488
|
+
babel: {
|
489
|
+
plugins: ['babel-plugin-xxx'],
|
490
|
+
},
|
491
|
+
},
|
492
|
+
};
|
493
|
+
|
494
|
+
// 正确用法,在默认配置中新增一个插件,而非覆盖插件
|
495
|
+
export default {
|
496
|
+
tools: {
|
497
|
+
babel(config) {
|
498
|
+
config.plugins.push('babel-plugin-xxx');
|
499
|
+
},
|
500
|
+
},
|
501
|
+
};
|
502
|
+
```
|
503
|
+
|
504
|
+
2. 项目里某一处代码依赖了 `core-js` v2 版本。这种情况通常需要你找出对应的代码,并升级其中的 `core-js` 到 v3 版本。
|
505
|
+
3. `node_modules` 中的某一个 npm 包引用了 `core-js`,但是没有在 `dependencies` 中声明 `core-js` 依赖。这种情况需要你在对应的 npm 包中声明 `core-js` 依赖,或者在项目根目录下安装一份 `core-js`。
|
506
|
+
|
507
|
+
---
|
508
|
+
|
509
|
+
### 从 lodash 中引用类型后出现编译报错?
|
510
|
+
|
511
|
+
当你的项目中安装了 `@types/lodash` 包时,你可能会从 `lodash` 中引用一些类型,比如引用 `DebouncedFunc` 类型:
|
512
|
+
|
513
|
+
```ts
|
514
|
+
import { debounce, DebouncedFunc } from 'lodash';
|
515
|
+
```
|
516
|
+
|
517
|
+
上述代码会在编译后产生如下报错:
|
518
|
+
|
519
|
+
```bash
|
520
|
+
SyntaxError: /project/src/index.ts: The 'lodash' method `DebouncedFunc` is not a known module.
|
521
|
+
Please report bugs to https://github.com/lodash/babel-plugin-lodash/issues.
|
522
|
+
```
|
523
|
+
|
524
|
+
这个问题的原因是 Modern.js 默认开启了 [babel-plugin-lodash](https://github.com/lodash/babel-plugin-lodash) 插件来优化 lodash 产物体积,但 Babel 无法区别「值」和「类型」,导致编译后的代码出现异常。
|
525
|
+
|
526
|
+
解决方法是使用 TypeScript 的 `import type` 语法,对 `DebouncedFunc` 类型进行显式声明:
|
527
|
+
|
528
|
+
```ts
|
529
|
+
import { debounce } from 'lodash';
|
530
|
+
import type { DebouncedFunc } from 'lodash';
|
531
|
+
```
|
532
|
+
|
533
|
+
:::tip
|
534
|
+
在任意情况下,我们都推荐使用 `import type` 来引用类型,这对于编译器识别类型会有很大帮助。
|
535
|
+
:::
|
536
|
+
|
537
|
+
---
|
538
|
+
|
539
|
+
### Less 文件中的除法不生效?
|
540
|
+
|
541
|
+
Less v4 版本与 v3 版本相比,除法的写法有一些区别:
|
542
|
+
|
543
|
+
```less
|
544
|
+
// Less v3
|
545
|
+
.math {
|
546
|
+
width: 2px / 2; // 1px
|
547
|
+
width: 2px ./ 2; // 1px
|
548
|
+
width: (2px / 2); // 1px
|
549
|
+
}
|
550
|
+
|
551
|
+
// Less v4
|
552
|
+
.math {
|
553
|
+
width: 2px / 2; // 2px / 2
|
554
|
+
width: 2px ./ 2; // 1px
|
555
|
+
width: (2px / 2); // 1px
|
556
|
+
}
|
557
|
+
```
|
558
|
+
|
559
|
+
Modern.js 内置的 Less 版本为 v4,低版本的写法不会生效,请注意区分。
|
560
|
+
|
561
|
+
Less 中除法的写法也可以通过配置项来修改,详见 [Less - Math](https://lesscss.org/usage/#less-options-math)。
|
562
|
+
|
563
|
+
---
|
28
564
|
|
29
|
-
|
30
|
-
- 编译时报错 `You may need additional loader`?
|
31
|
-
- 打开页面后报错,提示 `exports is not defined`?
|
565
|
+
### 修改配置后,报错 ‘TypeError: Cannot delete property 'xxx' of #\<Object\>’
|
32
566
|
|
33
|
-
|
567
|
+
该报错表示在编译过程中对一个只读配置项进行了删除操作。通常情况下,我们不希望编译过程中的任何操作会直接对传入的配置进行修改,但难以限制底层插件(如 postcss-loader 等)的行为,如果出现该报错,请联系 Modern.js 开发者,我们需要对该配置进行单独处理。
|
34
568
|
|
35
|
-
|
569
|
+
同类型报错还有:
|
36
570
|
|
37
|
-
-
|
38
|
-
-
|
39
|
-
- React 组件的热更新无法生效?
|
571
|
+
- 'TypeError: Cannot add property xxx, object is not extensible'
|
572
|
+
- 'TypeError: Cannot assign to read only property 'xxx' of object '#\<Object\>'
|