@rsbuild/core 2.1.2 → 2.1.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.
- package/dist/756.js +107 -74
- package/dist/fresh-import.js +90 -0
- package/dist-types/cli/commands.d.ts +2 -1
- package/dist-types/cli/index.d.ts +7 -1
- package/dist-types/cli/init.d.ts +3 -2
- package/dist-types/configChain.d.ts +3 -0
- package/dist-types/index.d.ts +2 -2
- package/dist-types/loadConfig.d.ts +15 -3
- package/dist-types/plugins/fileSize.d.ts +1 -1
- package/dist-types/types/config.d.ts +1 -1
- package/package.json +2 -1
package/dist/756.js
CHANGED
|
@@ -3500,7 +3500,7 @@ function createPublicContext(context) {
|
|
|
3500
3500
|
async function createContext(options, userConfig, logger) {
|
|
3501
3501
|
let { cwd } = options, rootPath = userConfig.root ? ensureAbsolutePath(cwd, userConfig.root) : cwd, rsbuildConfig = await withDefaultConfig(rootPath, userConfig), cachePath = join(rootPath, 'node_modules', '.cache'), specifiedEnvironments = options.environment && options.environment.length > 0 ? options.environment : void 0;
|
|
3502
3502
|
return {
|
|
3503
|
-
version: "2.1.
|
|
3503
|
+
version: "2.1.3",
|
|
3504
3504
|
rootPath,
|
|
3505
3505
|
distPath: '',
|
|
3506
3506
|
cachePath,
|
|
@@ -3778,12 +3778,15 @@ let configChain_CHAIN_ID = {
|
|
|
3778
3778
|
JS_MAIN: 'js',
|
|
3779
3779
|
JS_WORKER: 'js-worker',
|
|
3780
3780
|
JS_RAW: 'js-raw',
|
|
3781
|
+
JS_TEXT: 'js-text',
|
|
3781
3782
|
CSS_MAIN: 'css',
|
|
3782
3783
|
CSS_RAW: 'css-raw',
|
|
3784
|
+
CSS_TEXT: 'css-text',
|
|
3783
3785
|
CSS_URL: 'css-url',
|
|
3784
3786
|
CSS_INLINE: 'css-inline',
|
|
3785
3787
|
SVG: 'svg',
|
|
3786
3788
|
SVG_RAW: 'svg-asset-raw',
|
|
3789
|
+
SVG_TEXT: 'svg-asset-text',
|
|
3787
3790
|
SVG_URL: 'svg-asset-url',
|
|
3788
3791
|
SVG_ASSET: 'svg-asset',
|
|
3789
3792
|
SVG_REACT: 'svg-react',
|
|
@@ -4817,7 +4820,9 @@ let chainStaticAssetRule = ({ emit, rule, maxSize, filename, assetType })=>{
|
|
|
4817
4820
|
let generatorOptions = {
|
|
4818
4821
|
filename
|
|
4819
4822
|
};
|
|
4820
|
-
emit || (generatorOptions.emit = !1), rule.oneOf(`${assetType}-asset-url`).type('asset/resource').resourceQuery(URL_QUERY_REGEX).set('generator', generatorOptions), rule.oneOf(`${assetType}-asset-inline`).type('asset/inline').resourceQuery(INLINE_QUERY_REGEX), rule.oneOf(`${assetType}-asset-
|
|
4823
|
+
emit || (generatorOptions.emit = !1), rule.oneOf(`${assetType}-asset-url`).type('asset/resource').resourceQuery(URL_QUERY_REGEX).set('generator', generatorOptions), rule.oneOf(`${assetType}-asset-inline`).type('asset/inline').resourceQuery(INLINE_QUERY_REGEX), rule.oneOf(`${assetType}-asset-text`).type('asset/source').with({
|
|
4824
|
+
type: 'text'
|
|
4825
|
+
}), rule.oneOf(`${assetType}-asset-raw`).type('asset/source').resourceQuery(RAW_QUERY_REGEX), rule.oneOf(`${assetType}-asset`).type('asset').parser({
|
|
4821
4826
|
dataUrlCondition: {
|
|
4822
4827
|
maxSize
|
|
4823
4828
|
}
|
|
@@ -5150,7 +5155,7 @@ async function saveSnapshots(snapshotPath, snapshots, logger) {
|
|
|
5150
5155
|
logger.debug('Failed to save file size snapshots:', err);
|
|
5151
5156
|
}
|
|
5152
5157
|
}
|
|
5153
|
-
let EXCLUDE_ASSET_REGEX = /\.(?:map|LICENSE\.txt|d\.ts)$/, isSignificantDiff = (diff)=>Math.abs(diff) >= 10, formatDiff = (diff)=>{
|
|
5158
|
+
let EXCLUDE_ASSET_REGEX = /\.(?:map|LICENSE\.txt|d\.(?:ts|mts|cts))$/, isSignificantDiff = (diff)=>Math.abs(diff) >= 10, formatDiff = (diff)=>{
|
|
5154
5159
|
let label = `(${diff > 0 ? '+' : '-'}${calcFileSize(Math.abs(diff))})`;
|
|
5155
5160
|
return {
|
|
5156
5161
|
label: (diff > 0 ? color.red : color.green)(label),
|
|
@@ -5175,7 +5180,7 @@ function getHeader(maxFileLength, maxSizeLength, fileHeader, showGzipHeader) {
|
|
|
5175
5180
|
let calcFileSize = (len)=>{
|
|
5176
5181
|
let val = len / 1000;
|
|
5177
5182
|
return `${val.toFixed(val < 1 ? 2 : 1)} kB`;
|
|
5178
|
-
}, COMPRESSIBLE_REGEX = /\.(?:js|css|html|json|svg|txt|xml|xhtml|wasm|manifest|md)$/i, isCompressible = (assetName)=>COMPRESSIBLE_REGEX.test(assetName), getFilePath = (assetName)=>{
|
|
5183
|
+
}, COMPRESSIBLE_REGEX = /\.(?:js|mjs|cjs|jsx|ts|tsx|mts|cts|css|html|json|svg|txt|xml|xhtml|wasm|manifest|md)$/i, isCompressible = (assetName)=>COMPRESSIBLE_REGEX.test(assetName), getFilePath = (assetName)=>{
|
|
5179
5184
|
let queryIndex = assetName.indexOf('?');
|
|
5180
5185
|
return -1 === queryIndex ? assetName : assetName.slice(0, queryIndex);
|
|
5181
5186
|
};
|
|
@@ -5823,7 +5828,8 @@ let supportedChromiumBrowsers = [
|
|
|
5823
5828
|
'Microsoft Edge',
|
|
5824
5829
|
'Brave Browser',
|
|
5825
5830
|
'Vivaldi',
|
|
5826
|
-
'Chromium'
|
|
5831
|
+
'Chromium',
|
|
5832
|
+
'Helium'
|
|
5827
5833
|
], mapChromiumBrowserName = (browser)=>'chrome' === browser || 'google chrome' === browser ? 'Google Chrome' : browser;
|
|
5828
5834
|
async function openBrowser(url, logger) {
|
|
5829
5835
|
let browser = process.env.BROWSER, browserArgs = process.env.BROWSER_ARGS;
|
|
@@ -8736,7 +8742,11 @@ function applyDefaultPlugins(pluginManager, context) {
|
|
|
8736
8742
|
], emitAssets), createAssetRule(configChain_CHAIN_ID.RULE.MEDIA, [
|
|
8737
8743
|
...VIDEO_EXTENSIONS,
|
|
8738
8744
|
...AUDIO_EXTENSIONS
|
|
8739
|
-
], emitAssets), createAssetRule(configChain_CHAIN_ID.RULE.FONT, FONT_EXTENSIONS, emitAssets)
|
|
8745
|
+
], emitAssets), createAssetRule(configChain_CHAIN_ID.RULE.FONT, FONT_EXTENSIONS, emitAssets);
|
|
8746
|
+
let rule = chain.module.rule(configChain_CHAIN_ID.RULE.JSON).test(/\.json$/i);
|
|
8747
|
+
rule.oneOf('json-asset-text').type('asset/source').with({
|
|
8748
|
+
type: 'text'
|
|
8749
|
+
}), rule.oneOf('json-asset-raw').type('asset/source').resourceQuery(RAW_QUERY_REGEX);
|
|
8740
8750
|
let assetsFilename = getMergedFilename('assets');
|
|
8741
8751
|
chain.output.assetModuleFilename(assetsFilename), emitAssets || chain.module.generator.merge({
|
|
8742
8752
|
'asset/resource': {
|
|
@@ -9034,7 +9044,9 @@ try {
|
|
|
9034
9044
|
let cssRule = chain.module.rule(CHAIN_ID.RULE.CSS), { config } = environment;
|
|
9035
9045
|
cssRule.test(CSS_REGEX).dependency({
|
|
9036
9046
|
not: 'url'
|
|
9037
|
-
})
|
|
9047
|
+
}), cssRule.oneOf(CHAIN_ID.ONE_OF.CSS_TEXT).with({
|
|
9048
|
+
type: 'text'
|
|
9049
|
+
}).type('asset/source');
|
|
9038
9050
|
let urlRule = cssRule.oneOf(CHAIN_ID.ONE_OF.CSS_URL).resourceQuery(URL_QUERY_REGEX);
|
|
9039
9051
|
urlRule.use(CHAIN_ID.USE.CSS_URL).loader(node_path.join(dirname, 'cssUrlLoader.mjs'));
|
|
9040
9052
|
let inlineRule = cssRule.oneOf(CHAIN_ID.ONE_OF.CSS_INLINE).resourceQuery(INLINE_QUERY_REGEX);
|
|
@@ -9194,7 +9206,9 @@ try {
|
|
|
9194
9206
|
let { config, browserslist } = environment, cacheRoot = node_path.join(api.context.cachePath, '.swc'), rule = chain.module.rule(CHAIN_ID.RULE.JS).test(SCRIPT_REGEX).dependency({
|
|
9195
9207
|
not: 'url'
|
|
9196
9208
|
});
|
|
9197
|
-
rule.oneOf(CHAIN_ID.ONE_OF.
|
|
9209
|
+
rule.oneOf(CHAIN_ID.ONE_OF.JS_TEXT).with({
|
|
9210
|
+
type: 'text'
|
|
9211
|
+
}).type('asset/source'), rule.oneOf(CHAIN_ID.ONE_OF.JS_RAW).resourceQuery(RAW_QUERY_REGEX).type('asset/source');
|
|
9198
9212
|
let mainRule = rule.oneOf(CHAIN_ID.ONE_OF.JS_MAIN).type("javascript/auto"), dataUriRule = chain.module.rule(CHAIN_ID.RULE.JS_DATA_URI).mimetype({
|
|
9199
9213
|
or: [
|
|
9200
9214
|
"text/javascript",
|
|
@@ -9853,36 +9867,53 @@ async function createRsbuild(options = {}) {
|
|
|
9853
9867
|
function defineConfig(config) {
|
|
9854
9868
|
return config;
|
|
9855
9869
|
}
|
|
9856
|
-
|
|
9857
|
-
|
|
9870
|
+
let DEFAULT_CONFIG_FILE_NAMES = [
|
|
9871
|
+
'rsbuild.config.ts',
|
|
9872
|
+
'rsbuild.config.js',
|
|
9873
|
+
'rsbuild.config.mts',
|
|
9874
|
+
'rsbuild.config.mjs',
|
|
9875
|
+
'rsbuild.config.cts',
|
|
9876
|
+
'rsbuild.config.cjs'
|
|
9877
|
+
], getConfigExport = (module)=>module && 'object' == typeof module && 'default' in module ? module.default : module, tryFreshImport = async (configFileURL)=>{
|
|
9878
|
+
try {
|
|
9879
|
+
let { freshImport } = await import("./fresh-import.js");
|
|
9880
|
+
return await freshImport(configFileURL);
|
|
9881
|
+
} catch (err) {
|
|
9882
|
+
src_logger.debug('failed to initialize fresh-import, fallback to dynamic import.'), src_logger.debug(err);
|
|
9883
|
+
}
|
|
9884
|
+
}, loadConfigWithNative = async (configFilePath)=>{
|
|
9885
|
+
let configFileURL = pathToFileURL(configFilePath).href, freshImportResult = await tryFreshImport(configFileURL);
|
|
9886
|
+
return freshImportResult ? {
|
|
9887
|
+
configExport: getConfigExport(freshImportResult.result),
|
|
9888
|
+
dependencies: freshImportResult.dependencies.sort()
|
|
9889
|
+
} : {
|
|
9890
|
+
configExport: getConfigExport(await import(`${configFileURL}?t=${Date.now()}`)),
|
|
9891
|
+
dependencies: []
|
|
9892
|
+
};
|
|
9893
|
+
};
|
|
9894
|
+
async function loadConfig_loadConfig({ cwd = process.cwd(), path, configFileNames, envMode, meta, loader = 'auto', command } = {}) {
|
|
9895
|
+
let configExport, configFilePath = ((root, customConfig, configFileNames = DEFAULT_CONFIG_FILE_NAMES)=>{
|
|
9858
9896
|
if (customConfig) {
|
|
9859
9897
|
let customConfigPath = external_node_path_isAbsolute(customConfig) ? customConfig : join(root, customConfig);
|
|
9860
9898
|
if (node_fs.existsSync(customConfigPath)) return customConfigPath;
|
|
9861
9899
|
throw Error(`Cannot find config file: ${color.dim(customConfigPath)}`);
|
|
9862
9900
|
}
|
|
9863
|
-
for (let file of
|
|
9864
|
-
'rsbuild.config.ts',
|
|
9865
|
-
'rsbuild.config.js',
|
|
9866
|
-
'rsbuild.config.mts',
|
|
9867
|
-
'rsbuild.config.mjs',
|
|
9868
|
-
'rsbuild.config.cts',
|
|
9869
|
-
'rsbuild.config.cjs'
|
|
9870
|
-
]){
|
|
9901
|
+
for (let file of configFileNames){
|
|
9871
9902
|
let configFile = join(root, file);
|
|
9872
9903
|
if (node_fs.existsSync(configFile)) return configFile;
|
|
9873
9904
|
}
|
|
9874
9905
|
return null;
|
|
9875
|
-
})(cwd, path);
|
|
9906
|
+
})(cwd, path, configFileNames);
|
|
9876
9907
|
if (!configFilePath) return src_logger.debug('no config file found.'), {
|
|
9877
9908
|
content: {},
|
|
9878
|
-
filePath: configFilePath
|
|
9909
|
+
filePath: configFilePath,
|
|
9910
|
+
dependencies: []
|
|
9879
9911
|
};
|
|
9880
|
-
let applyMetaInfo = (config)=>(config._privateMeta = {
|
|
9912
|
+
let dependencies = [], applyMetaInfo = (config)=>(config._privateMeta = {
|
|
9881
9913
|
configFilePath
|
|
9882
9914
|
}, config);
|
|
9883
9915
|
if ('native' === loader || 'auto' === loader && (process.features.typescript || process.versions.bun || process.versions.deno) || /\.(?:js|mjs|cjs)$/.test(configFilePath)) try {
|
|
9884
|
-
|
|
9885
|
-
configExport = exportModule.default ? exportModule.default : exportModule;
|
|
9916
|
+
({ configExport, dependencies } = await loadConfigWithNative(configFilePath));
|
|
9886
9917
|
} catch (err) {
|
|
9887
9918
|
let errorMessage = `Failed to load file with native loader: ${color.dim(configFilePath)}`;
|
|
9888
9919
|
if ('native' === loader) throw src_logger.error(errorMessage), err;
|
|
@@ -9903,66 +9934,75 @@ async function loadConfig_loadConfig({ cwd = process.cwd(), path, envMode, meta,
|
|
|
9903
9934
|
throw src_logger.error(`Failed to load file with jiti: ${color.dim(configFilePath)}`), err;
|
|
9904
9935
|
}
|
|
9905
9936
|
if ('function' == typeof configExport) {
|
|
9906
|
-
let
|
|
9937
|
+
let nodeEnv = process.env.NODE_ENV || '', configParams = {
|
|
9907
9938
|
env: nodeEnv,
|
|
9908
|
-
command,
|
|
9939
|
+
command: command ?? process.argv[2],
|
|
9909
9940
|
envMode: envMode || nodeEnv,
|
|
9910
9941
|
meta
|
|
9911
|
-
});
|
|
9942
|
+
}, result = await configExport(configParams);
|
|
9912
9943
|
if (void 0 === result) throw Error(`${color.dim('[rsbuild:loadConfig]')} The config function must return a config object.`);
|
|
9913
9944
|
return {
|
|
9914
9945
|
content: applyMetaInfo(result),
|
|
9915
|
-
filePath: configFilePath
|
|
9946
|
+
filePath: configFilePath,
|
|
9947
|
+
dependencies
|
|
9916
9948
|
};
|
|
9917
9949
|
}
|
|
9918
9950
|
if (!isObject(configExport)) throw Error(`${color.dim('[rsbuild:loadConfig]')} The config must be an object or a function that returns an object, get ${color.yellow(configExport)}`);
|
|
9919
9951
|
return src_logger.debug('configuration loaded from:', configFilePath), {
|
|
9920
9952
|
content: applyMetaInfo(configExport),
|
|
9921
|
-
filePath: configFilePath
|
|
9953
|
+
filePath: configFilePath,
|
|
9954
|
+
dependencies
|
|
9922
9955
|
};
|
|
9923
9956
|
}
|
|
9924
|
-
let
|
|
9925
|
-
|
|
9957
|
+
let cliState = {
|
|
9958
|
+
options: {}
|
|
9959
|
+
}, initCliAction = (command, options)=>{
|
|
9960
|
+
process.env.NODE_ENV || (process.env.NODE_ENV = 'build' === command || 'preview' === command ? 'production' : 'development'), options.environment?.some((env)=>env.includes(',')) && (options.environment = options.environment.flatMap((env)=>env.split(','))), cliState.command = command, cliState.options = options;
|
|
9961
|
+
}, init_loadConfig = async (root)=>{
|
|
9962
|
+
let { options, command } = cliState, { content: config, filePath, dependencies } = await loadConfig_loadConfig({
|
|
9926
9963
|
cwd: root,
|
|
9927
|
-
path:
|
|
9928
|
-
envMode:
|
|
9929
|
-
loader:
|
|
9964
|
+
path: options.config,
|
|
9965
|
+
envMode: options.envMode,
|
|
9966
|
+
loader: options.configLoader,
|
|
9967
|
+
command
|
|
9930
9968
|
});
|
|
9931
|
-
if (config.dev ||= {}, config.source ||= {}, config.server ||= {},
|
|
9969
|
+
if (config.dev ||= {}, config.source ||= {}, config.server ||= {}, options.base && (config.server.base = options.base), options.root && (config.root = root), options.mode && (config.mode = options.mode), options.logLevel && (config.logLevel = options.logLevel), options.open && !config.server?.open && (config.server.open = options.open), void 0 !== options.host && (config.server.host = options.host), options.port && (config.server.port = options.port), void 0 !== options.strictPort && (config.server.strictPort = options.strictPort), void 0 !== options.distPath) {
|
|
9932
9970
|
config.output ||= {};
|
|
9933
9971
|
let { distPath } = config.output;
|
|
9934
9972
|
config.output.distPath = distPath && 'object' == typeof distPath ? {
|
|
9935
9973
|
...distPath,
|
|
9936
|
-
root:
|
|
9974
|
+
root: options.distPath
|
|
9937
9975
|
} : {
|
|
9938
|
-
root:
|
|
9976
|
+
root: options.distPath
|
|
9939
9977
|
};
|
|
9940
9978
|
}
|
|
9941
|
-
if (void 0 !==
|
|
9942
|
-
let sourceMap =
|
|
9979
|
+
if (void 0 !== options.sourceMap) {
|
|
9980
|
+
let sourceMap = options.sourceMap;
|
|
9943
9981
|
if ('boolean' != typeof sourceMap) throw Error('The "--source-map" option only accepts a boolean value.');
|
|
9944
9982
|
config.output ||= {}, config.output.sourceMap = sourceMap;
|
|
9945
9983
|
}
|
|
9946
9984
|
return void 0 === config.dev.cliShortcuts && (config.dev.cliShortcuts = !0), filePath && (config.dev.watchFiles = [
|
|
9947
9985
|
...config.dev.watchFiles ? helpers_castArray(config.dev.watchFiles) : [],
|
|
9948
9986
|
{
|
|
9949
|
-
paths:
|
|
9987
|
+
paths: [
|
|
9988
|
+
filePath,
|
|
9989
|
+
...dependencies
|
|
9990
|
+
],
|
|
9950
9991
|
type: 'reload-server'
|
|
9951
9992
|
}
|
|
9952
9993
|
]), config;
|
|
9953
9994
|
};
|
|
9954
|
-
async function init_init({
|
|
9955
|
-
|
|
9956
|
-
let logger = src_logger;
|
|
9995
|
+
async function init_init({ isRestart, isBuildWatch = !1 } = {}) {
|
|
9996
|
+
let logger = src_logger, { options } = cliState;
|
|
9957
9997
|
try {
|
|
9958
9998
|
var envDir;
|
|
9959
|
-
let cwd = process.cwd(), root =
|
|
9999
|
+
let cwd = process.cwd(), root = options.root ? ensureAbsolutePath(cwd, options.root) : cwd, rsbuild = await createRsbuild({
|
|
9960
10000
|
cwd: root,
|
|
9961
10001
|
config: ()=>init_loadConfig(root),
|
|
9962
|
-
environment:
|
|
9963
|
-
loadEnv: !1 !==
|
|
9964
|
-
cwd: (envDir =
|
|
9965
|
-
mode:
|
|
10002
|
+
environment: options.environment,
|
|
10003
|
+
loadEnv: !1 !== options.env && {
|
|
10004
|
+
cwd: (envDir = options.envDir) ? node_path.isAbsolute(envDir) ? envDir : node_path.join(root, envDir) : root,
|
|
10005
|
+
mode: options.envMode
|
|
9966
10006
|
}
|
|
9967
10007
|
});
|
|
9968
10008
|
return logger = rsbuild.logger, rsbuild.onBeforeCreateCompiler(()=>{
|
|
@@ -10042,11 +10082,11 @@ async function watchFilesForRestart({ files, rsbuild, isBuildWatch, watchOptions
|
|
|
10042
10082
|
watcher.on('add', onChange), watcher.on('change', onChange), watcher.on('unlink', onChange);
|
|
10043
10083
|
}
|
|
10044
10084
|
let applyServerOptions = (command)=>{
|
|
10045
|
-
command.option('-o, --open [url]', 'Open the page in browser on startup').option('--port <port>', 'Set the port number for the server').option('--host [host]', 'Set the host that the server listens to');
|
|
10085
|
+
command.option('-o, --open [url]', 'Open the page in browser on startup').option('--port <port>', 'Set the port number for the server').option('--strict-port', 'Exit if the specified port is already in use').option('--host [host]', 'Set the host that the server listens to');
|
|
10046
10086
|
};
|
|
10047
|
-
function setupCommands() {
|
|
10087
|
+
function setupCommands(argv) {
|
|
10048
10088
|
let cli = ((name = "")=>new CAC(name))('rsbuild');
|
|
10049
|
-
cli.version("2.1.
|
|
10089
|
+
cli.version("2.1.3"), cli.option('--base <base>', 'Set the base path of the server').option('-c, --config <config>', 'Set the configuration file (relative or absolute path)').option('--config-loader <loader>', 'Set the config file loader (auto | jiti | native)', {
|
|
10050
10090
|
default: 'auto'
|
|
10051
10091
|
}).option('--dist-path <dir>', 'Set the root directory of output files').option('--source-map', 'Enable source map').option('--env-dir <dir>', 'Set the directory for loading `.env` files').option('--env-mode <mode>', 'Set the env mode to load the `.env.[mode]` file').option('--environment <name>', 'Set the environment name(s) to build', {
|
|
10052
10092
|
type: [
|
|
@@ -10058,20 +10098,19 @@ function setupCommands() {
|
|
|
10058
10098
|
applyServerOptions(devCommand), applyServerOptions(previewCommand);
|
|
10059
10099
|
let logger = src_logger;
|
|
10060
10100
|
devCommand.action(async (options)=>{
|
|
10101
|
+
initCliAction('dev', options);
|
|
10061
10102
|
try {
|
|
10062
|
-
let rsbuild = await init_init(
|
|
10063
|
-
cliOptions: options
|
|
10064
|
-
});
|
|
10103
|
+
let rsbuild = await init_init();
|
|
10065
10104
|
if (!rsbuild) return;
|
|
10066
10105
|
logger = rsbuild.logger, await rsbuild.startDevServer();
|
|
10067
10106
|
} catch (err) {
|
|
10068
10107
|
logger.error('Failed to start dev server.'), logger.error(err), process.exit(1);
|
|
10069
10108
|
}
|
|
10070
10109
|
}), buildCommand.option('-w, --watch', 'Enable watch mode to automatically rebuild on file changes').action(async (options)=>{
|
|
10110
|
+
initCliAction('build', options);
|
|
10071
10111
|
try {
|
|
10072
10112
|
options.watch || (process.env.RSPACK_UNSAFE_FAST_DROP = 'true');
|
|
10073
10113
|
let rsbuild = await init_init({
|
|
10074
|
-
cliOptions: options,
|
|
10075
10114
|
isBuildWatch: options.watch
|
|
10076
10115
|
});
|
|
10077
10116
|
if (!rsbuild) return;
|
|
@@ -10084,20 +10123,18 @@ function setupCommands() {
|
|
|
10084
10123
|
err instanceof Error && err.message === RSPACK_BUILD_ERROR || logger.error('Failed to build.'), logger.error(err), process.exit(1);
|
|
10085
10124
|
}
|
|
10086
10125
|
}), previewCommand.action(async (options)=>{
|
|
10126
|
+
initCliAction('preview', options);
|
|
10087
10127
|
try {
|
|
10088
|
-
let rsbuild = await init_init(
|
|
10089
|
-
cliOptions: options
|
|
10090
|
-
});
|
|
10128
|
+
let rsbuild = await init_init();
|
|
10091
10129
|
if (!rsbuild) return;
|
|
10092
10130
|
logger = rsbuild.logger, await rsbuild.preview();
|
|
10093
10131
|
} catch (err) {
|
|
10094
10132
|
logger.error('Failed to start preview server.'), logger.error(err), process.exit(1);
|
|
10095
10133
|
}
|
|
10096
10134
|
}), inspectCommand.option('--output <output>', 'Set the output path for inspection results').option('--verbose', 'Show complete function definitions in output').action(async (options)=>{
|
|
10135
|
+
initCliAction('inspect', options);
|
|
10097
10136
|
try {
|
|
10098
|
-
let rsbuild = await init_init(
|
|
10099
|
-
cliOptions: options
|
|
10100
|
-
});
|
|
10137
|
+
let rsbuild = await init_init();
|
|
10101
10138
|
if (!rsbuild) return;
|
|
10102
10139
|
logger = rsbuild.logger, await rsbuild.inspectConfig({
|
|
10103
10140
|
verbose: options.verbose,
|
|
@@ -10109,21 +10146,17 @@ function setupCommands() {
|
|
|
10109
10146
|
}
|
|
10110
10147
|
}), cli.help((sections)=>{
|
|
10111
10148
|
for (let section of (sections.shift(), sections))'Usage' === section.title && (section.body = section.body.replace('$ rsbuild', color.yellow("$ rsbuild [command] [options]"))), 'Commands' === section.title && (section.body = section.body.replace(` ${devDescription}`, `dev ${devDescription}`)), section.title?.startsWith('For more info') ? (section.title = color.dim(' For details on a sub-command, run'), section.body = color.dim(' $ rsbuild <command> -h')) : section.title && (section.title = color.cyan(section.title));
|
|
10112
|
-
}), cli.parse();
|
|
10113
|
-
}
|
|
10114
|
-
let { argv: cli_argv } = process;
|
|
10115
|
-
function initNodeEnv(command) {
|
|
10116
|
-
process.env.NODE_ENV || (process.env.NODE_ENV = 'build' === command || 'preview' === command ? 'production' : 'development');
|
|
10149
|
+
}), cli.parse(argv);
|
|
10117
10150
|
}
|
|
10118
10151
|
function showGreeting() {
|
|
10119
10152
|
let { npm_execpath, npm_lifecycle_event, NODE_RUN_SCRIPT_NAME } = process.env, isBun = npm_execpath?.includes('.bun');
|
|
10120
|
-
src_logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v2.1.
|
|
10153
|
+
src_logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v2.1.3\n`);
|
|
10121
10154
|
}
|
|
10122
|
-
function setupLogLevel() {
|
|
10123
|
-
if (
|
|
10124
|
-
let logLevelIndex =
|
|
10155
|
+
function setupLogLevel(argv) {
|
|
10156
|
+
if (argv.length <= 3) return;
|
|
10157
|
+
let logLevelIndex = argv.findIndex((item)=>'--log-level' === item || '--logLevel' === item);
|
|
10125
10158
|
if (-1 !== logLevelIndex) {
|
|
10126
|
-
let level =
|
|
10159
|
+
let level = argv[logLevelIndex + 1];
|
|
10127
10160
|
level && [
|
|
10128
10161
|
'warn',
|
|
10129
10162
|
'error',
|
|
@@ -10131,13 +10164,13 @@ function setupLogLevel() {
|
|
|
10131
10164
|
].includes(level) && !isDebug() && (src_logger.level = level);
|
|
10132
10165
|
}
|
|
10133
10166
|
}
|
|
10134
|
-
function runCLI() {
|
|
10135
|
-
|
|
10167
|
+
function runCLI({ argv = process.argv } = {}) {
|
|
10168
|
+
setupLogLevel(argv), showGreeting();
|
|
10136
10169
|
try {
|
|
10137
|
-
setupCommands();
|
|
10170
|
+
setupCommands(argv);
|
|
10138
10171
|
} catch (err) {
|
|
10139
10172
|
src_logger.error('Failed to start Rsbuild CLI.'), src_logger.error(err), process.exit(1);
|
|
10140
10173
|
}
|
|
10141
10174
|
}
|
|
10142
|
-
let src_version = "2.1.
|
|
10175
|
+
let src_version = "2.1.3";
|
|
10143
10176
|
export { PLUGIN_CSS_NAME, PLUGIN_SWC_NAME, core_rspack as rspack, createRsbuild, defaultAllowedOrigins, defineConfig, ensureAssetPrefix, loadConfig_loadConfig as loadConfig, loadEnv, logger_createLogger as createLogger, mergeRsbuildConfig, mrmime_lookup, runCLI, src_logger as logger, src_version as version };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
let importer;
|
|
2
|
+
import { Module } from "node:module";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { MessageChannel } from "node:worker_threads";
|
|
5
|
+
let instanceId = Math.random().toString(36).slice(2), relativeImportRE = /^\.{1,2}(?:\/|\\)/;
|
|
6
|
+
function escapeRegExp(value) {
|
|
7
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8
|
+
}
|
|
9
|
+
function buildQueryName() {
|
|
10
|
+
return `fresh-import-${instanceId}`;
|
|
11
|
+
}
|
|
12
|
+
function buildQueryRE(queryName) {
|
|
13
|
+
return RegExp(`(?:\\?|&)${escapeRegExp(queryName)}=(\\d+),([^&]+)(?:&|$)`);
|
|
14
|
+
}
|
|
15
|
+
function formatTrackingQuery(queryName, id, context) {
|
|
16
|
+
return `?${queryName}=${id},${context}`;
|
|
17
|
+
}
|
|
18
|
+
function trackResolved(specifier, context, result, queryName, queryRE, onDependency) {
|
|
19
|
+
let isRelativeImport = relativeImportRE.test(specifier);
|
|
20
|
+
if ("builtin" === result.format || !isRelativeImport || !context.parentURL || queryRE.test(result.url) || !result.url.startsWith("file:")) return result;
|
|
21
|
+
let m = queryRE.exec(context.parentURL);
|
|
22
|
+
if (m) {
|
|
23
|
+
let [, id, contextFile] = m;
|
|
24
|
+
onDependency(contextFile, result.url), result.url = result.url.replace(/(\?)|$/, (_n, n1)=>`?${queryName}=${id},${contextFile}${"?" === n1 ? "&" : ""}`);
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
let nextId$1 = 0;
|
|
29
|
+
function createOffThreadImporter() {
|
|
30
|
+
let queryName = buildQueryName(), { port1, port2 } = new MessageChannel();
|
|
31
|
+
return Module.register('data:text/javascript,Math.random().toString(36).slice(2);%0Aconst relativeImportRE = /^\\.{1,2}(%3F:\\/|\\\\)/;%0Afunction escapeRegExp(value) {%0A%09return value.replace(/[.*+%3F^${}()|[\\]\\\\]/g, "\\\\$&");%0A}%0A/**%0A* Build the regex that matches the tracking query `%3F<name>=<id>,<context>`%0A* (or the `&<name>=...` form).%0A*/%0Afunction buildQueryRE(queryName) {%0A%09return new RegExp(`(%3F:\\\\%3F|&)${escapeRegExp(queryName)}=(\\\\d+),([^&]+)(%3F:&|$)`);%0A}%0A/**%0A* Shared body of the resolve hook for both the on-thread and off-thread%0A* importers. Given an already-resolved `result`, decides whether it is a tracked%0A* relative file dependency; if so, reports it via `onDependency` and tags the%0A* URL so the query propagates to its own dependencies.%0A*%0A* The sync/async difference between the two hooks lives entirely in the caller%0A* (which awaits `nextResolve` or not); this function performs no I/O. `result`%0A* is mutated in place and returned.%0A*/%0Afunction trackResolved(specifier, context, result, queryName, queryRE, onDependency) {%0A%09const isRelativeImport = relativeImportRE.test(specifier);%0A%09if (result.format === "builtin" || !isRelativeImport) return result;%0A%09if (!context.parentURL || queryRE.test(result.url) || !result.url.startsWith("file:")) return result;%0A%09const m = queryRE.exec(context.parentURL);%0A%09if (m) {%0A%09%09const [, id, contextFile] = m;%0A%09%09onDependency(contextFile, result.url);%0A%09%09result.url = result.url.replace(/(\\%3F)|$/, (_n, n1) => `%3F${queryName}=${id},${contextFile}${n1 === "%3F" %3F "&" : ""}`);%0A%09}%0A%09return result;%0A}%0A//%23endregion%0A//%23region src/off-thread/loader.ts%0Alet port;%0Alet queryName;%0Alet queryRE;%0Aconst initialize = async (data) => {%0A%09port = data.port;%0A%09queryName = data.queryName;%0A%09queryRE = buildQueryRE(queryName);%0A};%0Aconst resolve = async (specifier, context, nextResolve) => {%0A%09return trackResolved(specifier, context, await nextResolve(specifier, context), queryName, queryRE, (ctx, url) => {%0A%09%09port.postMessage({%0A%09%09%09context: ctx,%0A%09%09%09url%0A%09%09});%0A%09});%0A};%0A//%23endregion%0Aexport { initialize, resolve };%0A', {
|
|
32
|
+
data: {
|
|
33
|
+
port: port2,
|
|
34
|
+
queryName
|
|
35
|
+
},
|
|
36
|
+
transferList: [
|
|
37
|
+
port2
|
|
38
|
+
]
|
|
39
|
+
}), port1.unref(), {
|
|
40
|
+
async collect (specifier) {
|
|
41
|
+
let id = nextId$1++, depsList = new Set(), onMessage = (e)=>{
|
|
42
|
+
e.context === specifier && depsList.add(e.url);
|
|
43
|
+
};
|
|
44
|
+
port1.on("message", onMessage), port1.unref();
|
|
45
|
+
try {
|
|
46
|
+
let result = await import(specifier + formatTrackingQuery(queryName, id, specifier));
|
|
47
|
+
return await new Promise((resolve)=>setImmediate(resolve)), {
|
|
48
|
+
result,
|
|
49
|
+
dependencies: [
|
|
50
|
+
...depsList
|
|
51
|
+
].filter((url)=>url.startsWith("file:")).map((url)=>fileURLToPath(url))
|
|
52
|
+
};
|
|
53
|
+
} finally{
|
|
54
|
+
port1.off("message", onMessage);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
let nextId = 0;
|
|
60
|
+
function createOnThreadImporter() {
|
|
61
|
+
let registry = new Map(), queryName = buildQueryName(), queryRE = buildQueryRE(queryName);
|
|
62
|
+
return Module.registerHooks({
|
|
63
|
+
resolve: (specifier, context, nextResolve)=>trackResolved(specifier, context, nextResolve(specifier, context), queryName, queryRE, (ctx, url)=>{
|
|
64
|
+
registry.get(ctx)?.add(url);
|
|
65
|
+
})
|
|
66
|
+
}), {
|
|
67
|
+
async collect (specifier) {
|
|
68
|
+
let id = nextId++, depsList = new Set();
|
|
69
|
+
registry.set(specifier, depsList);
|
|
70
|
+
try {
|
|
71
|
+
return {
|
|
72
|
+
result: await import(specifier + formatTrackingQuery(queryName, id, specifier)),
|
|
73
|
+
dependencies: [
|
|
74
|
+
...depsList
|
|
75
|
+
].filter((url)=>url.startsWith("file:")).map((url)=>fileURLToPath(url))
|
|
76
|
+
};
|
|
77
|
+
} finally{
|
|
78
|
+
registry.delete(specifier);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function createImporter() {
|
|
84
|
+
return Module.registerHooks ? createOnThreadImporter() : Module.register ? createOffThreadImporter() : void 0;
|
|
85
|
+
}
|
|
86
|
+
let initialized = !1;
|
|
87
|
+
function freshImport(specifier) {
|
|
88
|
+
return initialized || (importer = createImporter(), initialized = !0), importer?.collect(specifier);
|
|
89
|
+
}
|
|
90
|
+
export { freshImport };
|
|
@@ -14,6 +14,7 @@ export type CommonOptions = {
|
|
|
14
14
|
open?: boolean | string;
|
|
15
15
|
host?: true | string;
|
|
16
16
|
port?: number;
|
|
17
|
+
strictPort?: boolean;
|
|
17
18
|
environment?: string[];
|
|
18
19
|
logLevel?: LogLevel;
|
|
19
20
|
};
|
|
@@ -27,4 +28,4 @@ export type InspectOptions = CommonOptions & {
|
|
|
27
28
|
};
|
|
28
29
|
export type DevOptions = CommonOptions;
|
|
29
30
|
export type PreviewOptions = CommonOptions;
|
|
30
|
-
export declare function setupCommands(): void;
|
|
31
|
+
export declare function setupCommands(argv: string[]): void;
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type RunCLIOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* The command-line arguments to parse, matching the shape of Node.js `process.argv`
|
|
4
|
+
* @default process.argv
|
|
5
|
+
*/ argv?: string[];
|
|
6
|
+
};
|
|
7
|
+
export declare function runCLI({ argv }?: RunCLIOptions): void;
|
package/dist-types/cli/init.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { RsbuildInstance } from '../types';
|
|
2
2
|
import type { CommonOptions } from './commands';
|
|
3
|
-
export
|
|
4
|
-
|
|
3
|
+
export type CommandName = 'dev' | 'build' | 'preview' | 'inspect';
|
|
4
|
+
export declare const initCliAction: (command: CommandName, options: CommonOptions) => void;
|
|
5
|
+
export declare function init({ isRestart, isBuildWatch }?: {
|
|
5
6
|
isRestart?: boolean;
|
|
6
7
|
isBuildWatch?: boolean;
|
|
7
8
|
}): Promise<RsbuildInstance | undefined>;
|
|
@@ -24,12 +24,15 @@ export declare const CHAIN_ID: {
|
|
|
24
24
|
/** JS oneOf rules */ readonly JS_MAIN: 'js';
|
|
25
25
|
readonly JS_WORKER: 'js-worker';
|
|
26
26
|
readonly JS_RAW: 'js-raw';
|
|
27
|
+
readonly JS_TEXT: 'js-text';
|
|
27
28
|
/** CSS oneOf rules */ readonly CSS_MAIN: 'css';
|
|
28
29
|
readonly CSS_RAW: 'css-raw';
|
|
30
|
+
readonly CSS_TEXT: 'css-text';
|
|
29
31
|
readonly CSS_URL: 'css-url';
|
|
30
32
|
readonly CSS_INLINE: 'css-inline';
|
|
31
33
|
/** SVG oneOf rules */ readonly SVG: 'svg';
|
|
32
34
|
readonly SVG_RAW: 'svg-asset-raw';
|
|
35
|
+
readonly SVG_TEXT: 'svg-asset-text';
|
|
33
36
|
readonly SVG_URL: 'svg-asset-url';
|
|
34
37
|
readonly SVG_ASSET: 'svg-asset';
|
|
35
38
|
readonly SVG_REACT: 'svg-react';
|
package/dist-types/index.d.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* the public API of @rsbuild/core.
|
|
4
4
|
*/ import type * as Rspack from '@rspack/core';
|
|
5
5
|
import { rspack } from '@rspack/core';
|
|
6
|
-
export { runCLI } from './cli';
|
|
6
|
+
export { type RunCLIOptions, runCLI } from './cli';
|
|
7
7
|
export { createRsbuild } from './createRsbuild';
|
|
8
|
-
export { type ConfigParams, defineConfig, type LoadConfigOptions, type LoadConfigResult, loadConfig } from './loadConfig';
|
|
8
|
+
export { type ConfigParams, defineConfig, type LoadConfigOptions, type LoadConfigResult, type RsbuildConfigAsyncFn, type RsbuildConfigDefinition, type RsbuildConfigSyncFn, loadConfig } from './loadConfig';
|
|
9
9
|
// Core methods
|
|
10
10
|
export { type LoadEnvOptions, type LoadEnvResult, loadEnv } from './loadEnv';
|
|
11
11
|
// Rsbuild version
|
|
@@ -7,7 +7,7 @@ export type ConfigParams = {
|
|
|
7
7
|
};
|
|
8
8
|
export type RsbuildConfigAsyncFn = (env: ConfigParams) => Promise<RsbuildConfig>;
|
|
9
9
|
export type RsbuildConfigSyncFn = (env: ConfigParams) => RsbuildConfig;
|
|
10
|
-
export type
|
|
10
|
+
export type RsbuildConfigDefinition = RsbuildConfig | RsbuildConfigSyncFn | RsbuildConfigAsyncFn;
|
|
11
11
|
export type LoadConfigOptions = {
|
|
12
12
|
/**
|
|
13
13
|
* The root path to resolve the config file.
|
|
@@ -18,6 +18,10 @@ export type LoadConfigOptions = {
|
|
|
18
18
|
* If `path` is not provided, the function will search for the config file in the `cwd`.
|
|
19
19
|
*/ path?: string;
|
|
20
20
|
/**
|
|
21
|
+
* Config file names to search in `cwd` when `path` is not provided.
|
|
22
|
+
* The list replaces the default `rsbuild.config.*` lookup order.
|
|
23
|
+
*/ configFileNames?: string[];
|
|
24
|
+
/**
|
|
21
25
|
* A custom meta object to be passed into the config function of `defineConfig`.
|
|
22
26
|
*/ meta?: Record<string, unknown>;
|
|
23
27
|
/**
|
|
@@ -31,6 +35,10 @@ export type LoadConfigOptions = {
|
|
|
31
35
|
* - 'native': Use native Node.js loader, requires TypeScript support in Node.js >= 22.6
|
|
32
36
|
* @default 'auto'
|
|
33
37
|
*/ loader?: ConfigLoader;
|
|
38
|
+
/**
|
|
39
|
+
* The command passed to the config function.
|
|
40
|
+
* @default process.argv[2]
|
|
41
|
+
*/ command?: string;
|
|
34
42
|
};
|
|
35
43
|
export type LoadConfigResult = {
|
|
36
44
|
/**
|
|
@@ -40,6 +48,10 @@ export type LoadConfigResult = {
|
|
|
40
48
|
* The path to the loaded configuration file.
|
|
41
49
|
* Return `null` if the configuration file is not found.
|
|
42
50
|
*/ filePath: string | null;
|
|
51
|
+
/**
|
|
52
|
+
* Absolute file paths of statically imported (relative) dependencies of the
|
|
53
|
+
* config file.
|
|
54
|
+
*/ dependencies: string[];
|
|
43
55
|
};
|
|
44
56
|
/**
|
|
45
57
|
* This function helps you to autocomplete configuration types.
|
|
@@ -47,6 +59,6 @@ export type LoadConfigResult = {
|
|
|
47
59
|
*/ export declare function defineConfig(config: RsbuildConfig): RsbuildConfig;
|
|
48
60
|
export declare function defineConfig(config: RsbuildConfigSyncFn): RsbuildConfigSyncFn;
|
|
49
61
|
export declare function defineConfig(config: RsbuildConfigAsyncFn): RsbuildConfigAsyncFn;
|
|
50
|
-
export declare function defineConfig(config:
|
|
62
|
+
export declare function defineConfig(config: RsbuildConfigDefinition): RsbuildConfigDefinition;
|
|
51
63
|
export type ConfigLoader = 'auto' | 'jiti' | 'native';
|
|
52
|
-
export declare function loadConfig({ cwd, path, envMode, meta, loader }?: LoadConfigOptions): Promise<LoadConfigResult>;
|
|
64
|
+
export declare function loadConfig({ cwd, path, configFileNames, envMode, meta, loader, command }?: LoadConfigOptions): Promise<LoadConfigResult>;
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* license at https://github.com/facebook/create-react-app/blob/master/LICENSE
|
|
4
4
|
*/ import type { InternalContext, PrintFileSizeAsset, RsbuildPlugin } from '../types';
|
|
5
5
|
/** Normalize file path by removing hash for comparison across builds */ export declare function normalizeFilePath(filePath: string): string;
|
|
6
|
-
/** Exclude source map and
|
|
6
|
+
/** Exclude source map, license, and type declaration files by default */ export declare const excludeAsset: (asset: PrintFileSizeAsset) => boolean;
|
|
7
7
|
export declare const pluginFileSize: (context: InternalContext) => RsbuildPlugin;
|
|
@@ -516,7 +516,7 @@ export type PrintFileSizeOptions = {
|
|
|
516
516
|
/**
|
|
517
517
|
* A filter function to exclude static assets from the total size or detailed size.
|
|
518
518
|
* If both `include` and `exclude` are set, `exclude` will take precedence.
|
|
519
|
-
* @default (asset) => /\.(?:map|LICENSE\.txt)$/.test(asset.name)
|
|
519
|
+
* @default (asset) => /\.(?:map|LICENSE\.txt|d\.(?:ts|mts|cts))$/.test(asset.name)
|
|
520
520
|
*/ exclude?: (asset: PrintFileSizeAsset) => boolean;
|
|
521
521
|
/**
|
|
522
522
|
* Controls whether file size differences are displayed relative to the previous build.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsbuild/core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"description": "The Rspack-based build tool.",
|
|
5
5
|
"homepage": "https://rsbuild.rs",
|
|
6
6
|
"bugs": {
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"css-loader": "7.1.4",
|
|
62
62
|
"deepmerge": "^4.3.1",
|
|
63
63
|
"dotenv-expand": "^13.0.0",
|
|
64
|
+
"fresh-import": "^0.2.1",
|
|
64
65
|
"html-rspack-plugin": "6.1.9",
|
|
65
66
|
"http-proxy-middleware": "4.1.1",
|
|
66
67
|
"jiti": "^2.7.0",
|