@modern-js/main-doc 3.9.1 → 3.9.3

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.
@@ -7,6 +7,10 @@ title: disableSvgr
7
7
  - **Type:** `boolean`
8
8
  - **Default:** `false`
9
9
 
10
+ :::warning Deprecated
11
+ `output.disableSvgr` is deprecated and will be removed in the next major version. Replace `output.disableSvgr: true` with [tools.svgr](/configure/app/tools/svgr) set to `false`; `output.disableSvgr: false` is the default behavior and can simply be removed. When both are set, `tools.svgr` wins.
12
+ :::
13
+
10
14
  Whether to transform SVGs into React components. If true, will treat all .svg files as assets.
11
15
 
12
16
  By default, when an SVG resource is referenced in a JS file, Modern.js will call SVGR to convert the SVG into a React component. If you are sure that all SVG resources in your project are not being used as React components, you can turn off this conversion by setting `disableSvgr` to true to improve build performance.
@@ -7,6 +7,10 @@ title: svgDefaultExport
7
7
  - **Type:** `'url' | 'component'`
8
8
  - **Default:** `'url'`
9
9
 
10
+ :::warning Deprecated
11
+ `output.svgDefaultExport` is deprecated and will be removed in the next major version. Use `svgrOptions.exportType` of [tools.svgr](/configure/app/tools/svgr) instead: `'component'` maps to `exportType: 'default'`, `'url'` maps to `exportType: 'named'`. When both are set, `tools.svgr` wins.
12
+ :::
13
+
10
14
  `output.svgDefaultExport` is used to configure the default export type of SVG files.
11
15
 
12
16
  When `output.svgDefaultExport` is set to `url` , the default export of SVG files is the URL of the file. For example:
@@ -9,49 +9,78 @@ title: less
9
9
 
10
10
  ```js
11
11
  const defaultOptions = {
12
- lessOptions: {
13
- javascriptEnabled: true,
12
+ lessLoaderOptions: {
13
+ lessOptions: {
14
+ javascriptEnabled: true,
15
+ },
16
+ // CSS Source Map enabled by default in development environment
17
+ sourceMap: isDev,
14
18
  },
15
- // CSS Source Map enabled by default in development environment
16
- sourceMap: isDev,
17
19
  };
18
20
  ```
19
21
 
