@modern-js/main-doc 0.0.0-nightly-20240819170736 → 0.0.0-nightly-20240821170648
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/docs/en/configure/app/tools/esbuild.mdx +1 -1
- package/docs/en/configure/app/tools/swc.mdx +1 -1
- package/docs/en/guides/_meta.json +5 -0
- package/docs/en/guides/rsbuild-plugins/plugin-esbuild.mdx +205 -0
- package/docs/en/guides/rsbuild-plugins/plugin-swc.mdx +356 -0
- package/docs/zh/configure/app/tools/esbuild.mdx +1 -1
- package/docs/zh/configure/app/tools/swc.mdx +1 -1
- package/docs/zh/guides/_meta.json +5 -0
- package/docs/zh/guides/rsbuild-plugins/plugin-esbuild.mdx +201 -0
- package/docs/zh/guides/rsbuild-plugins/plugin-swc.mdx +344 -0
- package/package.json +4 -4
@@ -41,4 +41,4 @@ export default defineConfig({
|
|
41
41
|
});
|
42
42
|
```
|
43
43
|
|
44
|
-
For config details, please refer to [
|
44
|
+
For config details, please refer to [Esbuild Plugin Configuration](/guides/rsbuild-plugins/plugin-esbuild.html#config).
|
@@ -77,4 +77,4 @@ export default defineConfig({
|
|
77
77
|
});
|
78
78
|
```
|
79
79
|
|
80
|
-
For config details, please refer to [
|
80
|
+
For config details, please refer to [SWC Plugin Configuration](/guides/rsbuild-plugins/plugin-swc.html#config).
|
@@ -0,0 +1,205 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 3
|
3
|
+
---
|
4
|
+
|
5
|
+
# Esbuild Plugin
|
6
|
+
|
7
|
+
:::warning
|
8
|
+
**The esbuild feature in the current document is no longer maintained**, we recommend using the Rspack + SWC solution, because Rspack + SWC provide better build performance, richer features, and better compatibility.
|
9
|
+
|
10
|
+
Please refer to [「Use Rspack」](guides/advanced-features/rspack-start) for more information.
|
11
|
+
|
12
|
+
:::
|
13
|
+
|
14
|
+
import Esbuild from '@modern-js/builder-doc/docs/en/shared/esbuild.md';
|
15
|
+
|
16
|
+
<Esbuild />
|
17
|
+
|
18
|
+
## Quick Start
|
19
|
+
|
20
|
+
### Used in Modern.js framework
|
21
|
+
|
22
|
+
The Modern.js framework integrates the Builder's esbuild plugin by default, so you don't need to manually install and register the plugin, just use the [tools.esbuild](https://modernjs.dev/en/configure/app/tools/esbuild.html) configuration:
|
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
|
+
## Config
|
40
|
+
|
41
|
+
The plugin will enable code transformation and minification by default. You can also customize the behavior of the plugin through configuration.
|
42
|
+
|
43
|
+
### loader
|
44
|
+
|
45
|
+
- **Type:**
|
46
|
+
|
47
|
+
```ts
|
48
|
+
type LoaderOptions = EsbuildLoaderOptions | false | undefined;
|
49
|
+
```
|
50
|
+
|
51
|
+
- **Default:**
|
52
|
+
|
53
|
+
```ts
|
54
|
+
const defaultOptions = {
|
55
|
+
target: 'es2015',
|
56
|
+
charset: builderConfig.output.charset,
|
57
|
+
};
|
58
|
+
```
|
59
|
+
|
60
|
+
This config is used to enable JavaScript/TypeScript transformation, which will replace babel-loader and ts-loader with esbuild-loader.
|
61
|
+
|
62
|
+
If you want to modify the options, you can check the [esbuild-loader documentation](https://github.com/privatenumber/esbuild-loader#loader).
|
63
|
+
|
64
|
+
#### Set JSX Format
|
65
|
+
|
66
|
+
When using esbuild for transformation, esbuild will read the `compilerOptions.jsx` field in `tsconfig.json` to determine which JSX syntax to use.
|
67
|
+
|
68
|
+
Therefore, you need to set the correct JSX syntax in `tsconfig.json`.
|
69
|
+
|
70
|
+
For example, React projects need to set `compilerOptions.jsx` to `react-jsx`:
|
71
|
+
|
72
|
+
```json
|
73
|
+
{
|
74
|
+
"compilerOptions": {
|
75
|
+
"jsx": "react-jsx"
|
76
|
+
}
|
77
|
+
}
|
78
|
+
```
|
79
|
+
|
80
|
+
#### Set the target environment
|
81
|
+
|
82
|
+
Use the `target` option to set the target environment for transformation. `target` can be set directly to the JavaScript language version, such as `es6`, `es2020`; it can also be set to several target environments, each target environment is an environment name followed by a version number, such as `['chrome58', 'edge16' ,'firefox57']`. For a detailed introduction of the `target` option, please refer to [esbuild - target](https://esbuild.github.io/api/#target).
|
83
|
+
|
84
|
+
target supports setting to the following environments:
|
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
|
+
#### Disable transformation
|
104
|
+
|
105
|
+
Set `loader` to `false` to disable esbuild transformation, and Builder will continue to use Babel to transform the code.
|
106
|
+
|
107
|
+
```ts
|
108
|
+
builderPluginEsbuild({
|
109
|
+
loader: false,
|
110
|
+
});
|
111
|
+
```
|
112
|
+
|
113
|
+
### minimize
|
114
|
+
|
115
|
+
- **Type:**
|
116
|
+
|
117
|
+
```ts
|
118
|
+
type MinimizeOptions = EsbuildMinifyOptions | false | undefined;
|
119
|
+
```
|
120
|
+
|
121
|
+
- **Default:**
|
122
|
+
|
123
|
+
```ts
|
124
|
+
const defaultOptions = {
|
125
|
+
css: true,
|
126
|
+
target: 'es2015',
|
127
|
+
format: builderTarget === 'web' ? 'iife' : undefined,
|
128
|
+
};
|
129
|
+
```
|
130
|
+
|
131
|
+
This option is used to enable minification for JavaScript and CSS.
|
132
|
+
|
133
|
+
If you want to modify the options, you can check the [esbuild-loader documentation](https://github.com/privatenumber/esbuild-loader#minifyplugin).
|
134
|
+
|
135
|
+
#### Set the target environment
|
136
|
+
|
137
|
+
Use the `target` option to set the target environment for minification.
|
138
|
+
|
139
|
+
```ts
|
140
|
+
builderPluginEsbuild({
|
141
|
+
minimize: {
|
142
|
+
target: 'chrome61',
|
143
|
+
},
|
144
|
+
});
|
145
|
+
```
|
146
|
+
|
147
|
+
#### Disable minification
|
148
|
+
|
149
|
+
Set `minimize` to `false` to disable esbuild minification, and Builder will continue to use Terser to minify the code.
|
150
|
+
|
151
|
+
```ts
|
152
|
+
builderPluginEsbuild({
|
153
|
+
minimize: false,
|
154
|
+
});
|
155
|
+
```
|
156
|
+
|
157
|
+
## Limitations
|
158
|
+
|
159
|
+
Although esbuild can significantly improve the build performance of existing webpack projects, it still has certain limitations that require special attention.
|
160
|
+
|
161
|
+
### Compatibility
|
162
|
+
|
163
|
+
As a compiler (i.e. `loader` capability), esbuild usually supports at least ES2015 (that is, ES6) syntax, and does not have the ability to automatically inject Polyfill.. If the production environment needs to downgrade to ES5 and below syntax, it is recommended to use SWC compilation.
|
164
|
+
|
165
|
+
You can specify the target syntax version by following config:
|
166
|
+
|
167
|
+
```ts
|
168
|
+
builderPluginEsbuild({
|
169
|
+
loader: {
|
170
|
+
target: 'es2015',
|
171
|
+
},
|
172
|
+
});
|
173
|
+
```
|
174
|
+
|
175
|
+
As a code minify tool (i.e. `minimize` capability), esbuild can minify the code in production environment, and usually supports ES2015 syntax at least.
|
176
|
+
|
177
|
+
If you set the compressed `target` to `es5`, you need to ensure that all codes have been compiled to ES5 codes, otherwise it will cause esbuild compilation error: `Transforming 'xxx' to the configured target environment ("es5") is not supported yet `.
|
178
|
+
|
179
|
+
Therefore, for projects that need to be compatible with ES5 and below syntax in the production environment, please be careful to enable the minimize capability, and it is recommended to use SWC compression.
|
180
|
+
|
181
|
+
You can specify the target syntax version by following config:
|
182
|
+
|
183
|
+
```js
|
184
|
+
builderPluginEsbuild({
|
185
|
+
minimize: {
|
186
|
+
target: 'es2015',
|
187
|
+
},
|
188
|
+
});
|
189
|
+
```
|
190
|
+
|
191
|
+
:::danger Caution
|
192
|
+
Projects that need to be compatible with ES5 and below syntax in the production environment need to be careful to turn on the minimize config.
|
193
|
+
:::
|
194
|
+
|
195
|
+
### Not support Babel plugins
|
196
|
+
|
197
|
+
As a compiler, the syntax transformation function of the original Babel plugins such as `babel-plugin-import` is not available after esbuild is turned on. And since the bottom layer of the plugin uses esbuild's `Transform API`, it does not support esbuild plugins to customize the compilation process.
|
198
|
+
|
199
|
+
If you have requirements related to Babel plugins such as `babel-plugin-import`, you can use the SWC plugin.
|
200
|
+
|
201
|
+
### Bundle Size
|
202
|
+
|
203
|
+
Although the compression speed of esbuild is faster, the compression ratio of esbuild is lower than that of terser, so the bundle size will increase, please use it according to the scenes. Generally speaking, esbuild is more suitable for scenes that are not sensitive to bundle size.
|
204
|
+
|
205
|
+
You can refer to [minification-benchmarks](https://github.com/privatenumber/minification-benchmarks) for a detailed comparison between minimizers.
|
@@ -0,0 +1,356 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 2
|
3
|
+
---
|
4
|
+
|
5
|
+
# SWC Plugin
|
6
|
+
|
7
|
+
import SWC from '@modern-js/builder-doc/docs/en/shared/swc.md';
|
8
|
+
|
9
|
+
<SWC />
|
10
|
+
|
11
|
+
## Usage Scenarios
|
12
|
+
|
13
|
+
Before using the SWC plugin, please understand the scenarios and limitations of the SWC plugin to determine whether your project is suitable for using it.
|
14
|
+
|
15
|
+
### Rspack Scenario
|
16
|
+
|
17
|
+
If you are already using Rspack as the bundler in your project, then you do not need to use the SWC plugin, because Rspack uses SWC for transpiler and minifier by default, and the SWC compilation capabilities are available out of the box.
|
18
|
+
|
19
|
+
If you have configured the current SWC plugin when using Rspack, it will not have any effect.
|
20
|
+
|
21
|
+
### Babel Plugins
|
22
|
+
|
23
|
+
If your project requires the registration of some custom Babel plugins, you will not be able to register and use Babel plugins after using SWC, since it replaces Babel as the transpiler.
|
24
|
+
|
25
|
+
For most common Babel plugins, you can find corresponding replacements in SWC, such as:
|
26
|
+
|
27
|
+
- `@babel/preset-env`: use [presetEnv](#presetenv) instead.
|
28
|
+
- `@babel/preset-react`: use [presetReact](#presetreact) instead.
|
29
|
+
- `babel-plugin-import`: use [source.transformImport](/configure/app/source/transform-import) instead.
|
30
|
+
- `babel-plugin-lodash`: use [extensions.lodash](#extensionslodash) instead.
|
31
|
+
- `@emotion/babel-plugin`: use [extensions.emotion](#extensionsemotion) instead.
|
32
|
+
- `babel-plugin-styled-components`: use [extensions.styledComponents](#extensionsstyledcomponents) instead.
|
33
|
+
- `@babel/plugin-react-transform-remove-prop-types`: use [reactUtils.removePropTypes](#extensionsreactutils) instead.
|
34
|
+
|
35
|
+
If you use Babel plugin capabilities that are not yet supported by SWC, you will no longer be able to use them after switching to SWC compilation. You can give feedback via issues under the [swc-plugins](https://github.com/web-infra-dev/swc-plugins) repository and we will evaluate if built-in support is needed.
|
36
|
+
|
37
|
+
### Bundle Size
|
38
|
+
|
39
|
+
When using SWC for code minification instead of [terser](https://github.com/terser/terser) and [cssnano](https://github.com/cssnano/cssnano), there may be a small change in the bundle size. SWC outperforms terser for JavaScript code compression and slightly underperforms cssnano for CSS code compression.
|
40
|
+
|
41
|
+
For a detailed comparison between minifiers, see [minification-benchmarks](https://github.com/privatenumber/minification-benchmarks).
|
42
|
+
|
43
|
+
## Quick Start
|
44
|
+
|
45
|
+
### Used in Modern.js framework
|
46
|
+
|
47
|
+
The Modern.js framework integrates the Builder's SWC plugin, and you can use it in the following ways:
|
48
|
+
|
49
|
+
import EnableSWC from '@modern-js/builder-doc/docs/en/shared/enableSwc.md';
|
50
|
+
|
51
|
+
<EnableSWC />
|
52
|
+
|
53
|
+
That's it! Now you can use SWC transformation and minification in your project.
|
54
|
+
|
55
|
+
## Config
|
56
|
+
|
57
|
+
- **Type:**
|
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 is configurations of 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
|
+
The plugin configuration is based on the SWC configuration. In order to simplify some deep-level configurations and improve development experience, certain extensions have been made. When using object-based configuration, for example you can use `presetReact` and `presetEnv` to quickly configure React-related features and syntax downgrading. Other configurations will also be directly passed through to SWC.
|
79
|
+
|
80
|
+
When using function-based configuration, the default configuration generated by the plugin will be passed in, allowing you to modify it or return a new configuration.
|
81
|
+
|
82
|
+
### presetReact
|
83
|
+
|
84
|
+
- **Type:** [presetReact](https://swc.rs/docs/configuration/compilation#jsctransformreact) in SWC.
|
85
|
+
|
86
|
+
Ported from `@babel/preset-react`. The value you passed will be merged with default option.
|
87
|
+
|
88
|
+
By default, the plugin will set `runtime` field based on your `react` version, if `react` version is newer than 17.0.0, it will be set to `automatic`, otherwish `classic`.
|
89
|
+
|
90
|
+
### presetEnv
|
91
|
+
|
92
|
+
- **Type:** [presetEnv](https://swc.rs/docs/configuration/supported-browsers#options) in SWC.
|
93
|
+
|
94
|
+
Ported from `@babel/preset-env`. The value you passed will be merged with default option.
|
95
|
+
|
96
|
+
Default option is:
|
97
|
+
|
98
|
+
```ts
|
99
|
+
{
|
100
|
+
targets: '', // automatic get browserslist from your project, so you don't have to set this field
|
101
|
+
mode: 'usage',
|
102
|
+
}
|
103
|
+
```
|
104
|
+
|
105
|
+
### jsMinify
|
106
|
+
|
107
|
+
- **Type:** `boolean` or [compress configuration](https://terser.org/docs/api-reference.html#compress-options).
|
108
|
+
- **Default:** `{ compress: {}, mangle: true }`.
|
109
|
+
|
110
|
+
If set it to `false`, then SWC minification will be disabled, if set it to `true` then will it applies default option. If you pass an object, then this object will be merged with default option.
|
111
|
+
|
112
|
+
### cssMinify
|
113
|
+
|
114
|
+
- **Type:**: `boolean`
|
115
|
+
- **Default:**: `true`
|
116
|
+
|
117
|
+
Whether enable to compress CSS files by SWC. If enabled, it will improve the performance of CSS compression, but the compression ratio will be slightly reduced.
|
118
|
+
|
119
|
+
### overrides
|
120
|
+
|
121
|
+
- **Type:**
|
122
|
+
|
123
|
+
```ts
|
124
|
+
interface Overrides extends SwcOptions {
|
125
|
+
test: RegExp;
|
126
|
+
include: RegExp[];
|
127
|
+
exclude: RegExp[];
|
128
|
+
}
|
129
|
+
```
|
130
|
+
|
131
|
+
- **Default:** `undefined`
|
132
|
+
|
133
|
+
Specify special configuration for specific modules. For example if you want to set ie 11 target for `foo.ts`:
|
134
|
+
|
135
|
+
```ts
|
136
|
+
{
|
137
|
+
test: /foo.ts/,
|
138
|
+
env: { targets: 'ie 11' }
|
139
|
+
}
|
140
|
+
```
|
141
|
+
|
142
|
+
This will merged into the default configuration, and do not affect other modules.
|
143
|
+
|
144
|
+
### extensions
|
145
|
+
|
146
|
+
- **Type:** `Object`
|
147
|
+
|
148
|
+
Some plugins ported from Babel.
|
149
|
+
|
150
|
+
#### extensions.reactUtils
|
151
|
+
|
152
|
+
- **Type:** `Object`
|
153
|
+
|
154
|
+
```ts
|
155
|
+
type ReactUtilsOptions = {
|
156
|
+
autoImportReact?: boolean;
|
157
|
+
removeEffect?: boolean;
|
158
|
+
removePropTypes?: {
|
159
|
+
mode?: 'remove' | 'unwrap' | 'unsafe-wrap';
|
160
|
+
removeImport?: boolean;
|
161
|
+
ignoreFilenames?: string[];
|
162
|
+
additionalLibraries?: string[];
|
163
|
+
classNameMatchers?: string[];
|
164
|
+
};
|
165
|
+
};
|
166
|
+
```
|
167
|
+
|
168
|
+
Some little help utils for `React`.
|
169
|
+
|
170
|
+
**reactUtils.autoImportReact**
|
171
|
+
|
172
|
+
- **Type:** `boolean`
|
173
|
+
|
174
|
+
Automatically import `React` as global variable, eg: `import React from 'react'`.
|
175
|
+
Mostly used for generated `React.createElement`.
|
176
|
+
|
177
|
+
**reactUtils.removeEffect**
|
178
|
+
|
179
|
+
- **Type:** `boolean`
|
180
|
+
|
181
|
+
Remove `useEffect` call.
|
182
|
+
|
183
|
+
**reactUtils.removePropTypes**
|
184
|
+
|
185
|
+
- **Type:**
|
186
|
+
|
187
|
+
```ts
|
188
|
+
type RemovePropTypesOptions = {
|
189
|
+
mode?: 'remove' | 'unwrap' | 'unsafe-wrap';
|
190
|
+
removeImport?: boolean;
|
191
|
+
ignoreFilenames?: string[];
|
192
|
+
additionalLibraries?: string[];
|
193
|
+
classNameMatchers?: string[];
|
194
|
+
};
|
195
|
+
```
|
196
|
+
|
197
|
+
Remove `React` runtime type checking. This is ported from [@babel/plugin-react-transform-remove-prop-types](https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types), All the configurations remain the same.
|
198
|
+
|
199
|
+
#### extensions.lodash
|
200
|
+
|
201
|
+
- **Type:**
|
202
|
+
|
203
|
+
```ts
|
204
|
+
type LodashOptions = {
|
205
|
+
cwd?: string;
|
206
|
+
ids?: string[];
|
207
|
+
};
|
208
|
+
```
|
209
|
+
|
210
|
+
- **Default:**
|
211
|
+
|
212
|
+
```ts
|
213
|
+
const defaultOptions = {
|
214
|
+
cwd: process.cwd(),
|
215
|
+
ids: ['lodash', 'lodash-es'],
|
216
|
+
};
|
217
|
+
```
|
218
|
+
|
219
|
+
Ported from [babel-plugin-lodash](https://github.com/lodash/babel-plugin-lodash), it is used to automatically convert references to Lodash into on-demand imports, thereby reducing the bundle size of Lodash code.
|
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
|
+
- **Type:**
|
233
|
+
|
234
|
+
```ts
|
235
|
+
boolean | {
|
236
|
+
// Enabled by default in development, disabled in production to reduce file size,
|
237
|
+
// setting this will override the default for all environments.
|
238
|
+
displayName?: boolean,
|
239
|
+
// Enabled by default.
|
240
|
+
ssr?: boolean,
|
241
|
+
// Enabled by default.
|
242
|
+
fileName?: boolean,
|
243
|
+
// Empty by default.
|
244
|
+
topLevelImportPaths?: string[],
|
245
|
+
// Defaults to ["index"].
|
246
|
+
meaninglessFileNames?: string[],
|
247
|
+
// Enabled by default.
|
248
|
+
cssProp?: boolean,
|
249
|
+
// Empty by default.
|
250
|
+
namespace?: string,
|
251
|
+
};
|
252
|
+
```
|
253
|
+
|
254
|
+
This is ported by Next.js team from [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components).
|
255
|
+
|
256
|
+
#### extensions.emotion
|
257
|
+
|
258
|
+
- **Type:**
|
259
|
+
|
260
|
+
```ts
|
261
|
+
boolean | {
|
262
|
+
// default is true. It will be disabled when build type is production.
|
263
|
+
sourceMap?: boolean,
|
264
|
+
// default is 'dev-only'.
|
265
|
+
autoLabel?: 'never' | 'dev-only' | 'always',
|
266
|
+
// default is '[local]'.
|
267
|
+
// Allowed values: `[local]` `[filename]` and `[dirname]`
|
268
|
+
// This option only works when autoLabel is set to 'dev-only' or 'always'.
|
269
|
+
// It allows you to define the format of the resulting label.
|
270
|
+
// The format is defined via string where variable parts are enclosed in square brackets [].
|
271
|
+
// For example labelFormat: "my-classname--[local]", where [local] will be replaced with the name of the variable the result is assigned to.
|
272
|
+
labelFormat?: string,
|
273
|
+
// default is undefined.
|
274
|
+
// This option allows you to tell the compiler what imports it should
|
275
|
+
// look at to determine what it should transform so if you re-export
|
276
|
+
// Emotion's exports, you can still use transforms.
|
277
|
+
importMap?: {
|
278
|
+
[packageName: string]: {
|
279
|
+
[exportName: string]: {
|
280
|
+
canonicalImport?: [string, string],
|
281
|
+
styledBaseImport?: [string, string],
|
282
|
+
}
|
283
|
+
}
|
284
|
+
},
|
285
|
+
}
|
286
|
+
```
|
287
|
+
|
288
|
+
This is ported by Next.js team from [@emotion/babel-plugin](https://www.npmjs.com/package/@emotion/babel-plugin)
|
289
|
+
|
290
|
+
#### extensions.pluginImport
|
291
|
+
|
292
|
+
:::tip
|
293
|
+
Builder provides the [source.transformImport](/configure/app/source/transform-import) config, so you don't need to configure `extensions.pluginImport` manually.
|
294
|
+
:::
|
295
|
+
|
296
|
+
Ported from [babel-plugin-import](https://github.com/umijs/babel-plugin-import), configurations are the same.
|
297
|
+
|
298
|
+
Some configurations can be passed in functions, such as `customName`, `customStyleName`. These JavaScript functions will be called by Rust through Node-API, which will cause some performance overhead.
|
299
|
+
|
300
|
+
Some simple function logic can be replaced by template language. Therefore, the configuration of function items such as `customName`, `customStyleName` can also be passed in strings as templates to replace functions and improve performance.
|
301
|
+
|
302
|
+
For example:
|
303
|
+
|
304
|
+
```ts
|
305
|
+
import { MyButton as Btn } from 'foo';
|
306
|
+
```
|
307
|
+
|
308
|
+
Apply following configurations:
|
309
|
+
|
310
|
+
```ts
|
311
|
+
PluginSWC({
|
312
|
+
extensions: {
|
313
|
+
pluginImport: [
|
314
|
+
{
|
315
|
+
libraryName: 'foo',
|
316
|
+
customName: 'foo/es/{{ member }}',
|
317
|
+
},
|
318
|
+
],
|
319
|
+
},
|
320
|
+
});
|
321
|
+
```
|
322
|
+
|
323
|
+
`{{ member }}` will be replaced by the imported specifier:
|
324
|
+
|
325
|
+
```ts
|
326
|
+
import Btn from 'foo/es/MyButton';
|
327
|
+
```
|
328
|
+
|
329
|
+
Template `customName: 'foo/es/{{ member }}'` is the same as `` customName: (member) => `foo/es/${member}` ``, but template value has no performance overhead of Node-API.
|
330
|
+
|
331
|
+
The template used here is [handlebars](https://handlebarsjs.com). There are some useful builtin tools, Take the above import statement as an example:
|
332
|
+
|
333
|
+
```ts
|
334
|
+
PluginSWC({
|
335
|
+
extensions: {
|
336
|
+
pluginImport: [
|
337
|
+
{
|
338
|
+
libraryName: 'foo',
|
339
|
+
customName: 'foo/es/{{ kebabCase member }}',
|
340
|
+
},
|
341
|
+
],
|
342
|
+
},
|
343
|
+
});
|
344
|
+
```
|
345
|
+
|
346
|
+
Transformed to:
|
347
|
+
|
348
|
+
```ts
|
349
|
+
import Btn from 'foo/es/my-button';
|
350
|
+
```
|
351
|
+
|
352
|
+
In addition to `kebabCase`, there are `cameraCase`, `snakeCase`, `upperCase` and `lowerCase` can be used as well.
|
353
|
+
|
354
|
+
## Limitation
|
355
|
+
|
356
|
+
Do not support `@babel/plugin-transform-runtime` and other custom Babel plugins.
|
@@ -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": "0.0.0-nightly-
|
18
|
+
"version": "0.0.0-nightly-20240821170648",
|
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": "0.0.0-nightly-
|
25
|
+
"@modern-js/sandpack-react": "0.0.0-nightly-20240821170648"
|
26
26
|
},
|
27
27
|
"peerDependencies": {
|
28
|
-
"@modern-js/builder-doc": "0.0.0-nightly-
|
28
|
+
"@modern-js/builder-doc": "0.0.0-nightly-20240821170648"
|
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": "0.0.0-nightly-
|
42
|
+
"@modern-js/builder-doc": "0.0.0-nightly-20240821170648"
|
43
43
|
},
|
44
44
|
"scripts": {
|
45
45
|
"dev": "rspress dev",
|