Skip to content

Commit db602d2

Browse files
authored
feat: add --root cli option and make basic js api work (#453)
1 parent 9653e3a commit db602d2

File tree

16 files changed

+193
-95
lines changed

16 files changed

+193
-95
lines changed

packages/core/src/build.ts renamed to packages/core/src/cli/build.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import { type RsbuildInstance, createRsbuild } from '@rsbuild/core';
2-
import type { BuildOptions } from './cli/commands';
3-
import { composeRsbuildEnvironments, pruneEnvironments } from './config';
4-
import type { RslibConfig } from './types/config';
2+
import { composeRsbuildEnvironments, pruneEnvironments } from '../config';
3+
import type { RslibConfig } from '../types/config';
4+
import type { BuildOptions } from './commands';
55

66
export async function build(
77
config: RslibConfig,
8-
options?: BuildOptions,
8+
options: Pick<BuildOptions, 'lib' | 'watch'> = {},
99
): Promise<RsbuildInstance> {
1010
const environments = await composeRsbuildEnvironments(config);
1111
const rsbuildInstance = await createRsbuild({
1212
rsbuildConfig: {
13-
environments: pruneEnvironments(environments, options?.lib),
13+
environments: pruneEnvironments(environments, options.lib),
1414
},
1515
});
1616

1717
await rsbuildInstance.build({
18-
watch: options?.watch,
18+
watch: options.watch,
1919
});
2020

2121
return rsbuildInstance;

packages/core/src/cli/commands.ts

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import { type RsbuildMode, createRsbuild } from '@rsbuild/core';
1+
import type { RsbuildMode } from '@rsbuild/core';
22
import { type Command, program } from 'commander';
3-
import { build } from '../build';
4-
import {
5-
composeRsbuildEnvironments,
6-
loadConfig,
7-
pruneEnvironments,
8-
} from '../config';
9-
import { startMFDevServer } from '../mf';
103
import { logger } from '../utils/logger';
4+
import { build } from './build';
5+
import { loadRslibConfig } from './init';
6+
import { inspect } from './inspect';
7+
import { startMFDevServer } from './mf';
118

129
export type CommonOptions = {
10+
root?: string;
1311
config?: string;
1412
envMode?: string;
1513
lib?: string[];
@@ -20,8 +18,8 @@ export type BuildOptions = CommonOptions & {
2018
};
2119

2220
export type InspectOptions = CommonOptions & {
23-
mode: RsbuildMode;
24-
output: string;
21+
mode?: RsbuildMode;
22+
output?: string;
2523
verbose?: boolean;
2624
};
2725

@@ -31,6 +29,10 @@ const applyCommonOptions = (command: Command) => {
3129
'-c --config <config>',
3230
'specify the configuration file, can be a relative or absolute path',
3331
)
32+
.option(
33+
'-r --root <root>',
34+
'specify the project root directory, can be an absolute path or a path relative to cwd',
35+
)
3436
.option(
3537
'--env-mode <mode>',
3638
'specify the env mode to load the `.env.[mode]` file',
@@ -60,11 +62,11 @@ export function runCli(): void {
6062
.description('build the library for production')
6163
.action(async (options: BuildOptions) => {
6264
try {
63-
const rslibConfig = await loadConfig({
64-
path: options.config,
65-
envMode: options.envMode,
65+
const rslibConfig = await loadRslibConfig(options);
66+
await build(rslibConfig, {
67+
lib: options.lib,
68+
watch: options.watch,
6669
});
67-
await build(rslibConfig, options);
6870
} catch (err) {
6971
logger.error('Failed to build.');
7072
logger.error(err);
@@ -88,21 +90,12 @@ export function runCli(): void {
8890
.action(async (options: InspectOptions) => {
8991
try {
9092
// TODO: inspect should output Rslib's config
91-
const rslibConfig = await loadConfig({
92-
path: options.config,
93-
envMode: options.envMode,
94-
});
95-
const environments = await composeRsbuildEnvironments(rslibConfig);
96-
const rsbuildInstance = await createRsbuild({
97-
rsbuildConfig: {
98-
environments: pruneEnvironments(environments, options.lib),
99-
},
100-
});
101-
await rsbuildInstance.inspectConfig({
93+
const rslibConfig = await loadRslibConfig(options);
94+
await inspect(rslibConfig, {
95+
lib: options.lib,
10296
mode: options.mode,
97+
output: options.output,
10398
verbose: options.verbose,
104-
outputPath: options.output,
105-
writeToDisk: true,
10699
});
107100
} catch (err) {
108101
logger.error('Failed to inspect config.');
@@ -115,10 +108,8 @@ export function runCli(): void {
115108
.description('start Rsbuild dev server of Module Federation format')
116109
.action(async (options: CommonOptions) => {
117110
try {
118-
const rslibConfig = await loadConfig({
119-
path: options.config,
120-
envMode: options.envMode,
121-
});
111+
const rslibConfig = await loadRslibConfig(options);
112+
// TODO: support lib option in mf dev server
122113
await startMFDevServer(rslibConfig);
123114
} catch (err) {
124115
logger.error('Failed to start mf dev.');

packages/core/src/cli/init.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { loadConfig } from '../config';
2+
import type { RslibConfig } from '../types';
3+
import { getAbsolutePath } from '../utils/helper';
4+
import type { CommonOptions } from './commands';
5+
6+
export async function loadRslibConfig(
7+
options: CommonOptions,
8+
): Promise<RslibConfig> {
9+
const cwd = process.cwd();
10+
const root = options.root ? getAbsolutePath(cwd, options.root) : cwd;
11+
12+
const rslibConfig = await loadConfig({
13+
cwd: root,
14+
path: options.config,
15+
envMode: options.envMode,
16+
});
17+
18+
return rslibConfig;
19+
}

packages/core/src/cli/inspect.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { type RsbuildInstance, createRsbuild } from '@rsbuild/core';
2+
import { composeRsbuildEnvironments, pruneEnvironments } from '../config';
3+
import type { RslibConfig } from '../types/config';
4+
import type { InspectOptions } from './commands';
5+
6+
export async function inspect(
7+
config: RslibConfig,
8+
options: Pick<InspectOptions, 'lib' | 'mode' | 'output' | 'verbose'> = {},
9+
): Promise<RsbuildInstance> {
10+
const environments = await composeRsbuildEnvironments(config);
11+
const rsbuildInstance = await createRsbuild({
12+
rsbuildConfig: {
13+
environments: pruneEnvironments(environments, options.lib),
14+
},
15+
});
16+
17+
await rsbuildInstance.inspectConfig({
18+
mode: options.mode,
19+
verbose: options.verbose,
20+
outputPath: options.output,
21+
writeToDisk: true,
22+
});
23+
24+
return rsbuildInstance;
25+
}

packages/core/src/mf.ts renamed to packages/core/src/cli/mf.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { createRsbuild, mergeRsbuildConfig } from '@rsbuild/core';
2-
import { composeCreateRsbuildConfig } from './config';
3-
42
import type { RsbuildConfig, RsbuildInstance } from '@rsbuild/core';
5-
import type { RslibConfig } from './types';
3+
import { composeCreateRsbuildConfig } from '../config';
4+
import type { RslibConfig } from '../types';
65

76
export async function startMFDevServer(
87
config: RslibConfig,

packages/core/src/config.ts

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import {
5353
calcLongestCommonPath,
5454
checkMFPlugin,
5555
color,
56+
getAbsolutePath,
5657
isEmptyObject,
5758
isObject,
5859
nodeBuiltInModules,
@@ -1084,9 +1085,13 @@ const composeExternalHelpersConfig = (
10841085
return defaultConfig;
10851086
};
10861087

1087-
async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
1088+
async function composeLibRsbuildConfig(config: LibConfig) {
10881089
checkMFPlugin(config);
1089-
const rootPath = dirname(configPath);
1090+
1091+
// Get the absolute path of the root directory to align with Rsbuild's default behavior
1092+
const rootPath = config.root
1093+
? getAbsolutePath(process.cwd(), config.root)
1094+
: process.cwd();
10901095
const pkgJson = readPackageJson(rootPath);
10911096
const { compilerOptions } = await loadTsconfig(
10921097
rootPath,
@@ -1148,7 +1153,7 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
11481153
const { entryConfig, lcp } = await composeEntryConfig(
11491154
config.source?.entry,
11501155
config.bundle,
1151-
dirname(configPath),
1156+
rootPath,
11521157
cssModulesAuto,
11531158
);
11541159
const cssConfig = composeCssConfig(lcp, config.bundle);
@@ -1192,10 +1197,8 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
11921197

11931198
export async function composeCreateRsbuildConfig(
11941199
rslibConfig: RslibConfig,
1195-
path?: string,
11961200
): Promise<RsbuildConfigWithLibInfo[]> {
11971201
const constantRsbuildConfig = await createConstantRsbuildConfig();
1198-
const configPath = path ?? rslibConfig._privateMeta?.configFilePath!;
11991202
const { lib: libConfigsArray, ...sharedRsbuildConfig } = rslibConfig;
12001203

12011204
if (!libConfigsArray) {
@@ -1212,10 +1215,7 @@ export async function composeCreateRsbuildConfig(
12121215

12131216
// Merge the configuration of each environment based on the shared Rsbuild
12141217
// configuration and Lib configuration in the settings.
1215-
const libRsbuildConfig = await composeLibRsbuildConfig(
1216-
userConfig,
1217-
configPath,
1218-
);
1218+
const libRsbuildConfig = await composeLibRsbuildConfig(userConfig);
12191219

12201220
// Reset certain fields because they will be completely overridden by the upcoming merge.
12211221
// We don't want to retain them in the final configuration.
@@ -1271,12 +1271,9 @@ export async function composeCreateRsbuildConfig(
12711271

12721272
export async function composeRsbuildEnvironments(
12731273
rslibConfig: RslibConfig,
1274-
path?: string,
12751274
): Promise<Record<string, EnvironmentConfig>> {
1276-
const rsbuildConfigWithLibInfo = await composeCreateRsbuildConfig(
1277-
rslibConfig,
1278-
path,
1279-
);
1275+
const rsbuildConfigWithLibInfo =
1276+
await composeCreateRsbuildConfig(rslibConfig);
12801277

12811278
// User provided ids should take precedence over generated ids.
12821279
const usedIds = rsbuildConfigWithLibInfo

packages/core/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
export { prepareCli } from './cli/prepare';
22
export { runCli } from './cli/commands';
3+
export { build } from './cli/build';
4+
export { inspect } from './cli/inspect';
5+
export { startMFDevServer } from './cli/mf';
36
export {
47
defineConfig,
58
loadConfig,
69
composeCreateRsbuildConfig as unstable_composeCreateRsbuildConfig,
710
} from './config';
8-
export { build } from './build';
911
export { logger } from './utils/logger';
1012
export type * from './types';
1113

packages/core/src/utils/helper.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import fs from 'node:fs';
22
import fsP from 'node:fs/promises';
3-
import path from 'node:path';
3+
import path, { isAbsolute, join } from 'node:path';
44
import type { RsbuildPlugins } from '@rsbuild/core';
55
import color from 'picocolors';
66

@@ -109,6 +109,10 @@ export async function calcLongestCommonPath(
109109
return lca;
110110
}
111111

112+
export function getAbsolutePath(base: string, filepath: string): string {
113+
return isAbsolute(filepath) ? filepath : join(base, filepath);
114+
}
115+
112116
export const readPackageJson = (rootPath: string): undefined | PkgJson => {
113117
const pkgJsonPath = path.join(rootPath, './package.json');
114118

packages/core/tests/__snapshots__/config.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1
7272
"pnpapi",
7373
],
7474
"filename": {
75-
"js": "[name].js",
75+
"js": "[name].mjs",
7676
},
7777
"filenameHash": false,
7878
"minify": {

0 commit comments

Comments
 (0)