Skip to content

Commit 4fadf93

Browse files
committed
feat: basic build command
1 parent cc0dd98 commit 4fadf93

4 files changed

Lines changed: 87 additions & 1 deletion

File tree

src/cli/commands.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import cac from 'cac';
2+
import { logger } from '@rsbuild/core';
3+
import { initRsbuild } from './rsbuild.js';
4+
import type { BuildOptions } from './types.js';
25

36
declare global {
47
const RSTACK_VERSION: string;
@@ -8,6 +11,45 @@ export function setupCommands(): void {
811
const cli = cac('rs');
912

1013
cli.version(RSTACK_VERSION);
11-
14+
15+
cli
16+
.command('build', 'Run Rsbuild to build the app for production')
17+
.option('-w, --watch', 'Enable watch mode to automatically rebuild on file changes')
18+
.action(async (options: BuildOptions) => {
19+
try {
20+
if (!options.watch) {
21+
process.env.RSPACK_UNSAFE_FAST_DROP = 'true';
22+
}
23+
24+
const rsbuild = await initRsbuild({
25+
options,
26+
});
27+
if (!rsbuild) {
28+
return;
29+
}
30+
31+
const buildResult = await rsbuild.build({
32+
watch: options.watch,
33+
});
34+
35+
if (buildResult) {
36+
if (options.watch) {
37+
// TODO
38+
} else {
39+
await buildResult.close();
40+
}
41+
}
42+
} catch (err) {
43+
const RSPACK_BUILD_ERROR = 'Rspack build failed.';
44+
const isRspackError = err instanceof Error && err.message === RSPACK_BUILD_ERROR;
45+
if (!isRspackError) {
46+
logger.error('Failed to build.');
47+
}
48+
49+
logger.error(err);
50+
process.exit(1);
51+
}
52+
});
53+
1254
cli.parse();
1355
}

src/cli/rsbuild.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { createRsbuild, loadConfig as baseLoadConfig, type RsbuildInstance } from '@rsbuild/core';
2+
import { ensureAbsolutePath } from '../helpers.js';
3+
import type { RsbuildCommonOptions } from './types.js';
4+
5+
const loadConfig = async (root: string) => {
6+
const { content: config } = await baseLoadConfig({
7+
cwd: root,
8+
});
9+
return config;
10+
};
11+
12+
export async function initRsbuild({
13+
options,
14+
}: {
15+
options?: RsbuildCommonOptions;
16+
}): Promise<RsbuildInstance | undefined> {
17+
const cwd = process.cwd();
18+
const root = options?.root ? ensureAbsolutePath(cwd, options.root) : cwd;
19+
20+
const rsbuild = await createRsbuild({
21+
cwd: root,
22+
config: () => loadConfig(root),
23+
});
24+
25+
return rsbuild;
26+
}

src/cli/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export type RsbuildCommonOptions = {
2+
root?: string;
3+
};
4+
5+
export type BuildOptions = {
6+
root?: string;
7+
watch?: boolean;
8+
};

src/helpers.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { isAbsolute, join } from 'node:path';
2+
3+
/**
4+
* ensure absolute file path.
5+
* @param base - Base path to resolve relative from.
6+
* @param filePath - Absolute or relative file path.
7+
* @returns Resolved absolute file path.
8+
*/
9+
export const ensureAbsolutePath = (base: string, filePath: string): string =>
10+
isAbsolute(filePath) ? filePath : join(base, filePath);

0 commit comments

Comments
 (0)