@bleedingdev/modern-js-builder 3.9.0-ultramodern.9 → 3.9.3-ultramodern.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/plugins/environmentDefaults.js +9 -8
- package/dist/cjs/plugins/manifest.js +3 -1
- package/dist/cjs/plugins/rscConfig.js +35 -14
- package/dist/cjs/shared/parseCommonConfig.js +42 -21
- package/dist/cjs/shared/pluginOptions.js +122 -0
- package/dist/cjs/shared/tsgo.js +7 -28
- package/dist/esm/plugins/environmentDefaults.mjs +9 -8
- package/dist/esm/plugins/manifest.mjs +3 -1
- package/dist/esm/plugins/rscConfig.mjs +35 -14
- package/dist/esm/shared/parseCommonConfig.mjs +43 -22
- package/dist/esm/shared/pluginOptions.mjs +75 -0
- package/dist/esm/shared/tsgo.mjs +7 -28
- package/dist/esm-node/plugins/environmentDefaults.mjs +9 -8
- package/dist/esm-node/plugins/manifest.mjs +3 -1
- package/dist/esm-node/plugins/rscConfig.mjs +35 -14
- package/dist/esm-node/shared/parseCommonConfig.mjs +43 -22
- package/dist/esm-node/shared/pluginOptions.mjs +76 -0
- package/dist/esm-node/shared/tsgo.mjs +7 -28
- package/dist/types/index.d.ts +1 -1
- package/dist/types/plugins/rscConfig.d.ts +4 -1
- package/dist/types/shared/pluginOptions.d.ts +32 -0
- package/dist/types/shared/tsgo.d.ts +2 -4
- package/dist/types/types.d.ts +36 -9
- package/package.json +38 -23
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { mergeRsbuildConfig } from "@rsbuild/core";
|
|
2
2
|
import { pluginCssMinimizer } from "@rsbuild/plugin-css-minimizer";
|
|
3
3
|
import { pluginLess } from "@rsbuild/plugin-less";
|
|
4
|
-
import { pluginReact } from "@rsbuild/plugin-react";
|
|
5
4
|
import { pluginSass } from "@rsbuild/plugin-sass";
|
|
6
5
|
import { pluginDevtool } from "../plugins/devtools.mjs";
|
|
7
6
|
import { pluginEmitRouteFile } from "../plugins/emitRouteFile.mjs";
|
|
@@ -10,8 +9,9 @@ import { pluginGlobalVars } from "../plugins/globalVars.mjs";
|
|
|
10
9
|
import { pluginHtmlMinifierTerser } from "../plugins/htmlMinify.mjs";
|
|
11
10
|
import { pluginRuntimeChunk } from "../plugins/runtimeChunk.mjs";
|
|
12
11
|
import { transformToRsbuildServerOptions } from "./devServer.mjs";
|
|
12
|
+
import { normalizeLessOptions, normalizeSassOptions, resolveSvgrOptions } from "./pluginOptions.mjs";
|
|
13
13
|
import { withTsgoDefaults } from "./tsgo.mjs";
|
|
14
|
-
import { NODE_MODULES_REGEX } from "./utils.mjs";
|
|
14
|
+
import { NODE_MODULES_REGEX, SERVICE_WORKER_ENVIRONMENT_NAME } from "./utils.mjs";
|
|
15
15
|
const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
|
|
16
16
|
const GLOBAL_CSS_REGEX = /\.global\.\w+$/;
|
|
17
17
|
const DEFAULT_CSS_MINIFIER_OPTIONS = {
|
|
@@ -37,7 +37,7 @@ function removeUndefinedKey(obj) {
|
|
|
37
37
|
}
|
|
38
38
|
async function parseCommonConfig(builderConfig, options) {
|
|
39
39
|
const frameworkConfigPath = options?.frameworkConfigPath;
|
|
40
|
-
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
40
|
+
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, svgr, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
41
41
|
let combinedAlias;
|
|
42
42
|
if (alias || resolve.alias) combinedAlias = [].concat(alias ?? []).concat(resolve.alias ?? []);
|
|
43
43
|
const rsbuildConfig = {
|
|
@@ -120,12 +120,8 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
120
120
|
sourceMap
|
|
121
121
|
}),
|
|
122
122
|
pluginEmitRouteFile(),
|
|
123
|
-
pluginSass(
|
|
124
|
-
|
|
125
|
-
}),
|
|
126
|
-
pluginLess({
|
|
127
|
-
lessLoaderOptions: less
|
|
128
|
-
}),
|
|
123
|
+
pluginSass(normalizeSassOptions(sass)),
|
|
124
|
+
pluginLess(normalizeLessOptions(less)),
|
|
129
125
|
pluginEnvironmentDefaults(distPath),
|
|
130
126
|
pluginHtmlMinifierTerser()
|
|
131
127
|
];
|
|
@@ -152,19 +148,44 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
152
148
|
const { pluginSourceBuild } = await import("@rsbuild/plugin-source-build");
|
|
153
149
|
rsbuildPlugins.push(pluginSourceBuild(true === sourceBuild ? {} : sourceBuild));
|
|
154
150
|
}
|
|
155
|
-
rsbuildPlugins.push(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
151
|
+
rsbuildPlugins.push({
|
|
152
|
+
name: 'rsbuild:react',
|
|
153
|
+
async setup (api) {
|
|
154
|
+
const { pluginReact } = await import("@rsbuild/plugin-react");
|
|
155
|
+
return pluginReact().setup(api);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
if (!options?.disableReactCompiler && void 0 !== reactCompiler) rsbuildPlugins.push({
|
|
159
|
+
name: 'builder:react-compiler',
|
|
160
|
+
setup (api) {
|
|
161
|
+
api.modifyEnvironmentConfig((config, { name, mergeEnvironmentConfig })=>'web' === config.output.target && name !== SERVICE_WORKER_ENVIRONMENT_NAME ? mergeEnvironmentConfig({
|
|
162
|
+
tools: {
|
|
163
|
+
swc: {
|
|
164
|
+
jsc: {
|
|
165
|
+
transform: {
|
|
166
|
+
reactCompiler
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, config) : config);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
const svgrOptions = resolveSvgrOptions({
|
|
175
|
+
svgr,
|
|
176
|
+
disableSvgr,
|
|
177
|
+
svgDefaultExport
|
|
178
|
+
});
|
|
179
|
+
if (false !== svgrOptions) rsbuildPlugins.push({
|
|
180
|
+
name: 'rsbuild:svgr',
|
|
181
|
+
pre: [
|
|
182
|
+
'rsbuild:react'
|
|
183
|
+
],
|
|
184
|
+
async setup (api) {
|
|
185
|
+
const { pluginSvgr } = await import("@rsbuild/plugin-svgr");
|
|
186
|
+
await pluginSvgr(svgrOptions).setup(api);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
168
189
|
if (assetsRetry) {
|
|
169
190
|
const { pluginAssetsRetry } = await import("@rsbuild/plugin-assets-retry");
|
|
170
191
|
rsbuildPlugins.push(pluginAssetsRetry(assetsRetry));
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { applyOptionsChain, isDevCommand, logger } from "@modern-js/utils";
|
|
2
|
+
const LESS_PLUGIN_KEYS = [
|
|
3
|
+
'lessLoaderOptions',
|
|
4
|
+
'include',
|
|
5
|
+
'exclude',
|
|
6
|
+
'parallel'
|
|
7
|
+
];
|
|
8
|
+
const SASS_PLUGIN_KEYS = [
|
|
9
|
+
'sassLoaderOptions',
|
|
10
|
+
'include',
|
|
11
|
+
'exclude',
|
|
12
|
+
'rewriteUrls'
|
|
13
|
+
];
|
|
14
|
+
const warned = new Set();
|
|
15
|
+
const resetPluginOptionsWarnings = ()=>{
|
|
16
|
+
warned.clear();
|
|
17
|
+
};
|
|
18
|
+
const warnOnceInDev = (key, message)=>{
|
|
19
|
+
if (!isDevCommand() || warned.has(key)) return;
|
|
20
|
+
warned.add(key);
|
|
21
|
+
logger.warn(message);
|
|
22
|
+
};
|
|
23
|
+
const isPlainObject = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
|
|
24
|
+
const isPluginLevelOptions = (value, pluginKeys)=>isPlainObject(value) && pluginKeys.some((key)=>key in value);
|
|
25
|
+
const isEmptyObject = (value)=>isPlainObject(value) && 0 === Object.keys(value).length;
|
|
26
|
+
const warnIgnoredKeys = (name, value, pluginKeys, loaderOptionsKey)=>{
|
|
27
|
+
const pluginLevel = Object.keys(value).filter((key)=>pluginKeys.includes(key));
|
|
28
|
+
const ignored = Object.keys(value).filter((key)=>!pluginKeys.includes(key));
|
|
29
|
+
if (0 === ignored.length) return;
|
|
30
|
+
warnOnceInDev(`${name}:mixed`, `\`${name}\` contains plugin-level options (${pluginLevel.join(', ')}) together with other keys (${ignored.join(', ')}). The whole object is passed to the plugin, so the other keys are ignored. Move loader options under \`${loaderOptionsKey}\`.`);
|
|
31
|
+
};
|
|
32
|
+
const normalizeLessOptions = (less)=>{
|
|
33
|
+
if (isPluginLevelOptions(less, LESS_PLUGIN_KEYS)) {
|
|
34
|
+
warnIgnoredKeys('tools.less', less, LESS_PLUGIN_KEYS, 'lessLoaderOptions');
|
|
35
|
+
return less;
|
|
36
|
+
}
|
|
37
|
+
if (void 0 !== less && !isEmptyObject(less)) warnOnceInDev('tools.less', "`tools.less` now accepts the full options of @rsbuild/plugin-less. Passing less-loader options directly is deprecated and will stop working in the next major version. Move them under `lessLoaderOptions`:\n before: tools: { less: { lessOptions: { javascriptEnabled: true } } }\n after: tools: { less: { lessLoaderOptions: { lessOptions: { javascriptEnabled: true } } } }");
|
|
38
|
+
return {
|
|
39
|
+
lessLoaderOptions: less
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const normalizeSassOptions = (sass)=>{
|
|
43
|
+
if (isPluginLevelOptions(sass, SASS_PLUGIN_KEYS)) {
|
|
44
|
+
warnIgnoredKeys('tools.sass', sass, SASS_PLUGIN_KEYS, 'sassLoaderOptions');
|
|
45
|
+
return sass;
|
|
46
|
+
}
|
|
47
|
+
if (void 0 !== sass && !isEmptyObject(sass)) warnOnceInDev('tools.sass', "`tools.sass` now accepts the full options of @rsbuild/plugin-sass. Passing sass-loader options directly is deprecated and will stop working in the next major version. Move them under `sassLoaderOptions`:\n before: tools: { sass: { sassOptions: { quietDeps: true } } }\n after: tools: { sass: { sassLoaderOptions: { sassOptions: { quietDeps: true } } } }");
|
|
48
|
+
return {
|
|
49
|
+
sassLoaderOptions: sass
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
const mergeSvgrOptions = (target, source)=>{
|
|
53
|
+
const svgrOptions = source.svgrOptions ? {
|
|
54
|
+
...target.svgrOptions,
|
|
55
|
+
...source.svgrOptions
|
|
56
|
+
} : target.svgrOptions;
|
|
57
|
+
return Object.assign(target, source, {
|
|
58
|
+
svgrOptions
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
const resolveSvgrOptions = ({ svgr, disableSvgr, svgDefaultExport })=>{
|
|
62
|
+
if (void 0 !== disableSvgr) warnOnceInDev('output.disableSvgr', disableSvgr ? '`output.disableSvgr` is deprecated and will be removed in the next major version. Use `tools: { svgr: false }` instead.' : '`output.disableSvgr` is deprecated and will be removed in the next major version. SVGR is enabled by default, so `output.disableSvgr: false` can be removed (or use `tools: { svgr: {} }` to keep it explicit).');
|
|
63
|
+
if (void 0 !== svgDefaultExport) warnOnceInDev('output.svgDefaultExport', "`output.svgDefaultExport` is deprecated and will be removed in the next major version. Use `tools.svgr.svgrOptions.exportType` instead:\n before: output: { svgDefaultExport: 'component' }\n after: tools: { svgr: { svgrOptions: { exportType: 'default' } } }\n ('url' maps to exportType: 'named')");
|
|
64
|
+
if (false === svgr) return false;
|
|
65
|
+
if (void 0 === svgr && disableSvgr) return false;
|
|
66
|
+
const defaults = {
|
|
67
|
+
mixedImport: true,
|
|
68
|
+
parallel: true,
|
|
69
|
+
svgrOptions: {
|
|
70
|
+
exportType: 'component' === svgDefaultExport ? 'default' : 'named'
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return applyOptionsChain(defaults, svgr, void 0, mergeSvgrOptions);
|
|
74
|
+
};
|
|
75
|
+
export { normalizeLessOptions, normalizeSassOptions, resetPluginOptionsWarnings, resolveSvgrOptions };
|
package/dist/esm/shared/tsgo.mjs
CHANGED
|
@@ -5,7 +5,6 @@ import node_path from "node:path";
|
|
|
5
5
|
import { json5 } from "@modern-js/utils";
|
|
6
6
|
const builderRequire = createRequire(import.meta.url);
|
|
7
7
|
const STABLE_TSGO_PACKAGE = "typescript/package.json";
|
|
8
|
-
const NATIVE_PREVIEW_TSGO_PACKAGE = "@typescript/native-preview/package.json";
|
|
9
8
|
const TSGO_CHECKER_DIR = node_path.join('.modern-js', 'tsgo');
|
|
10
9
|
const tryResolve = (request, rootPath)=>{
|
|
11
10
|
try {
|
|
@@ -18,25 +17,11 @@ const tryResolve = (request, rootPath)=>{
|
|
|
18
17
|
return;
|
|
19
18
|
}
|
|
20
19
|
};
|
|
21
|
-
const readPackageMajorVersion = (packageJsonPath)=>{
|
|
22
|
-
try {
|
|
23
|
-
const packageJson = JSON.parse(node_fs.readFileSync(packageJsonPath, 'utf8'));
|
|
24
|
-
const major = Number.parseInt(String(packageJson.version).split('.')[0], 10);
|
|
25
|
-
return Number.isFinite(major) ? major : void 0;
|
|
26
|
-
} catch {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
20
|
const resolveTsgoPackagePath = (rootPath)=>{
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
return builderRequire.resolve(NATIVE_PREVIEW_TSGO_PACKAGE);
|
|
37
|
-
} catch {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
21
|
+
const packageJsonPath = tryResolve(STABLE_TSGO_PACKAGE, rootPath) ?? builderRequire.resolve(STABLE_TSGO_PACKAGE);
|
|
22
|
+
const packageJson = JSON.parse(node_fs.readFileSync(packageJsonPath, 'utf8'));
|
|
23
|
+
if ("typescript" !== packageJson.name || '7.0.2' !== packageJson.version) throw new Error(`The native type checker requires typescript@7.0.2; found ${String(packageJson.name)}@${String(packageJson.version)} at ${packageJsonPath}.`);
|
|
24
|
+
return packageJsonPath;
|
|
40
25
|
};
|
|
41
26
|
const toPosixPath = (input)=>input.replaceAll(node_path.sep, '/');
|
|
42
27
|
const asTsConfigPath = (request)=>{
|
|
@@ -137,7 +122,7 @@ const createTsgoCheckerConfig = (configFile, checkerConfigFile = defaultTsgoChec
|
|
|
137
122
|
};
|
|
138
123
|
const declaredRootDir = tsConfig.compilerOptions?.rootDir;
|
|
139
124
|
if ('string' == typeof declaredRootDir) compilerOptions.rootDir = toPosixPath(declaredRootDir);
|
|
140
|
-
else
|
|
125
|
+
else compilerOptions.rootDir = toPosixPath(configDirectory);
|
|
141
126
|
const moduleResolution = String(tsConfig.compilerOptions?.moduleResolution).toLowerCase();
|
|
142
127
|
if ([
|
|
143
128
|
'node',
|
|
@@ -201,19 +186,13 @@ const withTsgoDefaults = (userOptions, rootPath)=>{
|
|
|
201
186
|
] : [];
|
|
202
187
|
return [
|
|
203
188
|
{
|
|
204
|
-
typescript:
|
|
189
|
+
typescript: {
|
|
205
190
|
tsgo: true,
|
|
206
191
|
typescriptPath: tsgoPath
|
|
207
|
-
} : {
|
|
208
|
-
tsgo: true
|
|
209
192
|
}
|
|
210
193
|
},
|
|
211
194
|
...userChain,
|
|
212
|
-
(config)=>
|
|
213
|
-
const { typescript } = config;
|
|
214
|
-
if (typescript?.tsgo === false && typescript.typescriptPath === tsgoPath) typescript.typescriptPath = tryResolve("typescript", rootPath);
|
|
215
|
-
return normalizeTsgoConfig(config, rootPath);
|
|
216
|
-
}
|
|
195
|
+
(config)=>normalizeTsgoConfig(config, rootPath)
|
|
217
196
|
];
|
|
218
197
|
};
|
|
219
198
|
export { refreshTsgoCheckerConfig, withTsgoDefaults };
|
|
@@ -57,14 +57,15 @@ const pluginEnvironmentDefaults = (distPath = {})=>({
|
|
|
57
57
|
});
|
|
58
58
|
api.modifyBundlerChain(async (chain, { environment })=>{
|
|
59
59
|
const isServiceWorker = environment.name === SERVICE_WORKER_ENVIRONMENT_NAME;
|
|
60
|
-
if (isServiceWorker
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
if (isServiceWorker) {
|
|
61
|
+
const library = chain.output.get('library');
|
|
62
|
+
chain.output.library({
|
|
63
|
+
...'string' == typeof library || Array.isArray(library) ? {
|
|
64
|
+
name: library
|
|
65
|
+
} : library,
|
|
66
|
+
type: true === chain.output.get('module') ? 'module' : 'commonjs2'
|
|
67
|
+
});
|
|
68
|
+
}
|
|
68
69
|
});
|
|
69
70
|
}
|
|
70
71
|
});
|
|
@@ -9,7 +9,9 @@ const pluginManifest = ()=>({
|
|
|
9
9
|
chain.plugin(CHAIN_ID.PLUGIN.MANIFEST).use(RspackManifestPlugin, [
|
|
10
10
|
{
|
|
11
11
|
fileName: 'web' === target ? 'asset-manifest.json' : `asset-manifest-${target}.json`,
|
|
12
|
-
publicPath
|
|
12
|
+
...'string' == typeof publicPath ? {
|
|
13
|
+
publicPath
|
|
14
|
+
} : {},
|
|
13
15
|
generate: generateManifest
|
|
14
16
|
}
|
|
15
17
|
]);
|
|
@@ -7,19 +7,26 @@ var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(imp
|
|
|
7
7
|
const ASYNC_STORAGE_PATTERN = /universal[/\\]async_storage/;
|
|
8
8
|
const SERVER_LOADER_ENTRY_PATTERN = /[/\\](?:server-loader-combined|route-server-loaders)\.js$/;
|
|
9
9
|
const RENDER_RSC_SOURCE_PATTERN = /render[/\\].*[/\\]server[/\\]rsc/;
|
|
10
|
-
const RENDER_RSC_RSLIB_ENTRY_PATTERN = /render[/\\]dist[/\\]esm[/\\]rsc(
|
|
11
|
-
const RENDER_RSC_RUNTIME = '@modern-js/render/rsc';
|
|
12
|
-
const RENDER_RSC_WORKER_RUNTIME = '@modern-js/render/rsc-worker';
|
|
10
|
+
const RENDER_RSC_RSLIB_ENTRY_PATTERN = /render[/\\]dist[/\\]esm[/\\]rsc(?:\.edge)?\.mjs$/;
|
|
13
11
|
const RSC_COMMON_LAYER = 'rsc-common';
|
|
14
12
|
const ENTRY_NAME_VAR = '__MODERN_JS_ENTRY_NAME';
|
|
15
13
|
const ROUTE_DATA_FILE_PATTERN = /[/\\]routes[/\\](?:.*[/\\])?(?:layout|page|\$)\.(?:loader|data)\.[tj]sx?(?:\?.*)?$/;
|
|
16
14
|
const createVirtualModule = (content)=>`data:text/javascript,${encodeURIComponent(content)}`;
|
|
15
|
+
const resolveRscEnvironments = (environments)=>{
|
|
16
|
+
const resolved = {
|
|
17
|
+
server: environments?.server ?? 'server',
|
|
18
|
+
client: environments?.client ?? 'client'
|
|
19
|
+
};
|
|
20
|
+
for (const [role, name] of Object.entries(resolved))if ('string' != typeof name || !name.trim()) throw new TypeError(`RSC ${role} environment must have a nonempty name`);
|
|
21
|
+
return resolved;
|
|
22
|
+
};
|
|
17
23
|
const isAsyncStorageExclude = (exclude)=>{
|
|
18
24
|
if ('string' == typeof exclude) return ASYNC_STORAGE_PATTERN.test(exclude);
|
|
19
25
|
if (exclude instanceof RegExp) return exclude.test('universal/async_storage') || exclude.test('universal\\async_storage');
|
|
20
26
|
return false;
|
|
21
27
|
};
|
|
22
|
-
function pluginRscConfig() {
|
|
28
|
+
function pluginRscConfig(environments, rscLayerMatchers = []) {
|
|
29
|
+
const serverEnvironment = resolveRscEnvironments(environments).server;
|
|
23
30
|
return {
|
|
24
31
|
name: 'builder:rsc-config',
|
|
25
32
|
setup (api) {
|
|
@@ -32,9 +39,8 @@ function pluginRscConfig() {
|
|
|
32
39
|
return layersCache;
|
|
33
40
|
};
|
|
34
41
|
api.modifyBundlerChain({
|
|
35
|
-
handler: (chain, { isServer })=>{
|
|
36
|
-
if (isServer) {
|
|
37
|
-
chain.resolve.alias.set(`${RENDER_RSC_RUNTIME}$`, RENDER_RSC_WORKER_RUNTIME);
|
|
42
|
+
handler: (chain, { isServer, environment })=>{
|
|
43
|
+
if (isServer || environment.name === serverEnvironment) {
|
|
38
44
|
let emptyModulePath;
|
|
39
45
|
try {
|
|
40
46
|
emptyModulePath = require.resolve('../shared/rsc/rscEmptyModule');
|
|
@@ -57,9 +63,25 @@ function pluginRscConfig() {
|
|
|
57
63
|
order: 'pre'
|
|
58
64
|
});
|
|
59
65
|
api.modifyRspackConfig(async (config, utils)=>{
|
|
60
|
-
const isServer = 'node' === config.target || 'node' === utils.target || utils.environment?.name ===
|
|
66
|
+
const isServer = 'node' === config.target || 'node' === utils.target || utils.environment?.name === serverEnvironment;
|
|
61
67
|
if (!isServer) return;
|
|
62
68
|
const Layers = await getLayers();
|
|
69
|
+
if (utils.environment?.name !== serverEnvironment && rscLayerMatchers.length > 0) {
|
|
70
|
+
config.module ??= {};
|
|
71
|
+
config.module.rules ??= [];
|
|
72
|
+
config.module.rules.push({
|
|
73
|
+
test: rscLayerMatchers,
|
|
74
|
+
layer: Layers.rsc
|
|
75
|
+
}, {
|
|
76
|
+
issuerLayer: Layers.rsc,
|
|
77
|
+
resolve: {
|
|
78
|
+
conditionNames: [
|
|
79
|
+
'react-server',
|
|
80
|
+
'...'
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
63
85
|
if (config.entry) {
|
|
64
86
|
const entries = config.entry;
|
|
65
87
|
const newEntries = {};
|
|
@@ -96,8 +118,8 @@ function pluginRscConfig() {
|
|
|
96
118
|
});
|
|
97
119
|
}
|
|
98
120
|
});
|
|
99
|
-
api.modifyBundlerChain((chain, { isServer, isWebWorker })=>{
|
|
100
|
-
if (!isServer && !isWebWorker) {
|
|
121
|
+
api.modifyBundlerChain((chain, { isServer, isWebWorker, environment })=>{
|
|
122
|
+
if (!isServer && !isWebWorker && environment.name !== serverEnvironment) {
|
|
101
123
|
const entries = chain.entryPoints.entries();
|
|
102
124
|
if (entries && 'object' == typeof entries) for (const entryName of Object.keys(entries)){
|
|
103
125
|
const entryPoint = chain.entry(entryName);
|
|
@@ -111,13 +133,12 @@ function pluginRscConfig() {
|
|
|
111
133
|
}
|
|
112
134
|
async function getRscPlugins(enableRsc, internalDirectory, environments) {
|
|
113
135
|
if (enableRsc) {
|
|
136
|
+
const rscEnvironments = resolveRscEnvironments(environments);
|
|
114
137
|
const rscLayerMatchers = createRscLayerMatchers(internalDirectory);
|
|
115
138
|
const { pluginRSC } = await import("rsbuild-plugin-rsc");
|
|
116
139
|
return [
|
|
117
140
|
pluginRSC({
|
|
118
|
-
|
|
119
|
-
environments
|
|
120
|
-
} : {},
|
|
141
|
+
environments: rscEnvironments,
|
|
121
142
|
layers: {
|
|
122
143
|
ssr: SERVER_LOADER_ENTRY_PATTERN,
|
|
123
144
|
rsc: [
|
|
@@ -128,7 +149,7 @@ async function getRscPlugins(enableRsc, internalDirectory, environments) {
|
|
|
128
149
|
]
|
|
129
150
|
}
|
|
130
151
|
}),
|
|
131
|
-
pluginRscConfig()
|
|
152
|
+
pluginRscConfig(rscEnvironments, rscLayerMatchers)
|
|
132
153
|
];
|
|
133
154
|
}
|
|
134
155
|
return [];
|
|
@@ -2,7 +2,6 @@ import "node:module";
|
|
|
2
2
|
import { mergeRsbuildConfig } from "@rsbuild/core";
|
|
3
3
|
import { pluginCssMinimizer } from "@rsbuild/plugin-css-minimizer";
|
|
4
4
|
import { pluginLess } from "@rsbuild/plugin-less";
|
|
5
|
-
import { pluginReact } from "@rsbuild/plugin-react";
|
|
6
5
|
import { pluginSass } from "@rsbuild/plugin-sass";
|
|
7
6
|
import { pluginDevtool } from "../plugins/devtools.mjs";
|
|
8
7
|
import { pluginEmitRouteFile } from "../plugins/emitRouteFile.mjs";
|
|
@@ -11,8 +10,9 @@ import { pluginGlobalVars } from "../plugins/globalVars.mjs";
|
|
|
11
10
|
import { pluginHtmlMinifierTerser } from "../plugins/htmlMinify.mjs";
|
|
12
11
|
import { pluginRuntimeChunk } from "../plugins/runtimeChunk.mjs";
|
|
13
12
|
import { transformToRsbuildServerOptions } from "./devServer.mjs";
|
|
13
|
+
import { normalizeLessOptions, normalizeSassOptions, resolveSvgrOptions } from "./pluginOptions.mjs";
|
|
14
14
|
import { withTsgoDefaults } from "./tsgo.mjs";
|
|
15
|
-
import { NODE_MODULES_REGEX } from "./utils.mjs";
|
|
15
|
+
import { NODE_MODULES_REGEX, SERVICE_WORKER_ENVIRONMENT_NAME } from "./utils.mjs";
|
|
16
16
|
const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
|
|
17
17
|
const GLOBAL_CSS_REGEX = /\.global\.\w+$/;
|
|
18
18
|
const DEFAULT_CSS_MINIFIER_OPTIONS = {
|
|
@@ -38,7 +38,7 @@ function removeUndefinedKey(obj) {
|
|
|
38
38
|
}
|
|
39
39
|
async function parseCommonConfig(builderConfig, options) {
|
|
40
40
|
const frameworkConfigPath = options?.frameworkConfigPath;
|
|
41
|
-
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
41
|
+
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, svgr, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
42
42
|
let combinedAlias;
|
|
43
43
|
if (alias || resolve.alias) combinedAlias = [].concat(alias ?? []).concat(resolve.alias ?? []);
|
|
44
44
|
const rsbuildConfig = {
|
|
@@ -121,12 +121,8 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
121
121
|
sourceMap
|
|
122
122
|
}),
|
|
123
123
|
pluginEmitRouteFile(),
|
|
124
|
-
pluginSass(
|
|
125
|
-
|
|
126
|
-
}),
|
|
127
|
-
pluginLess({
|
|
128
|
-
lessLoaderOptions: less
|
|
129
|
-
}),
|
|
124
|
+
pluginSass(normalizeSassOptions(sass)),
|
|
125
|
+
pluginLess(normalizeLessOptions(less)),
|
|
130
126
|
pluginEnvironmentDefaults(distPath),
|
|
131
127
|
pluginHtmlMinifierTerser()
|
|
132
128
|
];
|
|
@@ -153,19 +149,44 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
153
149
|
const { pluginSourceBuild } = await import("@rsbuild/plugin-source-build");
|
|
154
150
|
rsbuildPlugins.push(pluginSourceBuild(true === sourceBuild ? {} : sourceBuild));
|
|
155
151
|
}
|
|
156
|
-
rsbuildPlugins.push(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
152
|
+
rsbuildPlugins.push({
|
|
153
|
+
name: 'rsbuild:react',
|
|
154
|
+
async setup (api) {
|
|
155
|
+
const { pluginReact } = await import("@rsbuild/plugin-react");
|
|
156
|
+
return pluginReact().setup(api);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
if (!options?.disableReactCompiler && void 0 !== reactCompiler) rsbuildPlugins.push({
|
|
160
|
+
name: 'builder:react-compiler',
|
|
161
|
+
setup (api) {
|
|
162
|
+
api.modifyEnvironmentConfig((config, { name, mergeEnvironmentConfig })=>'web' === config.output.target && name !== SERVICE_WORKER_ENVIRONMENT_NAME ? mergeEnvironmentConfig({
|
|
163
|
+
tools: {
|
|
164
|
+
swc: {
|
|
165
|
+
jsc: {
|
|
166
|
+
transform: {
|
|
167
|
+
reactCompiler
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}, config) : config);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
const svgrOptions = resolveSvgrOptions({
|
|
176
|
+
svgr,
|
|
177
|
+
disableSvgr,
|
|
178
|
+
svgDefaultExport
|
|
179
|
+
});
|
|
180
|
+
if (false !== svgrOptions) rsbuildPlugins.push({
|
|
181
|
+
name: 'rsbuild:svgr',
|
|
182
|
+
pre: [
|
|
183
|
+
'rsbuild:react'
|
|
184
|
+
],
|
|
185
|
+
async setup (api) {
|
|
186
|
+
const { pluginSvgr } = await import("@rsbuild/plugin-svgr");
|
|
187
|
+
await pluginSvgr(svgrOptions).setup(api);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
169
190
|
if (assetsRetry) {
|
|
170
191
|
const { pluginAssetsRetry } = await import("@rsbuild/plugin-assets-retry");
|
|
171
192
|
rsbuildPlugins.push(pluginAssetsRetry(assetsRetry));
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { applyOptionsChain, isDevCommand, logger } from "@modern-js/utils";
|
|
3
|
+
const LESS_PLUGIN_KEYS = [
|
|
4
|
+
'lessLoaderOptions',
|
|
5
|
+
'include',
|
|
6
|
+
'exclude',
|
|
7
|
+
'parallel'
|
|
8
|
+
];
|
|
9
|
+
const SASS_PLUGIN_KEYS = [
|
|
10
|
+
'sassLoaderOptions',
|
|
11
|
+
'include',
|
|
12
|
+
'exclude',
|
|
13
|
+
'rewriteUrls'
|
|
14
|
+
];
|
|
15
|
+
const warned = new Set();
|
|
16
|
+
const resetPluginOptionsWarnings = ()=>{
|
|
17
|
+
warned.clear();
|
|
18
|
+
};
|
|
19
|
+
const warnOnceInDev = (key, message)=>{
|
|
20
|
+
if (!isDevCommand() || warned.has(key)) return;
|
|
21
|
+
warned.add(key);
|
|
22
|
+
logger.warn(message);
|
|
23
|
+
};
|
|
24
|
+
const isPlainObject = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
|
|
25
|
+
const isPluginLevelOptions = (value, pluginKeys)=>isPlainObject(value) && pluginKeys.some((key)=>key in value);
|
|
26
|
+
const isEmptyObject = (value)=>isPlainObject(value) && 0 === Object.keys(value).length;
|
|
27
|
+
const warnIgnoredKeys = (name, value, pluginKeys, loaderOptionsKey)=>{
|
|
28
|
+
const pluginLevel = Object.keys(value).filter((key)=>pluginKeys.includes(key));
|
|
29
|
+
const ignored = Object.keys(value).filter((key)=>!pluginKeys.includes(key));
|
|
30
|
+
if (0 === ignored.length) return;
|
|
31
|
+
warnOnceInDev(`${name}:mixed`, `\`${name}\` contains plugin-level options (${pluginLevel.join(', ')}) together with other keys (${ignored.join(', ')}). The whole object is passed to the plugin, so the other keys are ignored. Move loader options under \`${loaderOptionsKey}\`.`);
|
|
32
|
+
};
|
|
33
|
+
const normalizeLessOptions = (less)=>{
|
|
34
|
+
if (isPluginLevelOptions(less, LESS_PLUGIN_KEYS)) {
|
|
35
|
+
warnIgnoredKeys('tools.less', less, LESS_PLUGIN_KEYS, 'lessLoaderOptions');
|
|
36
|
+
return less;
|
|
37
|
+
}
|
|
38
|
+
if (void 0 !== less && !isEmptyObject(less)) warnOnceInDev('tools.less', "`tools.less` now accepts the full options of @rsbuild/plugin-less. Passing less-loader options directly is deprecated and will stop working in the next major version. Move them under `lessLoaderOptions`:\n before: tools: { less: { lessOptions: { javascriptEnabled: true } } }\n after: tools: { less: { lessLoaderOptions: { lessOptions: { javascriptEnabled: true } } } }");
|
|
39
|
+
return {
|
|
40
|
+
lessLoaderOptions: less
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const normalizeSassOptions = (sass)=>{
|
|
44
|
+
if (isPluginLevelOptions(sass, SASS_PLUGIN_KEYS)) {
|
|
45
|
+
warnIgnoredKeys('tools.sass', sass, SASS_PLUGIN_KEYS, 'sassLoaderOptions');
|
|
46
|
+
return sass;
|
|
47
|
+
}
|
|
48
|
+
if (void 0 !== sass && !isEmptyObject(sass)) warnOnceInDev('tools.sass', "`tools.sass` now accepts the full options of @rsbuild/plugin-sass. Passing sass-loader options directly is deprecated and will stop working in the next major version. Move them under `sassLoaderOptions`:\n before: tools: { sass: { sassOptions: { quietDeps: true } } }\n after: tools: { sass: { sassLoaderOptions: { sassOptions: { quietDeps: true } } } }");
|
|
49
|
+
return {
|
|
50
|
+
sassLoaderOptions: sass
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const mergeSvgrOptions = (target, source)=>{
|
|
54
|
+
const svgrOptions = source.svgrOptions ? {
|
|
55
|
+
...target.svgrOptions,
|
|
56
|
+
...source.svgrOptions
|
|
57
|
+
} : target.svgrOptions;
|
|
58
|
+
return Object.assign(target, source, {
|
|
59
|
+
svgrOptions
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const resolveSvgrOptions = ({ svgr, disableSvgr, svgDefaultExport })=>{
|
|
63
|
+
if (void 0 !== disableSvgr) warnOnceInDev('output.disableSvgr', disableSvgr ? '`output.disableSvgr` is deprecated and will be removed in the next major version. Use `tools: { svgr: false }` instead.' : '`output.disableSvgr` is deprecated and will be removed in the next major version. SVGR is enabled by default, so `output.disableSvgr: false` can be removed (or use `tools: { svgr: {} }` to keep it explicit).');
|
|
64
|
+
if (void 0 !== svgDefaultExport) warnOnceInDev('output.svgDefaultExport', "`output.svgDefaultExport` is deprecated and will be removed in the next major version. Use `tools.svgr.svgrOptions.exportType` instead:\n before: output: { svgDefaultExport: 'component' }\n after: tools: { svgr: { svgrOptions: { exportType: 'default' } } }\n ('url' maps to exportType: 'named')");
|
|
65
|
+
if (false === svgr) return false;
|
|
66
|
+
if (void 0 === svgr && disableSvgr) return false;
|
|
67
|
+
const defaults = {
|
|
68
|
+
mixedImport: true,
|
|
69
|
+
parallel: true,
|
|
70
|
+
svgrOptions: {
|
|
71
|
+
exportType: 'component' === svgDefaultExport ? 'default' : 'named'
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
return applyOptionsChain(defaults, svgr, void 0, mergeSvgrOptions);
|
|
75
|
+
};
|
|
76
|
+
export { normalizeLessOptions, normalizeSassOptions, resetPluginOptionsWarnings, resolveSvgrOptions };
|
|
@@ -6,7 +6,6 @@ import node_path from "node:path";
|
|
|
6
6
|
import { json5 } from "@modern-js/utils";
|
|
7
7
|
const builderRequire = createRequire(import.meta.url);
|
|
8
8
|
const STABLE_TSGO_PACKAGE = "typescript/package.json";
|
|
9
|
-
const NATIVE_PREVIEW_TSGO_PACKAGE = "@typescript/native-preview/package.json";
|
|
10
9
|
const TSGO_CHECKER_DIR = node_path.join('.modern-js', 'tsgo');
|
|
11
10
|
const tryResolve = (request, rootPath)=>{
|
|
12
11
|
try {
|
|
@@ -19,25 +18,11 @@ const tryResolve = (request, rootPath)=>{
|
|
|
19
18
|
return;
|
|
20
19
|
}
|
|
21
20
|
};
|
|
22
|
-
const readPackageMajorVersion = (packageJsonPath)=>{
|
|
23
|
-
try {
|
|
24
|
-
const packageJson = JSON.parse(node_fs.readFileSync(packageJsonPath, 'utf8'));
|
|
25
|
-
const major = Number.parseInt(String(packageJson.version).split('.')[0], 10);
|
|
26
|
-
return Number.isFinite(major) ? major : void 0;
|
|
27
|
-
} catch {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
21
|
const resolveTsgoPackagePath = (rootPath)=>{
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
return builderRequire.resolve(NATIVE_PREVIEW_TSGO_PACKAGE);
|
|
38
|
-
} catch {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
22
|
+
const packageJsonPath = tryResolve(STABLE_TSGO_PACKAGE, rootPath) ?? builderRequire.resolve(STABLE_TSGO_PACKAGE);
|
|
23
|
+
const packageJson = JSON.parse(node_fs.readFileSync(packageJsonPath, 'utf8'));
|
|
24
|
+
if ("typescript" !== packageJson.name || '7.0.2' !== packageJson.version) throw new Error(`The native type checker requires typescript@7.0.2; found ${String(packageJson.name)}@${String(packageJson.version)} at ${packageJsonPath}.`);
|
|
25
|
+
return packageJsonPath;
|
|
41
26
|
};
|
|
42
27
|
const toPosixPath = (input)=>input.replaceAll(node_path.sep, '/');
|
|
43
28
|
const asTsConfigPath = (request)=>{
|
|
@@ -138,7 +123,7 @@ const createTsgoCheckerConfig = (configFile, checkerConfigFile = defaultTsgoChec
|
|
|
138
123
|
};
|
|
139
124
|
const declaredRootDir = tsConfig.compilerOptions?.rootDir;
|
|
140
125
|
if ('string' == typeof declaredRootDir) compilerOptions.rootDir = toPosixPath(declaredRootDir);
|
|
141
|
-
else
|
|
126
|
+
else compilerOptions.rootDir = toPosixPath(configDirectory);
|
|
142
127
|
const moduleResolution = String(tsConfig.compilerOptions?.moduleResolution).toLowerCase();
|
|
143
128
|
if ([
|
|
144
129
|
'node',
|
|
@@ -202,19 +187,13 @@ const withTsgoDefaults = (userOptions, rootPath)=>{
|
|
|
202
187
|
] : [];
|
|
203
188
|
return [
|
|
204
189
|
{
|
|
205
|
-
typescript:
|
|
190
|
+
typescript: {
|
|
206
191
|
tsgo: true,
|
|
207
192
|
typescriptPath: tsgoPath
|
|
208
|
-
} : {
|
|
209
|
-
tsgo: true
|
|
210
193
|
}
|
|
211
194
|
},
|
|
212
195
|
...userChain,
|
|
213
|
-
(config)=>
|
|
214
|
-
const { typescript } = config;
|
|
215
|
-
if (typescript?.tsgo === false && typescript.typescriptPath === tsgoPath) typescript.typescriptPath = tryResolve("typescript", rootPath);
|
|
216
|
-
return normalizeTsgoConfig(config, rootPath);
|
|
217
|
-
}
|
|
196
|
+
(config)=>normalizeTsgoConfig(config, rootPath)
|
|
218
197
|
];
|
|
219
198
|
};
|
|
220
199
|
export { refreshTsgoCheckerConfig, withTsgoDefaults };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export { type ChainIdentifier, type ConfigChain, logger, type NormalizedConfig,
|
|
|
4
4
|
export { parseConfig as parseRspackConfig } from './createBuilder.js';
|
|
5
5
|
export { refreshTsgoCheckerConfig } from './shared/tsgo.js';
|
|
6
6
|
export { castArray, isHtmlDisabled, RUNTIME_CHUNK_NAME, RUNTIME_CHUNK_REGEX, SERVICE_WORKER_ENVIRONMENT_NAME, } from './shared/utils.js';
|
|
7
|
-
export type { BuilderConfig, BundlerType, CacheGroup, MetaOptions, MultiStats, RspackConfig, Stats, ToolsDevServerConfig, } from './types.js';
|
|
7
|
+
export type { BuilderConfig, BuilderSvgOptions, BundlerType, CacheGroup, MetaOptions, MultiStats, RspackConfig, Stats, ToolsDevServerConfig, } from './types.js';
|
|
8
8
|
export type { BuilderInstance, CreateBuilderOptions };
|
|
9
9
|
export { createRspackBuilder as createBuilder };
|