Skip to content

Commit 1c8a0d8

Browse files
committed
refactor: load config
1 parent 79f500c commit 1c8a0d8

File tree

10 files changed

+134
-115
lines changed

10 files changed

+134
-115
lines changed

packages/core/src/cli/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { LogLevel, RsbuildMode, RsbuildPlugin } from '@rsbuild/core';
22
import cac, { type CAC } from 'cac';
3-
import type { ConfigLoader } from '../config';
3+
import type { ConfigLoader } from '../loadConfig';
44
import type { Format, Syntax } from '../types';
55
import { color } from '../utils/color';
66
import { logger } from '../utils/logger';

packages/core/src/cli/initConfig.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'node:path';
22
import util from 'node:util';
33
import { loadEnv, type RsbuildEntry } from '@rsbuild/core';
4-
import { loadConfig } from '../config';
4+
import { loadConfig } from '../loadConfig';
55
import type {
66
LibConfig,
77
RsbuildConfigOutputTarget,
@@ -107,7 +107,7 @@ export const applyCliOptions = (
107107

108108
export async function initConfig(options: CommonOptions): Promise<{
109109
config: RslibConfig;
110-
configFilePath?: string;
110+
configFilePath: string | null;
111111
watchFiles: string[];
112112
}> {
113113
const cwd = process.cwd();
@@ -126,7 +126,7 @@ export async function initConfig(options: CommonOptions): Promise<{
126126
loader: options.configLoader,
127127
});
128128

129-
if (configFilePath === undefined) {
129+
if (configFilePath === null) {
130130
config.lib = [{} satisfies LibConfig];
131131
logger.debug(
132132
'No config file found. Falling back to CLI options for the default library.',

packages/core/src/config.ts

Lines changed: 1 addition & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import fs from 'node:fs';
2-
import path, { dirname, extname, isAbsolute, join } from 'node:path';
2+
import path, { dirname, extname, join } from 'node:path';
33
import {
44
defineConfig as defineRsbuildConfig,
55
type EnvironmentConfig,
6-
loadConfig as loadRsbuildConfig,
76
mergeRsbuildConfig,
87
type RsbuildConfig,
98
type RsbuildEntry,
@@ -16,8 +15,6 @@ import {
1615
import { glob } from 'tinyglobby';
1716
import { composeAssetConfig } from './asset/assetConfig';
1817
import {
19-
DEFAULT_CONFIG_EXTENSIONS,
20-
DEFAULT_CONFIG_NAME,
2118
DTS_EXTENSIONS_PATTERN,
2219
JS_EXTENSIONS_PATTERN,
2320
SWC_HELPERS,
@@ -50,9 +47,6 @@ import type {
5047
RsbuildConfigOutputTarget,
5148
RsbuildConfigWithLibInfo,
5249
RslibConfig,
53-
RslibConfigAsyncFn,
54-
RslibConfigExport,
55-
RslibConfigSyncFn,
5650
RspackResolver,
5751
Shims,
5852
Syntax,
@@ -81,81 +75,6 @@ import {
8175
} from './utils/syntax';
8276
import { loadTsconfig } from './utils/tsconfig';
8377

84-
/**
85-
* This function helps you to autocomplete configuration types.
86-
* It accepts a Rslib config object, or a function that returns a config.
87-
*/
88-
export function defineConfig(config: RslibConfig): RslibConfig;
89-
export function defineConfig(config: RslibConfigSyncFn): RslibConfigSyncFn;
90-
export function defineConfig(config: RslibConfigAsyncFn): RslibConfigAsyncFn;
91-
export function defineConfig(config: RslibConfigExport): RslibConfigExport;
92-
export function defineConfig(config: RslibConfigExport) {
93-
return config;
94-
}
95-
96-
const findConfig = (basePath: string): string | undefined => {
97-
return DEFAULT_CONFIG_EXTENSIONS.map((ext) => basePath + ext).find(
98-
fs.existsSync,
99-
);
100-
};
101-
102-
const resolveConfigPath = (
103-
root: string,
104-
customConfig?: string,
105-
): string | undefined => {
106-
if (customConfig) {
107-
const customConfigPath = isAbsolute(customConfig)
108-
? customConfig
109-
: join(root, customConfig);
110-
if (fs.existsSync(customConfigPath)) {
111-
return customConfigPath;
112-
}
113-
logger.warn(`Cannot find config file: ${color.dim(customConfigPath)}\n`);
114-
}
115-
116-
const configFilePath = findConfig(join(root, DEFAULT_CONFIG_NAME));
117-
118-
if (configFilePath) {
119-
return configFilePath;
120-
}
121-
return undefined;
122-
};
123-
124-
export type ConfigLoader = 'auto' | 'jiti' | 'native';
125-
126-
export async function loadConfig({
127-
cwd = process.cwd(),
128-
path,
129-
envMode,
130-
loader,
131-
}: {
132-
cwd?: string;
133-
path?: string;
134-
envMode?: string;
135-
loader?: ConfigLoader;
136-
}): Promise<{
137-
content: RslibConfig;
138-
filePath?: string;
139-
}> {
140-
const configFilePath = resolveConfigPath(cwd, path);
141-
if (!configFilePath) {
142-
return {
143-
content: {
144-
lib: [],
145-
},
146-
filePath: undefined,
147-
};
148-
}
149-
const { content } = await loadRsbuildConfig({
150-
cwd: dirname(configFilePath),
151-
path: configFilePath,
152-
envMode,
153-
loader,
154-
});
155-
156-
return { content: content as RslibConfig, filePath: configFilePath };
157-
}
158-
15978
// Match logic is derived from https://github.com/webpack/webpack/blob/94aba382eccf3de1004d235045d4462918dfdbb7/lib/ExternalModuleFactoryPlugin.js#L89-L158
16079
const handleMatchedExternal = (
16180
value: string | string[] | boolean | Record<string, string | string[]>,

packages/core/src/constant.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
1-
export const DEFAULT_CONFIG_NAME = 'rslib.config';
2-
3-
export const DEFAULT_CONFIG_EXTENSIONS = [
4-
'.js',
5-
'.ts',
6-
'.mjs',
7-
'.mts',
8-
'.cjs',
9-
'.cts',
10-
] as const;
11-
121
export const SWC_HELPERS = '@swc/helpers';
132

143
const DTS_EXTENSIONS: string[] = ['d.ts', 'd.mts', 'd.cts'];

packages/core/src/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ export { runCLI } from './cli';
77
export { build } from './cli/build';
88
export { inspect } from './cli/inspect';
99
export { startMFDevServer } from './cli/mf';
10+
export { composeCreateRsbuildConfig as unstable_composeCreateRsbuildConfig } from './config';
1011
export {
11-
composeCreateRsbuildConfig as unstable_composeCreateRsbuildConfig,
12+
type ConfigParams,
1213
defineConfig,
14+
type LoadConfigOptions,
15+
type LoadConfigResult,
1316
loadConfig,
14-
} from './config';
17+
} from './loadConfig';
18+
1519
export type * from './types';
1620
export { logger } from './utils/logger';
1721

packages/core/src/loadConfig.ts

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import fs from 'node:fs';
2+
import { dirname, isAbsolute, join } from 'node:path';
3+
import {
4+
loadConfig as loadRsbuildConfig,
5+
type LoadConfigOptions as RsbuildLoadConfigOptions,
6+
} from '@rsbuild/core';
7+
import type { RslibConfig } from './types';
8+
import { color } from './utils/color';
9+
import { logger } from './utils/logger';
10+
11+
export type ConfigParams = {
12+
env: string;
13+
command: string;
14+
envMode?: string;
15+
meta?: Record<string, unknown>;
16+
};
17+
18+
export type RslibConfigSyncFn = (env: ConfigParams) => RslibConfig;
19+
20+
export type RslibConfigAsyncFn = (env: ConfigParams) => Promise<RslibConfig>;
21+
22+
export type RslibConfigExport =
23+
| RslibConfig
24+
| RslibConfigSyncFn
25+
| RslibConfigAsyncFn;
26+
27+
export type LoadConfigOptions = Pick<
28+
RsbuildLoadConfigOptions,
29+
'cwd' | 'path' | 'envMode' | 'meta' | 'loader'
30+
>;
31+
32+
export type ConfigLoader = RsbuildLoadConfigOptions['loader'];
33+
34+
export type LoadConfigResult = {
35+
/**
36+
* The loaded configuration object.
37+
*/
38+
content: RslibConfig;
39+
/**
40+
* The path to the loaded configuration file.
41+
* Return `null` if the configuration file is not found.
42+
*/
43+
filePath: string | null;
44+
};
45+
46+
/**
47+
* This function helps you to autocomplete configuration types.
48+
* It accepts a Rslib config object, or a function that returns a config.
49+
*/
50+
export function defineConfig(config: RslibConfig): RslibConfig;
51+
export function defineConfig(config: RslibConfigSyncFn): RslibConfigSyncFn;
52+
export function defineConfig(config: RslibConfigAsyncFn): RslibConfigAsyncFn;
53+
export function defineConfig(config: RslibConfigExport): RslibConfigExport;
54+
export function defineConfig(config: RslibConfigExport) {
55+
return config;
56+
}
57+
58+
const resolveConfigPath = (
59+
root: string,
60+
customConfig?: string,
61+
): string | null => {
62+
if (customConfig) {
63+
const customConfigPath = isAbsolute(customConfig)
64+
? customConfig
65+
: join(root, customConfig);
66+
if (fs.existsSync(customConfigPath)) {
67+
return customConfigPath;
68+
}
69+
logger.warn(`Cannot find config file: ${color.dim(customConfigPath)}\n`);
70+
}
71+
72+
const CONFIG_FILES = [
73+
// `.mjs` and `.ts` are the most used configuration types,
74+
// so we resolve them first for performance
75+
'rslib.config.mjs',
76+
'rslib.config.ts',
77+
'rslib.config.js',
78+
'rslib.config.cjs',
79+
'rslib.config.mts',
80+
'rslib.config.cts',
81+
];
82+
83+
for (const file of CONFIG_FILES) {
84+
const configFile = join(root, file);
85+
86+
if (fs.existsSync(configFile)) {
87+
return configFile;
88+
}
89+
}
90+
91+
return null;
92+
};
93+
94+
export async function loadConfig({
95+
cwd = process.cwd(),
96+
path,
97+
envMode,
98+
meta,
99+
loader,
100+
}: LoadConfigOptions): Promise<LoadConfigResult> {
101+
const configFilePath = resolveConfigPath(cwd, path);
102+
103+
if (!configFilePath) {
104+
logger.debug('no config file found.');
105+
return {
106+
content: {} as RslibConfig,
107+
filePath: null,
108+
};
109+
}
110+
111+
const { content } = await loadRsbuildConfig({
112+
cwd: dirname(configFilePath),
113+
path: configFilePath,
114+
envMode,
115+
meta,
116+
loader,
117+
});
118+
119+
return { content: content as RslibConfig, filePath: configFilePath };
120+
}

packages/core/src/types/config.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -390,16 +390,3 @@ export interface RslibConfig extends RsbuildConfig {
390390
*/
391391
output?: RslibOutputConfig;
392392
}
393-
394-
export type ConfigParams = {
395-
env: string;
396-
command: string;
397-
envMode?: string;
398-
};
399-
400-
export type RslibConfigSyncFn = (env: ConfigParams) => RslibConfig;
401-
export type RslibConfigAsyncFn = (env: ConfigParams) => Promise<RslibConfig>;
402-
export type RslibConfigExport =
403-
| RslibConfig
404-
| RslibConfigSyncFn
405-
| RslibConfigAsyncFn;

packages/core/tests/config.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import { initConfig } from '../src/cli/initConfig';
77
import {
88
composeCreateRsbuildConfig,
99
composeRsbuildEnvironments,
10-
loadConfig,
1110
} from '../src/config';
11+
import { loadConfig } from '../src/loadConfig';
1212
import type { RslibConfig } from '../src/types/config';
1313

1414
rs.mock('rslog');

packages/core/tests/fixtures/config/cjs/rslib.config.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { defineConfig } = require('../../../../../core/src/config');
1+
const { defineConfig } = require('../../../../../core/src/loadConfig');
22

33
module.exports = defineConfig((_args) => ({
44
lib: [],

packages/core/tests/fixtures/config/esm/rslib.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { defineConfig } from '../../../../../core/src/config';
1+
import { defineConfig } from '../../../../../core/src/loadConfig';
22

33
export default defineConfig((_args) => ({
44
lib: [],

0 commit comments

Comments
 (0)