@modern-js/main-doc 2.58.1 → 2.58.2

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.
@@ -0,0 +1,201 @@
1
+ ---
2
+ sidebar_position: 3
3
+ ---
4
+
5
+ # Esbuild 插件
6
+
7
+ :::warning
8
+ **当前文档中的 esbuild 功能已停止迭代**,我们更推荐使用 Rspack + SWC 的方案,因为 Rspack + SWC 具备更好的构建性能、功能丰富度和产物兼容性。
9
+
10
+ 请参考[「使用 Rspack」](guides/advanced-features/rspack-start)了解更多。
11
+
12
+ :::
13
+
14
+ import Esbuild from '@modern-js/builder-doc/docs/zh/shared/esbuild.md';
15
+
16
+ <Esbuild />
17
+
18
+ ## 快速开始
19
+
20
+ ### 在 Modern.js 框架中使用
21
+
22
+ Modern.js 框架默认集成了 Builder 的 esbuild 插件,因此,你不需要手动安装和注册插件,只需要使用 [tools.esbuild](/configure/app/tools/esbuild.html) 配置项即可:
23
+
24
+ ```js
25
+ export default defineConfig({
26
+ tools: {
27
+ esbuild: {
28
+ loader: {
29
+ target: 'chrome61',
30
+ },
31
+ minimize: {
32
+ target: 'chrome61',
33
+ },
34
+ },
35
+ },
36
+ });
37
+ ```
38
+
39
+ ## 配置
40
+
41
+ 插件默认会开启代码转译和代码压缩的功能,你也可以通过配置来自定义插件的行为。
42
+
43
+ ### loader
44
+
45
+ - **类型:**
46
+
47
+ ```ts
48
+ type LoaderOptions = EsbuildLoaderOptions | false | undefined;
49
+ ```
50
+
51
+ - **默认值:**
52
+
53
+ ```ts
54
+ const defaultOptions = {
55
+ target: 'es2015',
56
+ charset: builderConfig.output.charset,
57
+ };
58
+ ```
59
+
60
+ 这个选项用于启用 JavaScript 和 TypeScript 的转译,启用时将会使用 esbuild-loader 替换 babel-loader 和 ts-loader。
61
+
62
+ 如果你需要修改转译参数,可以查看 [esbuild-loader 文档](https://github.com/privatenumber/esbuild-loader#loader)。
63
+
64
+ #### 设置 JSX 格式
65
+
66
+ 在使用 esbuild 进行代码转译时,esbuild 默认会读取 `tsconfig.json` 中的 `compilerOptions.jsx` 字段,来决定使用哪种 JSX 语法。
67
+
68
+ 因此,你需要在 `tsconfig.json` 中设置正确的 JSX 语法。
69
+
70
+ 比如 React 项目,需要将 `compilerOptions.jsx` 设置为 `react-jsx`:
71
+
72
+ ```json
73
+ {
74
+ "compilerOptions": {
75
+ "jsx": "react-jsx"
76
+ }
77
+ }
78
+ ```
79
+
80
+ #### 修改目标环境
81
+
82
+ 通过 `target` 选项来修改代码转译的目标环境。`target` 可以直接设置为 JavaScript 语言版本,比如 `es6`,`es2020`;也可以设置为若干个目标环境,每个目标环境都是一个环境名称后跟一个版本号,比如 `['chrome58', 'edge16' ,'firefox57']`。`target` 字段的详细介绍可以参考 [esbuild - target](https://esbuild.github.io/api/#target)。
83
+
84
+ target 支持设置为以下环境:
85
+
86
+ - chrome
87
+ - edge
88
+ - firefox
89
+ - ie
90
+ - ios
91
+ - node
92
+ - opera
93
+ - safari
94
+
95
+ ```ts
96
+ builderPluginEsbuild({
97
+ loader: {
98
+ target: 'chrome61',
99
+ },
100
+ });
101
+ ```
102
+
103
+ #### 关闭代码转译
104
+
105
+ 将 `loader` 设置为 `false` 来关闭 esbuild 代码转译,此时 Builder 会继续使用 Babel 来进行代码转译。
106
+
107
+ ```ts
108
+ builderPluginEsbuild({
109
+ loader: false,
110
+ });
111
+ ```
112
+
113
+ ### minimize
114
+
115
+ - **类型:**
116
+
117
+ ```ts
118
+ type MinimizeOptions = EsbuildMinifyOptions | false | undefined;
119
+ ```
120
+
121
+ - **默认值:**
122
+
123
+ ```ts
124
+ const defaultOptions = {
125
+ css: true,
126
+ target: 'es2015',
127
+ format: builderTarget === 'web' ? 'iife' : undefined,
128
+ };
129
+ ```
130
+
131
+ 这个选项用于启用 JavaScript 和 CSS 的代码压缩。
132
+
133
+ 如果你需要修改压缩参数,可以查看 [esbuild-loader 文档](https://github.com/privatenumber/esbuild-loader#minifyplugin)。
134
+
135
+ #### 修改目标环境
136
+
137
+ 通过 `target` 选项来修改代码压缩的目标环境。
138
+
139
+ ```ts
140
+ builderPluginEsbuild({
141
+ minimize: {
142
+ target: 'chrome61',
143
+ },
144
+ });
145
+ ```
146
+
147
+ #### 关闭代码压缩
148
+
149
+ 将 `minimize` 设置为 `false` 来关闭 esbuild 代码压缩,此时 Builder 会继续使用 Terser 进行代码压缩。
150
+
151
+ ```ts
152
+ builderPluginEsbuild({
153
+ minimize: false,
154
+ });
155
+ ```
156
+
157
+ ## esbuild 局限性
158
+
159
+ 虽然 esbuild 能给现有的 webpack 项目带来明显的构建性能提升,但这个工具在接入 Builder 时还存在一定的局限性,需要大家在接入的时候格外注意。
160
+
161
+ ### 兼容性
162
+
163
+ 使用 esbuild 进行代码转译时(即 `loader` 能力),esbuild 通常最低支持到 ES2015(即 ES6)语法,并且不具备自动注入 Polyfill 的能力。如果生产环境需要降级到 ES5 及以下的语法,建议使用 SWC 编译。
164
+
165
+ 你可以通过如下的配置指定目标语法版本:
166
+
167
+ ```ts
168
+ builderPluginEsbuild({
169
+ loader: {
170
+ target: 'es2015',
171
+ },
172
+ });
173
+ ```
174
+
175
+ 使用 esbuild 进行代码压缩时(即 `minimize` 能力),esbuild 可以在生产环境中进行压缩和混淆,通常最低支持到 ES2015 语法。
176
+
177
+ 如果设置压缩的 `target` 为 `es5`,需要保证所有代码已经被转义为 ES5 代码,否则会导致 esbuild 编译报错:`Transforming 'xxx' to the configured target environment ("es5") is not supported yet`。
178
+
179
+ 因此,对于生产环境需要兼容 ES5 及以下语法的项目,请谨慎开启 minimize 能力,建议使用 SWC 压缩。
180
+
181
+ 你可以通过如下的配置指定目标语法版本:
182
+
183
+ ```ts
184
+ builderPluginEsbuild({
185
+ minimize: {
186
+ target: 'es2015',
187
+ },
188
+ });
189
+ ```
190
+
191
+ ### 不支持 Babel 插件
192
+
193
+ 使用 esbuild 进行代码转译时,诸如 `babel-plugin-import` 等原有 Babel 插件的语法编译功能在开启 esbuild 后无法使用。并且由于 Builder 底层使用的是 esbuild 的 `Transform API`,因此不支持使用额外 esbuild 插件来进行自定义编译过程。
194
+
195
+ 如果你有 `babel-plugin-import` 等 Babel 插件相关诉求,可以使用 SWC 插件。
196
+
197
+ ### 产物体积
198
+
199
+ 使用 esbuild 压缩虽然带来了构建效率上的提升,但 esbuild 的压缩比例是低于 terser 的,因此**构建产物的体积会增大**,请根据业务情况酌情使用。通常来说,esbuild 比较适合中后台等对体积不敏感的场景。
200
+
201
+ 对于压缩工具之间的详细对比,可以参考 [minification-benchmarks](https://github.com/privatenumber/minification-benchmarks)。
@@ -0,0 +1,344 @@
1
+ ---
2
+ sidebar_position: 2
3
+ ---
4
+
5
+ # SWC 插件
6
+
7
+ import SWC from '@modern-js/builder-doc/docs/zh/shared/swc.md';
8
+
9
+ <SWC />
10
+
11
+ ## 适用场景
12
+
13
+ 在使用 SWC 插件之前,请先了解一下 SWC 插件的适用场景和局限性,以明确你的项目是否需要使用 SWC 插件。
14
+
15
+ ### Rspack 场景
16
+
17
+ 如果你的项目中已经使用了 Rspack 作为打包工具,那么你不需要接入 SWC 插件,因为 Rspack 默认会使用 SWC 进行转译和压缩,各个 SWC 编译能力可以开箱即用。
18
+
19
+ 如果你使用 Rspack 时配置了当前的 SWC 插件,它将不会产生任何效果。
20
+
21
+ ### Babel 插件
22
+
23
+ 如果你的项目需要注册一些自定义的 Babel 插件,由于 SWC 替代了 Babel 作为转译工具,因此使用 SWC 后,你将无法注册和使用 Babel 插件。
24
+
25
+ 对于大部分常见的 Babel 插件,你可以在 SWC 中找到对应的替代品,比如:
26
+
27
+ - `@babel/preset-env`: 使用 [presetEnv](#presetenv) 代替。
28
+ - `@babel/preset-react`: 使用 [presetReact](#presetreact) 代替。
29
+ - `babel-plugin-import`:使用 [source.transformImport](/configure/app/source/transform-import) 代替。
30
+ - `babel-plugin-lodash`:使用 [extensions.lodash](#extensionslodash) 代替。
31
+ - `@emotion/babel-plugin`:使用 [extensions.emotion](#extensionsemotion) 代替。
32
+ - `babel-plugin-styled-components`:使用 [extensions.styledComponents](#extensionsstyledcomponents) 代替。
33
+ - `@babel/plugin-react-transform-remove-prop-types`: 使用 [reactUtils.removePropTypes](#extensionsreactutils) 代替。
34
+
35
+ 如果你使用了 SWC 尚未支持的 Babel 插件能力,在切换到 SWC 编译后,将无法再使用它们。你可以到 [swc-plugins](https://github.com/web-infra-dev/swc-plugins) 仓库下通过 issues 进行反馈,我们会评估是否需要内置支持。
36
+
37
+ ### 产物体积
38
+
39
+ 在使用 SWC 来代替 [terser](https://github.com/terser/terser) 和 [cssnano](https://github.com/cssnano/cssnano) 进行代码压缩时,构建产物的体积可能会出现少量变化。在 JavaScript 代码压缩方面,SWC 的压缩率是优于 terser 的;在 CSS 代码压缩方面,SWC 的压缩率稍逊于 cssnano。
40
+
41
+ 对于压缩工具之间的详细对比,可以参考 [minification-benchmarks](https://github.com/privatenumber/minification-benchmarks)。
42
+
43
+ ## 快速开始
44
+
45
+ ### 在 Modern.js 框架中使用
46
+
47
+ Modern.js 框架对 Builder 的 SWC 插件进行了封装,你可以通过以下方式来使用:
48
+
49
+ import EnableSWC from '@modern-js/builder-doc/docs/zh/shared/enableSwc.md';
50
+
51
+ <EnableSWC />
52
+
53
+ That's it! 现在你可以在项目中无缝使用 SWC 的转译和压缩能力了。
54
+
55
+ ## 配置
56
+
57
+ - **类型:**
58
+
59
+ ```ts
60
+ type PluginConfig =
61
+ | ObjPluginConfig
62
+ | ((
63
+ config: ObjPluginConfig,
64
+ utils: { mergeConfig: typeof lodash.merge; setConfig: typeof lodash.set },
65
+ ) => ObjPluginConfig | void);
66
+
67
+ // SwcOptions 为 swc 配置项 https://swc.rs/docs/configuration/compilation
68
+ interface ObjPluginConfig extends SwcOptions {
69
+ presetReact?: ReactConfig;
70
+ presetEnv?: EnvConfig;
71
+ jsMinify?: boolean | JsMinifyOptions;
72
+ cssMinify?: boolean | CssMinifyOptions;
73
+ extensions?: Extensions;
74
+ overrides?: Overrides;
75
+ }
76
+ ```
77
+
78
+ 插件配置在 SWC 配置的基础上,为了简化部分深层配置和为提高开发体验,进行了部分拓展,例如当使用对象形式配置时,可以使用 `presetReact` 以及 `presetEnv` 快速配置 react 以及语法降级相关功能,另外不属于插件特有的配置也会直接透传给 swc。
79
+
80
+ 当使用函数形式配置时,则会传入插件内部产出的默认配置,可以对其进行修改或返回新的配置。
81
+
82
+ ### presetReact
83
+
84
+ - **类型:** SWC 中的 [react](https://swc.rs/docs/configuration/compilation#jsctransformreact) 配置。
85
+
86
+ 对标 `@babel/preset-react`。传入的值会与默认配置进行合并。
87
+
88
+ 插件默认会自动根据你的 `react` 版本确定 `runtime` 字段,如果 `react` 版本大于 17.0.0,会设置成 `automatic`,否则设置成 `classic`。
89
+
90
+ ### presetEnv
91
+
92
+ - **类型:** SWC 中的 [presetEnv](https://swc.rs/docs/configuration/supported-browsers#options)。
93
+
94
+ 对标 `@babel/preset-env`。传入的值会与默认配置进行合并。
95
+ 默认配置为:
96
+
97
+ ```ts
98
+ {
99
+ targets: '', // 自动从项目中获取 browserslist
100
+ mode: 'usage',
101
+ }
102
+ ```
103
+
104
+ ### jsMinify
105
+
106
+ - **类型:** `boolean` 或者 [terser 中的 compress 配置](https://terser.org/docs/api-reference.html#compress-options)。
107
+ - **默认值:** `{ compress: {}, mangle: true }`。
108
+
109
+ 如果配置 `false` 将不会使用 SWC 的压缩能力,配置 `true` 会启用默认压缩配置,如果配置是对象,则会与默认配置进行合并。
110
+
111
+ ### cssMinify
112
+
113
+ - **类型:** `boolean`
114
+ - **默认值:** `true`
115
+
116
+ 是否启用 SWC 对 CSS 文件进行压缩,若启用会使得 CSS 压缩性能提高,但压缩率会略微降低。
117
+
118
+ ### overrides
119
+
120
+ - **类型:**
121
+
122
+ ```ts
123
+ interface Overrides extends SwcOptions {
124
+ test: RegExp;
125
+ include: RegExp[];
126
+ exclude: RegExp[];
127
+ }
128
+ ```
129
+
130
+ - **默认值:** `undefined`
131
+
132
+ 对指定文件运用另外的配置。例如需要对 `foo.ts` 的语法降级成 ie 11,则可以如下配置:
133
+
134
+ ```ts
135
+ {
136
+ test: /foo.ts/,
137
+ env: { targets: 'ie 11' }
138
+ }
139
+ ```
140
+
141
+ 该配置会与默认配置进行合并,并且不会影响到其他文件。
142
+
143
+ ### extensions
144
+
145
+ - **类型:** `Object`
146
+
147
+ `extensions` 包含了从 Babel 移植过来的一些插件能力。
148
+
149
+ #### extensions.reactUtils
150
+
151
+ - **类型:**
152
+
153
+ ```ts
154
+ type ReactUtilsOptions = {
155
+ autoImportReact?: boolean;
156
+ removeEffect?: boolean;
157
+ removePropTypes?: {
158
+ mode?: 'remove' | 'unwrap' | 'unsafe-wrap';
159
+ removeImport?: boolean;
160
+ ignoreFilenames?: string[];
161
+ additionalLibraries?: string[];
162
+ classNameMatchers?: string[];
163
+ };
164
+ };
165
+ ```
166
+
167
+ 一些用于 `React` 的工具,包括以下配置项:
168
+
169
+ **reactUtils.autoImportReact**
170
+
171
+ - **类型:** `boolean`
172
+
173
+ 自动引入 `React`, `import React from 'react'`,用于 `jsx` 转换使用 `React.createElement`。
174
+
175
+ **reactUtils.removeEffect**
176
+
177
+ - **类型:** `boolean`
178
+
179
+ 移除 `useEffect` 调用。
180
+
181
+ **reactUtils.removePropTypes**
182
+
183
+ - **类型:**
184
+
185
+ ```ts
186
+ type RemovePropTypesOptions = {
187
+ mode?: 'remove' | 'unwrap' | 'unsafe-wrap';
188
+ removeImport?: boolean;
189
+ ignoreFilenames?: string[];
190
+ additionalLibraries?: string[];
191
+ classNameMatchers?: string[];
192
+ };
193
+ ```
194
+
195
+ 移除 `React` 组件在运行时的类型判断。移植自 [@babel/plugin-react-transform-remove-prop-types](https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types)。
196
+
197
+ 相应配置和 `@babel/plugin-react-transform-remove-prop-types` 插件保持一致。
198
+
199
+ #### extensions.lodash
200
+
201
+ - **类型:**
202
+
203
+ ```ts
204
+ type LodashOptions = {
205
+ cwd?: string;
206
+ ids?: string[];
207
+ };
208
+ ```
209
+
210
+ - **默认值:**
211
+
212
+ ```ts
213
+ const defaultOptions = {
214
+ cwd: process.cwd(),
215
+ ids: ['lodash', 'lodash-es'],
216
+ };
217
+ ```
218
+
219
+ 移植自 [babel-plugin-lodash](https://github.com/lodash/babel-plugin-lodash),用于自动将 Lodash 的引用转换为按需引入,从而减少打包后的 Lodash 代码大小。
220
+
221
+ ```ts
222
+ // Input
223
+ import { get, throttle } from 'lodash';
224
+
225
+ // Output
226
+ import get from 'lodash/get';
227
+ import throttle from 'lodash/throttle';
228
+ ```
229
+
230
+ #### extensions.styledComponents
231
+
232
+ - **类型:**
233
+
234
+ ```ts
235
+ boolean | {
236
+ displayName?: boolean; // 默认开发模式开启, 生产模式关闭,
237
+ ssr?: boolean; // 默认开启
238
+ fileName?: boolean; // 默认开启
239
+ topLevelImportPaths?: string[]; // 默认空
240
+ meaninglessFileNames?: string[]; // 默认为 ["index"].
241
+ cssProp?: boolean; // 默认开启
242
+ namespace?: string; // 默认空
243
+ };
244
+ ```
245
+
246
+ 由 Next.js 团队移植自 [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components)。
247
+
248
+ #### extensions.emotion
249
+
250
+ - **类型:**
251
+
252
+ ```ts
253
+ boolean | {
254
+ sourceMap?: boolean, // 默认开启
255
+ autoLabel?: 'never' | 'dev-only' | 'always', // 默认 'dev-only'
256
+ // 默认 '[local]'.
257
+ // 允许的值为: `[local]` `[filename]` 以及 `[dirname]`
258
+ // 只有当 autoLabel 设置成 'dev-only' 或者 'always' 才会生效.
259
+ // 该配置允许你定义结果标签的格式,该格式的组成是字符串以及可以由方括号包裹字符串作为变量
260
+ // 例如对于 "my-classname--[local]",其中的 [local] 会被替换成相应的变量
261
+ labelFormat?: string,
262
+ // 默认值 undefined.
263
+ // 该配置允许让编译器知道哪一个引入需要进行转换,所以如果你重导出了 emotion
264
+ // 的导出,你仍然可以使用该插件进行转换
265
+ importMap?: {
266
+ [packageName: string]: {
267
+ [exportName: string]: {
268
+ canonicalImport?: [string, string],
269
+ styledBaseImport?: [string, string],
270
+ }
271
+ }
272
+ },
273
+ },
274
+ ```
275
+
276
+ 由 Next.js 团队移植自 [@emotion/babel-plugin](https://www.npmjs.com/package/@emotion/babel-plugin)。
277
+
278
+ #### extensions.pluginImport
279
+
280
+ :::tip
281
+ Builder 提供了 [source.transformImport](/configure/app/source/transform-import) 配置项,因此你不需要手动配置 `extensions.pluginImport`。
282
+ :::
283
+
284
+ 移植自 [babel-plugin-import](https://github.com/umijs/babel-plugin-import),配置选项保持一致。
285
+
286
+ 一些配置可以传入函数,例如 `customName`,`customStyleName` 等,这些 JavaScript 函数会由 Rust 通过 Node-API 调用,这种调用会造成一些性能劣化。
287
+
288
+ 简单的函数逻辑其实可以通过模版语言来代替,因此`customName`,`customStyleName` 等这些配置除了可以传入函数,也可以传入字符串作为模版来代替函数,提高性能。
289
+
290
+ 我们以下面代码为例说明:
291
+
292
+ ```ts
293
+ import { MyButton as Btn } from 'foo';
294
+ ```
295
+
296
+ 添加以下配置:
297
+
298
+ ```ts
299
+ PluginSWC({
300
+ extensions: {
301
+ pluginImport: [
302
+ {
303
+ libraryName: 'foo',
304
+ customName: 'foo/es/{{ member }}',
305
+ },
306
+ ],
307
+ },
308
+ });
309
+ ```
310
+
311
+ 其中的 `{{ member }}` 会被替换为相应的引入成员,转换后:
312
+
313
+ ```ts
314
+ import Btn from 'foo/es/MyButton';
315
+ ```
316
+
317
+ 可以看出配置 `customName: "foo/es/{{ member }}"` 的效果等同于配置 `` customName: (member) => `foo/es/${member}` ``,但是不会有 Node-API 的调用开销。
318
+
319
+ 这里使用到的模版是 [handlebars](https://handlebarsjs.com),模版配置中还内置了一些有用的辅助工具,还是以上面的导入语句为例,配置成:
320
+
321
+ ```ts
322
+ PluginSWC({
323
+ extensions: {
324
+ pluginImport: [
325
+ {
326
+ libraryName: 'foo',
327
+ customName: 'foo/es/{{ kebabCase member }}',
328
+ },
329
+ ],
330
+ },
331
+ });
332
+ ```
333
+
334
+ 会转换成下面的结果:
335
+
336
+ ```ts
337
+ import Btn from 'foo/es/my-button';
338
+ ```
339
+
340
+ 除了 `kebabCase` 以外还有 `camelCase`,`snakeCase`,`upperCase`,`lowerCase` 可以使用。
341
+
342
+ ## 限制
343
+
344
+ 不支持 `@babel/plugin-transform-runtime` 以及其他自定义的 Babel 插件。
package/package.json CHANGED
@@ -15,17 +15,17 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.58.1",
18
+ "version": "2.58.2",
19
19
  "publishConfig": {
20
20
  "registry": "https://registry.npmjs.org/",
21
21
  "access": "public",
22
22
  "provenance": true
23
23
  },
24
24
  "dependencies": {
25
- "@modern-js/sandpack-react": "2.58.1"
25
+ "@modern-js/sandpack-react": "2.58.2"
26
26
  },
27
27
  "peerDependencies": {
28
- "@modern-js/builder-doc": "^2.58.1"
28
+ "@modern-js/builder-doc": "^2.58.2"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@rspress/shared": "1.27.0",
@@ -39,7 +39,7 @@
39
39
  "rspress": "1.27.0",
40
40
  "ts-node": "^10.9.1",
41
41
  "typescript": "^5",
42
- "@modern-js/builder-doc": "2.58.1"
42
+ "@modern-js/builder-doc": "2.58.2"
43
43
  },
44
44
  "scripts": {
45
45
  "dev": "rspress dev",
package/rspress.config.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from 'path';
2
2
  import { defineConfig } from 'rspress/config';
3
- import { NavItem } from '@rspress/shared';
3
+ import type { NavItem } from '@rspress/shared';
4
4
 
5
5
  const { version } = require('./package.json');
6
6
 
@@ -148,5 +148,5 @@ export default defineConfig({
148
148
  '@site': require('path').resolve(__dirname),
149
149
  },
150
150
  },
151
- }
151
+ },
152
152
  });
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
2
  import cl from 'classnames';
3
3
  import { withBase } from 'rspress/runtime';
4
4
  import styles from './index.module.scss';
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
2
  import styles from './index.module.css';
3
3
 
4
4
  export const FeatureLayout: React.FC<{ children: React.ReactNode }> = ({
@@ -103,8 +103,8 @@ export default function Footer() {
103
103
  },
104
104
  ];
105
105
 
106
- const Links = links.map((linkItem, i) => (
107
- <div className={styles.linkWrapper} key={i}>
106
+ const Links = links.map(linkItem => (
107
+ <div className={styles.linkWrapper} key={linkItem.title}>
108
108
  <div className={styles.linkTitle}>{linkItem.title}</div>
109
109
  <ul className={styles.items}>
110
110
  {linkItem.items.map((item, key) => (
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
2
  import { withBase } from 'rspress/runtime';
3
3
  import styles from './index.module.css';
4
4
 
@@ -1,5 +1,7 @@
1
- import ModernSandpack, { ModernSandpackProps } from '@modern-js/sandpack-react';
2
- import React, { PropsWithChildren } from 'react';
1
+ import ModernSandpack, {
2
+ type ModernSandpackProps,
3
+ } from '@modern-js/sandpack-react';
4
+ import React, { type PropsWithChildren } from 'react';
3
5
  import { useDark, NoSSR } from 'rspress/runtime';
4
6
 
5
7
  import './index.css';
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
2
  import styles from './index.module.css';
3
3
 
4
4
  interface ITitleProps {
package/src/i18n/zhCN.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { EN_US } from './enUS';
1
+ import type { EN_US } from './enUS';
2
2
 
3
3
  export const ZH_CN: Record<keyof typeof EN_US, string> = {
4
4
  introduction: '介绍',
package/src/index.ts CHANGED
@@ -6,5 +6,4 @@ export default {
6
6
  HomeLayout,
7
7
  };
8
8
 
9
- // eslint-disable-next-line import/export
10
9
  export * from 'rspress/theme';