20
- You can modify the config of [less-loader](https://github.com/webpack-contrib/less-loader) via `tools.less`.
22
+ `tools.less` modifies the options of [@rsbuild/plugin-less](https://rsbuild.rs/plugins/list/plugin-less). It accepts the full plugin options:
23
+
24
+ | Option | Description |
25
+ | ------------------- | ---------------------------------------------------------------------------------------------- |
26
+ | `lessLoaderOptions` | Options passed to [less-loader](https://github.com/webpack-contrib/less-loader), object or function |
27
+ | `include` | Files handled by less-loader, defaults to `/\.less$/` |
28
+ | `exclude` | Files that less-loader should skip |
29
+ | `parallel` | Whether to compile Less modules in worker threads, defaults to `false` |
30
+
31
+ ### Modifying less-loader options
32
+
33
+ When `lessLoaderOptions` is an `Object`, it is merged with the default config through Object.assign in a shallow way. It should be noted that `lessOptions` is merged through deepMerge in a deep way. For example:
21
34
 
22
- ### Object Type
35
+ ```js
36
+ export default {
37
+ tools: {
38
+ less: {
39
+ lessLoaderOptions: {
40
+ lessOptions: {
41
+ javascriptEnabled: false,
42
+ },
43
+ },
44
+ },
45
+ },
46
+ };
47
+ ```
23
48
 
24
- When `tools.less` is configured as `Object` type, it is merged with the default config through Object.assign in a shallow way. It should be noted that `lessOptions` is merged through deepMerge in a deep way. For example:
49
+ When `lessLoaderOptions` is a `Function`, the default config is passed as the first parameter, which can be directly modified or returned as the final result. The second parameter provides some utility functions that can be called directly. For example:
25
50
 
26
51
  ```js
27
52
  export default {
28
53
  tools: {
29
54
  less: {
30
- lessOptions: {
31
- javascriptEnabled: false,
55
+ lessLoaderOptions(config) {
56
+ // Modify the config of lessOptions
57
+ config.lessOptions = {
58
+ javascriptEnabled: false,
59
+ };
32
60
  },
33
61
  },
34
62
  },
35
63
  };
36
64
  ```
37
65
 
38
- ### Function Type
66
+ ### Parallel compilation
39
67
 
40
- When `tools.less` is a Function, the default config is passed as the first parameter, which can be directly modified or returned as the final result. The second parameter provides some utility functions that can be called directly. For example:
68
+ Less compilation is pure JavaScript and runs on the Node.js main thread by default. With `parallel` enabled, Less modules are compiled in a pool of worker threads, which shortens the build when a project has many Less files.
41
69
 
42
70
  ```js
43
71
  export default {
44
72
  tools: {
45
- less(config) {
46
- // Modify the config of lessOptions
47
- config.lessOptions = {
48
- javascriptEnabled: false,
49
- };
73
+ less: {
74
+ parallel: true,
50
75
  },
51
76
  },
52
77
  };
53
78
  ```
54
79
 
80
+ :::tip
81
+ Options sent to worker threads must satisfy the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). With `parallel` enabled, `lessLoaderOptions` therefore cannot contain functions, such as an `additionalData` function or a custom `implementation`.
82
+ :::
83
+
55
84
  ### Modifying Less Version
56
85
 
57
86
  In some scenarios, if you need to use a specific version of Less instead of the built-in Less v4 in Modern.js, you can install the desired Less version in your project and set it up using the `implementation` option of the `less-loader`.
@@ -60,7 +89,9 @@ In some scenarios, if you need to use a specific version of Less instead of the
60
89
  export default {
61
90
  tools: {
62
91
  less: {
63
- implementation: require('less'),
92
+ lessLoaderOptions: {
93
+ implementation: require('less'),
94
+ },
64
95
  },
65
96
  },
66
97
  };
@@ -77,8 +108,53 @@ Used to specify which files `less-loader` does not compile, You can pass in one
77
108
  ```js
78
109
  export default {
79
110
  tools: {
80
- less(config, { addExcludes }) {
81
- addExcludes(/node_modules/);
111
+ less: {
112
+ lessLoaderOptions(config, { addExcludes }) {
113
+ addExcludes(/node_modules/);
114
+ },
115
+ },
116
+ },
117
+ };
118
+ ```
119
+
120
+ The plugin's `exclude` option is the recommended equivalent:
121
+
122
+ ```js
123
+ export default {
124
+ tools: {
125
+ less: {
126
+ exclude: /node_modules/,
127
+ },
128
+ },
129
+ };
130
+ ```
131
+
132
+ ### Legacy form
133
+
134
+ :::warning Do not mix the two layers
135
+ As soon as an object contains a plugin-level key (`lessLoaderOptions`, `include`, `exclude`, ...), the whole object is parsed as plugin options and any loader option in it has no effect. For example, `lessOptions` in `tools.less: { parallel: true, lessOptions: { ... } }` is ignored and must be moved under `lessLoaderOptions`; a hint is printed in development.
136
+ :::
137
+
138
+
139
+ In earlier versions, `tools.less` took the less-loader options directly, e.g. `tools.less: { lessOptions: {} }` or `tools.less(config, { addExcludes }) {}`. This form still works: Modern.js wraps it into `lessLoaderOptions` and produces exactly the same config as before. A migration hint is printed in development, and the legacy form will be removed in the next major version.
140
+
141
+ ```js
142
+ // legacy
143
+ export default {
144
+ tools: {
145
+ less: {
146
+ lessOptions: { javascriptEnabled: false },
147
+ },
148
+ },
149
+ };
150
+
151
+ // current
152
+ export default {
153
+ tools: {
154
+ less: {
155
+ lessLoaderOptions: {
156
+ lessOptions: { javascriptEnabled: false },
157
+ },
82
158
  },
83
159
  },
84
160
  };
@@ -9,41 +9,64 @@ title: sass
9
9
 
10
10
  ```js
11
11
  const defaultOptions = {
12
- // CSS Source Map enabled by default in development environment
13
- sourceMap: isDev,
12
+ sassLoaderOptions: {
13
+ // CSS Source Map enabled by default in development environment
14
+ sourceMap: isDev,
15
+ },
14
16
  };
15
17
  ```
16
18
 
17
- You can modify the config of [sass-loader](https://github.com/webpack-contrib/sass-loader) via `tools.sass`.
19
+ `tools.sass` modifies the options of [@rsbuild/plugin-sass](https://rsbuild.rs/plugins/list/plugin-sass). It accepts the full plugin options:
18
20
 
19
- ### Object Type
21
+ | Option | Description |
22
+ | ------------------- | ---------------------------------------------------------------------------------------------- |
23
+ | `sassLoaderOptions` | Options passed to [sass-loader](https://github.com/webpack-contrib/sass-loader), object or function |
24
+ | `include` | Files handled by sass-loader, defaults to `/\.s(?:a|c)ss$/` |
25
+ | `exclude` | Files that sass-loader should skip |
26
+ | `rewriteUrls` | Whether to rewrite relative URLs in Sass files with resolve-url-loader, defaults to `true` |
20
27
 
21
- When `tools.sass` is `Object` type, it is merged with the default config through Object.assign. It should be noted that `sassOptions` is merged through deepMerge in a deep way.
28
+ ### Modifying sass-loader options
22
29
 
23
- For example:
30
+ When `sassLoaderOptions` is an `Object`, it is merged with the default config through Object.assign in a shallow way. It should be noted that `sassOptions` is merged through deepMerge in a deep way. For example:
24
31
 
25
32
  ```js
26
33
  export default {
27
34
  tools: {
28
35
  sass: {
29
- sourceMap: true,
36
+ sassLoaderOptions: {
37
+ sourceMap: true,
38
+ },
39
+ },
40
+ },
41
+ };
42
+ ```
43
+
44
+ When `sassLoaderOptions` is a `Function`, the default config is passed as the first parameter, which can be directly modified or returned as the final result. The second parameter provides some utility functions that can be called directly. For example:
45
+
46
+ ```js
47
+ export default {
48
+ tools: {
49
+ sass: {
50
+ sassLoaderOptions(config) {
51
+ // Modify the additionalData config
52
+ config.additionalData = async (content, loaderContext) => {
53
+ // ...
54
+ };
55
+ },
30
56
  },
31
57
  },
32
58
  };
33
59
  ```
34
60
 
35
- ### Function Type
61
+ ### Disabling URL rewriting
36
62
 
37
- When `tools.sass` is a Function, the default config is passed as the first parameter, which can be directly modified or returned as the final result. The second parameter provides some utility functions that can be called directly. For Example:
63
+ By default, relative URLs in Sass files are rewritten by resolve-url-loader so that they resolve relative to the source file. If your project does not rely on this, turn it off to drop one loader from the chain:
38
64
 
39
65
  ```js
40
66
  export default {
41
67
  tools: {
42
- sass(config) {
43
- // Modify sourceMap config
44
- config.additionalData = async (content, loaderContext) => {
45
- // ...
46
- };
68
+ sass: {
69
+ rewriteUrls: false,
47
70
  },
48
71
  },
49
72
  };
@@ -57,13 +80,15 @@ In some scenarios, if you need to use a specific version of Sass instead of the
57
80
  export default {
58
81
  tools: {
59
82
  sass: {
60
- implementation: require('sass'),
83
+ sassLoaderOptions: {
84
+ implementation: require('sass'),
85
+ },
61
86
  },
62
87
  },
63
88
  };
64
89
  ```
65
90
 
66
- ### Utility Function
91
+ ### Util Function
67
92
 
68
93
  #### addExcludes
69
94
 
@@ -74,8 +99,53 @@ Used to specify which files `sass-loader` does not compile, You can pass in one
74
99
  ```js
75
100
  export default {
76
101
  tools: {
77
- sass(config, { addExcludes }) {
78
- addExcludes(/node_modules/);
102
+ sass: {
103
+ sassLoaderOptions(config, { addExcludes }) {
104
+ addExcludes(/node_modules/);
105
+ },
106
+ },
107
+ },
108
+ };
109
+ ```
110
+
111
+ The plugin's `exclude` option is the recommended equivalent:
112
+
113
+ ```js
114
+ export default {
115
+ tools: {
116
+ sass: {
117
+ exclude: /node_modules/,
118
+ },
119
+ },
120
+ };
121
+ ```
122
+
123
+ ### Legacy form
124
+
125
+ :::warning Do not mix the two layers
126
+ As soon as an object contains a plugin-level key (`sassLoaderOptions`, `include`, `exclude`, ...), the whole object is parsed as plugin options and any loader option in it has no effect. For example, `sassOptions` in `tools.sass: { rewriteUrls: false, sassOptions: { ... } }` is ignored and must be moved under `sassLoaderOptions`; a hint is printed in development.
127
+ :::
128
+
129
+
130
+ In earlier versions, `tools.sass` took the sass-loader options directly, e.g. `tools.sass: { sassOptions: {} }` or `tools.sass(config, { addExcludes }) {}`. This form still works: Modern.js wraps it into `sassLoaderOptions` and produces exactly the same config as before. A migration hint is printed in development, and the legacy form will be removed in the next major version.
131
+
132
+ ```js
133
+ // legacy
134
+ export default {
135
+ tools: {
136
+ sass: {
137
+ sourceMap: true,
138
+ },
139
+ },
140
+ };
141
+
142
+ // current
143
+ export default {
144
+ tools: {
145
+ sass: {
146
+ sassLoaderOptions: {
147
+ sourceMap: true,
148
+ },
79
149
  },
80
150
  },
81
151
  };
@@ -0,0 +1,93 @@
1
+ ---
2
+ title: svgr
3
+ ---
4
+
5
+ # tools.svgr
6
+
7
+ - **Type:** `Object | Function | false`
8
+ - **Default:**
9
+
10
+ ```js
11
+ const defaultOptions = {
12
+ mixedImport: true,
13
+ svgrOptions: {
14
+ exportType: 'named',
15
+ },
16
+ };
17
+ ```
18
+
19
+ `tools.svgr` modifies the options of [@rsbuild/plugin-svgr](https://rsbuild.rs/plugins/list/plugin-svgr). It accepts the full plugin options. Set it to `false` to skip registering the SVGR plugin; all `.svg` files are then treated as static assets.
20
+
21
+ | Option | Description |
22
+ | ----------------- | ---------------------------------------------------------------------------------------------------- |
23
+ | `svgrOptions` | Options passed to [SVGR](https://react-svgr.com/docs/options/), such as `exportType`, `icon`, `svgoConfig` |
24
+ | `parallel` | Whether to transform SVG files in worker threads, defaults to `false` |
25
+ | `exclude` | SVG files that SVGR should skip |
26
+ | `excludeImporter` | Importer files whose SVG imports should skip SVGR |
27
+ | `query` | Query that triggers the SVGR transform, defaults to `/react/` |
28
+ | `mixedImport` | Whether a module may import both the URL and the React component, defaults to `true` |
29
+
30
+ ### Merge rules
31
+
32
+ When `tools.svgr` is an `Object`, its top-level fields are merged with the defaults through Object.assign in a shallow way, and `svgrOptions` is merged one level deeper, so setting only `svgrOptions.icon` keeps the default `exportType`.
33
+
34
+ When `tools.svgr` is a `Function`, the default config is passed as the first parameter, which can be directly modified or returned as the final result. An array of objects and functions is also accepted and applied in order.
35
+
36
+ ### Parallel transform
37
+
38
+ The SVGR transform is pure JavaScript and runs on the Node.js main thread by default. With many SVG files, enable `parallel` to move the transform into a pool of worker threads:
39
+
40
+ ```js
41
+ export default {
42
+ tools: {
43
+ svgr: {
44
+ parallel: true,
45
+ },
46
+ },
47
+ };
48
+ ```
49
+
50
+ :::tip
51
+ Options sent to worker threads must satisfy the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). With `parallel` enabled, `svgrOptions` therefore cannot contain functions.
52
+ :::
53
+
54
+ ### Changing the default export
55
+
56
+ `svgrOptions.exportType` controls what an SVG file exports by default: `'named'` exports the file URL by default and the React component as the named export `ReactComponent`; `'default'` exports the React component by default.
57
+
58
+ ```js
59
+ export default {
60
+ tools: {
61
+ svgr: {
62
+ svgrOptions: {
63
+ exportType: 'default',
64
+ },
65
+ },
66
+ },
67
+ };
68
+ ```
69
+
70
+ ### Disabling SVGR
71
+
72
+ If you are sure that no SVG asset in your project is used as a React component, disable SVGR to improve build performance:
73
+
74
+ ```js
75
+ export default {
76
+ tools: {
77
+ svgr: false,
78
+ },
79
+ };
80
+ ```
81
+
82
+ ### Relation to the legacy options
83
+
84
+ `tools.svgr` replaces the two deprecated options below. They still work today and will be removed in the next major version:
85
+
86
+ | Legacy option | Replacement |
87
+ | -------------------------------------- | -------------------------------------------------------- |
88
+ | `output.svgDefaultExport: 'component'` | `tools.svgr: { svgrOptions: { exportType: 'default' } }` |
89
+ | `output.svgDefaultExport: 'url'` | `tools.svgr: { svgrOptions: { exportType: 'named' } }` |
90
+ | `output.disableSvgr: true` | `tools.svgr: false` |
91
+ | `output.disableSvgr: false` | Default behavior, just remove it |
92
+
93
+ When both are set, `tools.svgr` wins: once `tools.svgr` is set explicitly, `output.disableSvgr` no longer applies, and `tools.svgr.svgrOptions.exportType` overrides the value derived from `output.svgDefaultExport`.
@@ -42,16 +42,22 @@ export default () => <Logo />;
42
42
 
43
43
  ## Modify the Default Export
44
44
 
45
- You can modify the default export of SVG files through the [output.svgDefaultExport](/configure/app/output/svg-default-export) config. For example, set the default export as a React component:
45
+ You can modify the default export of SVG files through `svgrOptions.exportType` of [tools.svgr](/configure/app/tools/svgr). For example, set the default export as a React component:
46
46
 
47
47
  ```ts
48
48
  export default {
49
- output: {
50
- svgDefaultExport: 'component',
49
+ tools: {
50
+ svgr: {
51
+ svgrOptions: {
52
+ exportType: 'default',
53
+ },
54
+ },
51
55
  },
52
56
  };
53
57
  ```
54
58
 
59
+ The legacy [output.svgDefaultExport](/configure/app/output/svg-default-export) config still works but is deprecated.
60
+
55
61
  Then import the SVG, you'll get a React component instead of a URL:
56
62
 
57
63
  ```tsx title="src/component/Logo.tsx"
@@ -78,12 +84,12 @@ Please read the [Import Static Assets](/guides/basic-features/static-assets) sec
78
84
 
79
85
  ## Disable SVGR Processing
80
86
 
81
- By default, when an SVG resource is referenced in a JS file, Modern.js will call SVGR to convert the SVG into a React component. If you are sure that all SVG resources in your project are not being used as React components, you can turn off this conversion by setting [disableSvgr](/configure/app/output/disable-svgr) to true to improve build performance.
87
+ By default, when an SVG resource is referenced in a JS file, Modern.js will call SVGR to convert the SVG into a React component. If you are sure that all SVG resources in your project are not being used as React components, you can turn off this conversion by setting [tools.svgr](/configure/app/tools/svgr) to `false` to improve build performance.
82
88
 
83
89
  ```js
84
90
  export default {
85
- output: {
86
- disableSvgr: true,
91
+ tools: {
92
+ svgr: false,
87
93
  },
88
94
  };
89
95
  ```
@@ -151,21 +157,27 @@ When SVGR is enabled, its default configuration is as follows:
151
157
  }
152
158
  ```
153
159
 
154
- If you need to modify the SVGR configuration, you can do the following:
160
+ To modify the SVGR configuration, use `svgrOptions` of [tools.svgr](/configure/app/tools/svgr). The `svgoConfig.plugins` you pass are deep merged with the defaults by plugin name, so only the changed part needs to be written:
155
161
 
156
162
  ```js
157
163
  export default {
158
164
  tools: {
159
- bundlerChain: (chain, { CHAIN_ID }) => {
160
- chain.module
161
- .rule(CHAIN_ID.RULE.SVG)
162
- .oneOf(CHAIN_ID.ONE_OF.SVG)
163
- .use(CHAIN_ID.USE.SVGR)
164
- .tap(options => {
165
- // modify svgoConfig
166
- options.svgoConfig.plugins[0].params.overrides.removeUselessDefs = false;
167
- return options;
168
- });
165
+ svgr: {
166
+ svgrOptions: {
167
+ svgoConfig: {
168
+ plugins: [
169
+ {
170
+ name: 'preset-default',
171
+ params: {
172
+ overrides: {
173
+ // add one more override on top of the default preset-default
174
+ removeUselessDefs: false,
175
+ },
176
+ },
177
+ },
178
+ ],
179
+ },
180
+ },
169
181
  },
170
182
  },
171
183
  };
@@ -129,7 +129,7 @@ The following are official Rsbuild plugins that are already built into Modern.js
129
129
  | Plugin | Description | Modern.js Link |
130
130
  | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
131
131
  | [React Plugin](https://v2.rsbuild.rs/plugins/list/plugin-react) | Provides support for React | - |
132
- | [SVGR Plugin](https://v2.rsbuild.rs/plugins/list/plugin-svgr) | Supports converting SVG images into React components | [output.disableSvgr](/configure/app/output/disable-svgr)<br />[output.svgDefaultExport](/configure/app/output/svg-default-export) |
132
+ | [SVGR Plugin](https://v2.rsbuild.rs/plugins/list/plugin-svgr) | Supports converting SVG images into React components | [tools.svgr](/configure/app/tools/svgr) |
133
133
  | [Assets Retry Plugin](https://github.com/rstackjs/rsbuild-plugin-assets-retry) | Automatically retries requests when static asset loading fails | [output.assetsRetry](/configure/app/output/assets-retry.html) |
134
134
  | [Type Check Plugin](https://github.com/rstackjs/rsbuild-plugin-type-check) | Runs TypeScript type checking in a separate process | [output.disableTsChecker](/configure/app/output/disable-ts-checker.html)<br />[tools.tsChecker](/configure/app/tools/ts-checker.html) |
135
135
  | [Source Build Plugin](https://github.com/rstackjs/rsbuild-plugin-source-build) | For monorepo scenarios, supports referencing source code from other subdirectories and completing builds and hot updates | [experiments.sourceBuild](/configure/app/experiments/source-build.html) |
@@ -7,6 +7,10 @@ title: disableSvgr
7
7
  - **类型:** `boolean`
8
8
  - **默认值:** `false`
9
9
 
10
+ :::warning 已废弃
11
+ `output.disableSvgr` 已废弃,并将在下一个大版本中移除。`output.disableSvgr: true` 请改为 [tools.svgr](/configure/app/tools/svgr) 设置为 `false`;`output.disableSvgr: false` 是默认行为,直接删除即可。两者同时设置时,以 `tools.svgr` 为准。
12
+ :::
13
+
10
14
  是否调用 SVGR 将 SVG 转化为 React 组件。如果设置为 true,将把所有的.svg 文件视为资源处理。
11
15
 
12
16
  默认情况下,在 JS 文件中引用 SVG 资源时,Modern.js 会调用 SVGR,将 SVG 图片转换为一个 React 组件。
@@ -7,6 +7,10 @@ title: svgDefaultExport
7
7
  - **类型:** `'url' | 'component'`
8
8
  - **默认值:** `'url'`
9
9
 
10
+ :::warning 已废弃
11
+ `output.svgDefaultExport` 已废弃,并将在下一个大版本中移除,请改用 [tools.svgr](/configure/app/tools/svgr) 的 `svgrOptions.exportType`:`'component'` 对应 `exportType: 'default'`,`'url'` 对应 `exportType: 'named'`。两者同时设置时,以 `tools.svgr` 为准。
12
+ :::
13
+
10
14
  `output.svgDefaultExport` 可以用来配置 SVG 文件的默认导出。
11
15
 
12
16
  当 `output.svgDefaultExport` 配置为 `url` 时,SVG 文件的默认导出是文件的 URL。例如:
@@ -9,49 +9,78 @@ title: less
9
9
 
10
10
  ```js
11
11
  const defaultOptions = {
12
- lessOptions: {
13
- javascriptEnabled: true,
12
+ lessLoaderOptions: {
13
+ lessOptions: {
14
+ javascriptEnabled: true,
15
+ },
16
+ // 默认在开发环境下启用 CSS 的 Source Map
17
+ sourceMap: isDev,
14
18
  },
15
- // 默认在开发环境下启用 CSS 的 Source Map
16
- sourceMap: isDev,
17
19
  };
18
20
  ```
19
21
 
20
- 你可以通过 `tools.less` 修改 [less-loader](https://github.com/webpack-contrib/less-loader) 的配置。
22
+ `tools.less` 用于修改 [@rsbuild/plugin-less](https://rsbuild.rs/plugins/list/plugin-less) 的选项,取值为该插件的完整选项:
23
+
24
+ | 选项 | 说明 |
25
+ | -------------------- | ---------------------------------------------------------------------------------- |
26
+ | `lessLoaderOptions` | 传给 [less-loader](https://github.com/webpack-contrib/less-loader) 的选项,支持对象或函数 |
27
+ | `include` | 指定哪些文件交给 less-loader 处理,默认 `/\.less$/` |
28
+ | `exclude` | 指定哪些文件不交给 less-loader 处理 |
29
+ | `parallel` | 是否使用 worker 线程并行编译 Less,默认 `false` |
30
+
31
+ ### 修改 less-loader 选项
21
32
 
22
- ### Object 类型
33
+ `lessLoaderOptions` 为 `Object` 类型时,会与默认配置通过 Object.assign 进行浅层合并,值得注意的是,`lessOptions` 会通过 deepMerge 进行深层合并。
34
+
35
+ ```js
36
+ export default {
37
+ tools: {
38
+ less: {
39
+ lessLoaderOptions: {
40
+ lessOptions: {
41
+ javascriptEnabled: false,
42
+ },
43
+ },
44
+ },
45
+ },
46
+ };
47
+ ```
23
48
 
24
- 当 `tools.less` 的值为 `Object` 类型时,会与默认配置通过 Object.assign 进行浅层合并,值得注意的是,`lessOptions` 会通过 deepMerge 进行深层合并。
49
+ `lessLoaderOptions` 为 `Function` 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果,第二个参数提供了一些可以直接调用的工具函数:
25
50
 
26
51
  ```js
27
52
  export default {
28
53
  tools: {
29
54
  less: {
30
- lessOptions: {
31
- javascriptEnabled: false,
55
+ lessLoaderOptions(config) {
56
+ // 修改 lessOptions 配置
57
+ config.lessOptions = {
58
+ javascriptEnabled: false,
59
+ };
32
60
  },
33
61
  },
34
62
  },
35
63
  };
36
64
  ```
37
65
 
38
- ### Function 类型
66
+ ### 并行编译
39
67
 
40
- 当 `tools.less` 为 Function 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果,第二个参数提供了一些可以直接调用的工具函数:
68
+ Less 编译是纯 JavaScript 计算,默认只占用 Node.js 主线程。开启 `parallel` 后,Less 模块会分发到 worker 线程池中编译,项目里 Less 文件较多时可以缩短构建时间。
41
69
 
42
70
  ```js
43
71
  export default {
44
72
  tools: {
45
- less(config) {
46
- // 修改 lessOptions 配置
47
- config.lessOptions = {
48
- javascriptEnabled: false,
49
- };
73
+ less: {
74
+ parallel: true,
50
75
  },
51
76
  },
52
77
  };
53
78
  ```
54
79
 
80
+ :::tip
81
+ 传给 worker 线程的选项需要满足[结构化克隆算法](https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)的要求,因此开启 `parallel` 后,`lessLoaderOptions` 中不能包含函数,例如 `additionalData` 函数或自定义的 `implementation`。
82
+ :::
83
+
55
84
  ### 修改 Less 版本
56
85
 
57
86
  在某些场景下,如果你需要使用特定的 Less 版本,而不是使用 Modern.js 内置的 Less v4,可以在项目中安装需要使用的 Less 版本,并通过 `less-loader` 的 `implementation` 选项设置。
@@ -60,7 +89,9 @@ export default {
60
89
  export default {
61
90
  tools: {
62
91
  less: {
63
- implementation: require('less'),
92
+ lessLoaderOptions: {
93
+ implementation: require('less'),
94
+ },
64
95
  },
65
96
  },
66
97
  };
@@ -77,10 +108,54 @@ export default {
77
108
  ```js
78
109
  export default {
79
110
  tools: {
80
- less(config, { addExcludes }) {
81
- addExcludes(/node_modules/);
111
+ less: {
112
+ lessLoaderOptions(config, { addExcludes }) {
113
+ addExcludes(/node_modules/);
114
+ },
115
+ },
116
+ },
117
+ };
118
+ ```
119
+
120
+ 推荐直接使用插件的 `exclude` 选项,效果相同:
121
+
122
+ ```js
123
+ export default {
124
+ tools: {
125
+ less: {
126
+ exclude: /node_modules/,
82
127
  },
83
128
  },
84
129
  };
85
130
  ```
86
131
 
132
+ ### 兼容旧写法
133
+
134
+ :::warning 不要混写两种层级
135
+ 同一个对象里只要出现插件顶层键(`lessLoaderOptions`、`include`、`exclude` 等),整个对象就会按插件选项解析,其中的 loader 选项不会生效。例如 `tools.less: { parallel: true, lessOptions: { ... } }` 里的 `lessOptions` 会被忽略,必须移到 `lessLoaderOptions` 下;开发环境下会打印一条提示。
136
+ :::
137
+
138
+
139
+ 在之前的版本中,`tools.less` 的取值直接是 less-loader 的选项,例如 `tools.less: { lessOptions: {} }` 或 `tools.less(config, { addExcludes }) {}`。这种写法目前仍然生效,Modern.js 会自动把它包装为 `lessLoaderOptions`,产出的配置与之前完全一致;在开发环境下会打印一条迁移提示,并将在下一个大版本中移除。
140
+
141
+ ```js
142
+ // 旧写法
143
+ export default {
144
+ tools: {
145
+ less: {
146
+ lessOptions: { javascriptEnabled: false },
147
+ },
148
+ },
149
+ };
150
+
151
+ // 新写法
152
+ export default {
153
+ tools: {
154
+ less: {
155
+ lessLoaderOptions: {
156
+ lessOptions: { javascriptEnabled: false },
157
+ },
158
+ },
159
+ },
160
+ };
161
+ ```
@@ -9,39 +9,64 @@ title: sass
9
9
 
10
10
  ```js
11
11
  const defaultOptions = {
12
- // 默认在开发环境下启用 CSS 的 Source Map
13
- sourceMap: isDev,
12
+ sassLoaderOptions: {
13
+ // 默认在开发环境下启用 CSS 的 Source Map
14
+ sourceMap: isDev,
15
+ },
14
16
  };
15
17
  ```
16
18
 
17
- 你可以通过 `tools.sass` 修改 [sass-loader](https://github.com/webpack-contrib/sass-loader) 的配置。
19
+ `tools.sass` 用于修改 [@rsbuild/plugin-sass](https://rsbuild.rs/plugins/list/plugin-sass) 的选项,取值为该插件的完整选项:
20
+
21
+ | 选项 | 说明 |
22
+ | -------------------- | ---------------------------------------------------------------------------------- |
23
+ | `sassLoaderOptions` | 传给 [sass-loader](https://github.com/webpack-contrib/sass-loader) 的选项,支持对象或函数 |
24
+ | `include` | 指定哪些文件交给 sass-loader 处理,默认 `/\.s(?:a|c)ss$/` |
25
+ | `exclude` | 指定哪些文件不交给 sass-loader 处理 |
26
+ | `rewriteUrls` | 是否使用 resolve-url-loader 重写 Sass 文件中的相对 URL,默认 `true` |
18
27
 
19
- ### Object 类型
28
+ ### 修改 sass-loader 选项
20
29
 
21
- 当 `tools.sass` 的值为 `Object` 类型时,会与默认配置通过 Object.assign 进行浅层合并,值得注意的是,`sassOptions` 会通过 deepMerge 进行深层合并。
30
+ `sassLoaderOptions` 为 `Object` 类型时,会与默认配置通过 Object.assign 进行浅层合并,值得注意的是,`sassOptions` 会通过 deepMerge 进行深层合并。
22
31
 
23
32
  ```js
24
33
  export default {
25
34
  tools: {
26
35
  sass: {
27
- sourceMap: true,
36
+ sassLoaderOptions: {
37
+ sourceMap: true,
38
+ },
28
39
  },
29
40
  },
30
41
  };
31
42
  ```
32
43
 
33
- ### Function 类型
44
+ `sassLoaderOptions` 为 `Function` 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果,第二个参数提供了一些可以直接调用的工具函数:
45
+
46
+ ```js
47
+ export default {
48
+ tools: {
49
+ sass: {
50
+ sassLoaderOptions(config) {
51
+ // 修改 additionalData 配置
52
+ config.additionalData = async (content, loaderContext) => {
53
+ // ...
54
+ };
55
+ },
56
+ },
57
+ },
58
+ };
59
+ ```
34
60
 
35
- 当 `tools.sass` 为 Function 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果,第二个参数提供了一些可以直接调用的工具函数:
61
+ ### 关闭 URL 重写
62
+
63
+ 默认情况下,Sass 文件里的相对 URL 会经过 resolve-url-loader 重写为相对于源文件的路径。如果项目不依赖这一行为,可以关闭它来减少一个 loader:
36
64
 
37
65
  ```js
38
66
  export default {
39
67
  tools: {
40
- sass(config) {
41
- // 修改 sourceMap 配置
42
- config.additionalData = async (content, loaderContext) => {
43
- // ...
44
- };
68
+ sass: {
69
+ rewriteUrls: false,
45
70
  },
46
71
  },
47
72
  };
@@ -55,7 +80,9 @@ export default {
55
80
  export default {
56
81
  tools: {
57
82
  sass: {
58
- implementation: require('sass'),
83
+ sassLoaderOptions: {
84
+ implementation: require('sass'),
85
+ },
59
86
  },
60
87
  },
61
88
  };
@@ -72,8 +99,53 @@ export default {
72
99
  ```js
73
100
  export default {
74
101
  tools: {
75
- sass(config, { addExcludes }) {
76
- addExcludes(/node_modules/);
102
+ sass: {
103
+ sassLoaderOptions(config, { addExcludes }) {
104
+ addExcludes(/node_modules/);
105
+ },
106
+ },
107
+ },
108
+ };
109
+ ```
110
+
111
+ 推荐直接使用插件的 `exclude` 选项,效果相同:
112
+
113
+ ```js
114
+ export default {
115
+ tools: {
116
+ sass: {
117
+ exclude: /node_modules/,
118
+ },
119
+ },
120
+ };
121
+ ```
122
+
123
+ ### 兼容旧写法
124
+
125
+ :::warning 不要混写两种层级
126
+ 同一个对象里只要出现插件顶层键(`sassLoaderOptions`、`include`、`exclude` 等),整个对象就会按插件选项解析,其中的 loader 选项不会生效。例如 `tools.sass: { rewriteUrls: false, sassOptions: { ... } }` 里的 `sassOptions` 会被忽略,必须移到 `sassLoaderOptions` 下;开发环境下会打印一条提示。
127
+ :::
128
+
129
+
130
+ 在之前的版本中,`tools.sass` 的取值直接是 sass-loader 的选项,例如 `tools.sass: { sassOptions: {} }` 或 `tools.sass(config, { addExcludes }) {}`。这种写法目前仍然生效,Modern.js 会自动把它包装为 `sassLoaderOptions`,产出的配置与之前完全一致;在开发环境下会打印一条迁移提示,并将在下一个大版本中移除。
131
+
132
+ ```js
133
+ // 旧写法
134
+ export default {
135
+ tools: {
136
+ sass: {
137
+ sourceMap: true,
138
+ },
139
+ },
140
+ };
141
+
142
+ // 新写法
143
+ export default {
144
+ tools: {
145
+ sass: {
146
+ sassLoaderOptions: {
147
+ sourceMap: true,
148
+ },
77
149
  },
78
150
  },
79
151
  };
@@ -0,0 +1,93 @@
1
+ ---
2
+ title: svgr
3
+ ---
4
+
5
+ # tools.svgr
6
+
7
+ - **类型:** `Object | Function | false`
8
+ - **默认值:**
9
+
10
+ ```js
11
+ const defaultOptions = {
12
+ mixedImport: true,
13
+ svgrOptions: {
14
+ exportType: 'named',
15
+ },
16
+ };
17
+ ```
18
+
19
+ `tools.svgr` 用于修改 [@rsbuild/plugin-svgr](https://rsbuild.rs/plugins/list/plugin-svgr) 的选项,取值为该插件的完整选项。设置为 `false` 时不再注册 SVGR 插件,所有 `.svg` 文件按静态资源处理。
20
+
21
+ | 选项 | 说明 |
22
+ | ----------------- | --------------------------------------------------------------------------------------------- |
23
+ | `svgrOptions` | 传给 [SVGR](https://react-svgr.com/docs/options/) 的参数,例如 `exportType`、`icon`、`svgoConfig` |
24
+ | `parallel` | 是否使用 worker 线程并行转换 SVG,默认 `false` |
25
+ | `exclude` | 指定哪些 SVG 文件不交给 SVGR 处理 |
26
+ | `excludeImporter` | 指定从哪些文件导入 SVG 时不交给 SVGR 处理 |
27
+ | `query` | 指定触发 SVGR 转换的 query,默认 `/react/` |
28
+ | `mixedImport` | 是否允许在同一个模块中同时导入 URL 与 React 组件,默认 `true` |
29
+
30
+ ### 合并规则
31
+
32
+ `tools.svgr` 为 `Object` 类型时,顶层字段与默认配置通过 Object.assign 进行浅层合并,`svgrOptions` 会再合并一层,因此只设置 `svgrOptions.icon` 不会丢掉默认的 `exportType`。
33
+
34
+ `tools.svgr` 为 `Function` 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果。也支持传入由对象和函数组成的数组,按顺序依次应用。
35
+
36
+ ### 并行转换
37
+
38
+ SVGR 转换是纯 JavaScript 计算,默认只占用 Node.js 主线程。项目里 SVG 文件较多时,开启 `parallel` 可以把转换分发到 worker 线程池:
39
+
40
+ ```js
41
+ export default {
42
+ tools: {
43
+ svgr: {
44
+ parallel: true,
45
+ },
46
+ },
47
+ };
48
+ ```
49
+
50
+ :::tip
51
+ 传给 worker 线程的选项需要满足[结构化克隆算法](https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)的要求,因此开启 `parallel` 后,`svgrOptions` 中不能包含函数。
52
+ :::
53
+
54
+ ### 修改默认导出
55
+
56
+ `svgrOptions.exportType` 决定 SVG 文件默认导出的内容:`'named'` 表示默认导出是文件 URL,React 组件通过 `ReactComponent` 具名导出;`'default'` 表示默认导出就是 React 组件。
57
+
58
+ ```js
59
+ export default {
60
+ tools: {
61
+ svgr: {
62
+ svgrOptions: {
63
+ exportType: 'default',
64
+ },
65
+ },
66
+ },
67
+ };
68
+ ```
69
+
70
+ ### 关闭 SVGR
71
+
72
+ 如果你确定项目内的所有 SVG 资源都没有当成 React 组件使用,可以关闭 SVGR 以提升构建性能:
73
+
74
+ ```js
75
+ export default {
76
+ tools: {
77
+ svgr: false,
78
+ },
79
+ };
80
+ ```
81
+
82
+ ### 与旧配置的关系
83
+
84
+ `tools.svgr` 取代了下面两个已废弃的配置项,二者目前仍然生效,并将在下一个大版本中移除:
85
+
86
+ | 旧配置 | 新配置 |
87
+ | ------------------------------------- | ------------------------------------------------- |
88
+ | `output.svgDefaultExport: 'component'` | `tools.svgr: { svgrOptions: { exportType: 'default' } }` |
89
+ | `output.svgDefaultExport: 'url'` | `tools.svgr: { svgrOptions: { exportType: 'named' } }` |
90
+ | `output.disableSvgr: true` | `tools.svgr: false` |
91
+ | `output.disableSvgr: false` | 默认行为,直接删除即可 |
92
+
93
+ 同时设置时以 `tools.svgr` 为准:显式设置了 `tools.svgr` 后,`output.disableSvgr` 不再生效;`tools.svgr.svgrOptions.exportType` 会覆盖 `output.svgDefaultExport` 派生的值。
@@ -42,16 +42,22 @@ export default () => <Logo />;
42
42
 
43
43
  ## 修改默认导出
44
44
 
45
- 你可以通过 [output.svgDefaultExport](/configure/app/output/svg-default-export) 配置项来修改 SVG 文件默认导出的内容,比如把默认导出的内容设置为 React 组件:
45
+ 你可以通过 [tools.svgr](/configure/app/tools/svgr) 的 `svgrOptions.exportType` 来修改 SVG 文件默认导出的内容,比如把默认导出的内容设置为 React 组件:
46
46
 
47
47
  ```ts
48
48
  export default {
49
- output: {
50
- svgDefaultExport: 'component',
49
+ tools: {
50
+ svgr: {
51
+ svgrOptions: {
52
+ exportType: 'default',
53
+ },
54
+ },
51
55
  },
52
56
  };
53
57
  ```
54
58
 
59
+ 旧的 [output.svgDefaultExport](/configure/app/output/svg-default-export) 配置项仍然生效,但已废弃。
60
+
55
61
  此时再使用默认导入,你会得到一个 React 组件,而不是 URL:
56
62
 
57
63
  ```tsx title="src/component/Logo.tsx"
@@ -80,12 +86,12 @@ export default () => <Logo />;
80
86
 
81
87
  默认情况下,在 JS 文件中引用 SVG 资源时,Modern.js 会调用 SVGR,将 SVG 图片转换为一个 React 组件。
82
88
 
83
- 如果你确定项目内的所有 SVG 资源都没有当成 React 组件使用时,可以通过将 [disableSvgr](/configure/app/output/disable-svgr) 设置为 true 来关闭此项转换,以提升构建性能。
89
+ 如果你确定项目内的所有 SVG 资源都没有当成 React 组件使用时,可以通过将 [tools.svgr](/configure/app/tools/svgr) 设置为 `false` 来关闭此项转换,以提升构建性能。
84
90
 
85
91
  ```js
86
92
  export default {
87
- output: {
88
- disableSvgr: true,
93
+ tools: {
94
+ svgr: false,
89
95
  },
90
96
  };
91
97
  ```
@@ -153,21 +159,27 @@ declare module '*.svg' {
153
159
  }
154
160
  ```
155
161
 
156
- 如果需要修改 SVGR 配置,可通过如下方式:
162
+ 如果需要修改 SVGR 配置,可通过 [tools.svgr](/configure/app/tools/svgr) 的 `svgrOptions` 设置。传入的 `svgoConfig.plugins` 会按插件名与默认配置深度合并,因此只需写出要改动的部分:
157
163
 
158
164
  ```js
159
165
  export default {
160
166
  tools: {
161
- bundlerChain: (chain, { CHAIN_ID }) => {
162
- chain.module
163
- .rule(CHAIN_ID.RULE.SVG)
164
- .oneOf(CHAIN_ID.ONE_OF.SVG)
165
- .use(CHAIN_ID.USE.SVGR)
166
- .tap(options => {
167
- // modify svgoConfig
168
- options.svgoConfig.plugins[0].params.overrides.removeUselessDefs = false;
169
- return options;
170
- });
167
+ svgr: {
168
+ svgrOptions: {
169
+ svgoConfig: {
170
+ plugins: [
171
+ {
172
+ name: 'preset-default',
173
+ params: {
174
+ overrides: {
175
+ // 在默认的 preset-default 之上追加一项 override
176
+ removeUselessDefs: false,
177
+ },
178
+ },
179
+ },
180
+ ],
181
+ },
182
+ },
171
183
  },
172
184
  },
173
185
  };
@@ -129,7 +129,7 @@ Rsbuild 是 Modern.js 底层的构建工具,通过添加 Rsbuild 插件可修
129
129
  | 插件 | 介绍 | Modern.js 链接 |
130
130
  | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
131
131
  | [React 插件](https://v2.rsbuild.rs/zh/plugins/list/plugin-react) | 提供对 React 的支持 | - |
132
- | [SVGR 插件](https://v2.rsbuild.rs/zh/plugins/list/plugin-svgr) | 支持将 SVG 图片转换为一个 React 组件 | [output.disableSvgr](/configure/app/output/disable-svgr)<br />[output.svgDefaultExport](/configure/app/output/svg-default-export) |
132
+ | [SVGR 插件](https://v2.rsbuild.rs/zh/plugins/list/plugin-svgr) | 支持将 SVG 图片转换为一个 React 组件 | [tools.svgr](/configure/app/tools/svgr) |
133
133
  | [Assets Retry 插件](https://github.com/rstackjs/rsbuild-plugin-assets-retry) | 用于在静态资源加载失败时自动发起重试请求 | [output.assetsRetry](/configure/app/output/assets-retry.html) |
134
134
  | [Type Check 插件](https://github.com/rstackjs/rsbuild-plugin-type-check) | 用于在单独的进程中运行 TypeScript 类型检查 | [output.disableTsChecker](/configure/app/output/disable-ts-checker.html)<br />[tools.tsChecker](/configure/app/tools/ts-checker.html) |
135
135
  | [Source Build 插件](https://github.com/rstackjs/rsbuild-plugin-source-build) | 用于 monorepo 场景,支持引用其他子目录的源代码,并完成构建和热更新 | [experiments.sourceBuild](/configure/app/experiments/source-build.html) |
package/package.json CHANGED
@@ -16,14 +16,14 @@
16
16
  "modern",
17
17
  "modern.js"
18
18
  ],
19
- "version": "3.9.1",
19
+ "version": "3.9.3",
20
20
  "publishConfig": {
21
21
  "registry": "https://registry.npmjs.org/",
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
25
  "mermaid": "^11.15.0",
26
- "@modern-js/sandpack-react": "3.9.1"
26
+ "@modern-js/sandpack-react": "3.9.3"
27
27
  },
28
28
  "devDependencies": {
29
29
  "rsbuild-plugin-open-graph": "1.1.3",