Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add --root cli option and make basic js api work #453

Merged
merged 4 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions packages/core/src/build.ts → packages/core/src/cli/build.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { type RsbuildInstance, createRsbuild } from '@rsbuild/core';
import type { BuildOptions } from './cli/commands';
import { composeRsbuildEnvironments, pruneEnvironments } from './config';
import type { RslibConfig } from './types/config';
import { composeRsbuildEnvironments, pruneEnvironments } from '../config';
import type { RslibConfig } from '../types/config';
import type { BuildOptions } from './commands';

export async function build(
config: RslibConfig,
options?: BuildOptions,
options: Pick<BuildOptions, 'lib' | 'watch'> = {},
): Promise<RsbuildInstance> {
const environments = await composeRsbuildEnvironments(config);
const rsbuildInstance = await createRsbuild({
rsbuildConfig: {
environments: pruneEnvironments(environments, options?.lib),
environments: pruneEnvironments(environments, options.lib),
},
});

await rsbuildInstance.build({
watch: options?.watch,
watch: options.watch,
});

return rsbuildInstance;
Expand Down
53 changes: 22 additions & 31 deletions packages/core/src/cli/commands.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { type RsbuildMode, createRsbuild } from '@rsbuild/core';
import type { RsbuildMode } from '@rsbuild/core';
import { type Command, program } from 'commander';
import { build } from '../build';
import {
composeRsbuildEnvironments,
loadConfig,
pruneEnvironments,
} from '../config';
import { startMFDevServer } from '../mf';
import { logger } from '../utils/logger';
import { build } from './build';
import { loadRslibConfig } from './init';
import { inspect } from './inspect';
import { startMFDevServer } from './mf';

export type CommonOptions = {
root?: string;
config?: string;
envMode?: string;
lib?: string[];
Expand All @@ -20,8 +18,8 @@ export type BuildOptions = CommonOptions & {
};

export type InspectOptions = CommonOptions & {
mode: RsbuildMode;
output: string;
mode?: RsbuildMode;
output?: string;
verbose?: boolean;
};

Expand All @@ -31,6 +29,10 @@ const applyCommonOptions = (command: Command) => {
'-c --config <config>',
'specify the configuration file, can be a relative or absolute path',
)
.option(
'-r --root <root>',
'specify the project root directory, can be an absolute path or a path relative to cwd',
)
.option(
'--env-mode <mode>',
'specify the env mode to load the `.env.[mode]` file',
Expand Down Expand Up @@ -60,11 +62,11 @@ export function runCli(): void {
.description('build the library for production')
.action(async (options: BuildOptions) => {
try {
const rslibConfig = await loadConfig({
path: options.config,
envMode: options.envMode,
const rslibConfig = await loadRslibConfig(options);
await build(rslibConfig, {
lib: options.lib,
watch: options.watch,
});
await build(rslibConfig, options);
} catch (err) {
logger.error('Failed to build.');
logger.error(err);
Expand All @@ -88,21 +90,12 @@ export function runCli(): void {
.action(async (options: InspectOptions) => {
try {
// TODO: inspect should output Rslib's config
const rslibConfig = await loadConfig({
path: options.config,
envMode: options.envMode,
});
const environments = await composeRsbuildEnvironments(rslibConfig);
const rsbuildInstance = await createRsbuild({
rsbuildConfig: {
environments: pruneEnvironments(environments, options.lib),
},
});
await rsbuildInstance.inspectConfig({
const rslibConfig = await loadRslibConfig(options);
await inspect(rslibConfig, {
lib: options.lib,
mode: options.mode,
output: options.output,
verbose: options.verbose,
outputPath: options.output,
writeToDisk: true,
});
} catch (err) {
logger.error('Failed to inspect config.');
Expand All @@ -115,10 +108,8 @@ export function runCli(): void {
.description('start Rsbuild dev server of Module Federation format')
.action(async (options: CommonOptions) => {
try {
const rslibConfig = await loadConfig({
path: options.config,
envMode: options.envMode,
});
const rslibConfig = await loadRslibConfig(options);
// TODO: support lib option in mf dev server
await startMFDevServer(rslibConfig);
} catch (err) {
logger.error('Failed to start mf dev.');
Expand Down
19 changes: 19 additions & 0 deletions packages/core/src/cli/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { loadConfig } from '../config';
import type { RslibConfig } from '../types';
import { getAbsolutePath } from '../utils/helper';
import type { CommonOptions } from './commands';

export async function loadRslibConfig(
options: CommonOptions,
): Promise<RslibConfig> {
const cwd = process.cwd();
const root = options.root ? getAbsolutePath(cwd, options.root) : cwd;
fi3ework marked this conversation as resolved.
Show resolved Hide resolved

const rslibConfig = await loadConfig({
cwd: root,
path: options.config,
envMode: options.envMode,
});

return rslibConfig;
}
25 changes: 25 additions & 0 deletions packages/core/src/cli/inspect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type RsbuildInstance, createRsbuild } from '@rsbuild/core';
import { composeRsbuildEnvironments, pruneEnvironments } from '../config';
import type { RslibConfig } from '../types/config';
import type { InspectOptions } from './commands';

export async function inspect(
config: RslibConfig,
options: Pick<InspectOptions, 'lib' | 'mode' | 'output' | 'verbose'> = {},
): Promise<RsbuildInstance> {
const environments = await composeRsbuildEnvironments(config);
const rsbuildInstance = await createRsbuild({
rsbuildConfig: {
environments: pruneEnvironments(environments, options.lib),
},
});

await rsbuildInstance.inspectConfig({
mode: options.mode,
verbose: options.verbose,
outputPath: options.output,
writeToDisk: true,
});

return rsbuildInstance;
}
5 changes: 2 additions & 3 deletions packages/core/src/mf.ts → packages/core/src/cli/mf.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { createRsbuild, mergeRsbuildConfig } from '@rsbuild/core';
import { composeCreateRsbuildConfig } from './config';

import type { RsbuildConfig, RsbuildInstance } from '@rsbuild/core';
import type { RslibConfig } from './types';
import { composeCreateRsbuildConfig } from '../config';
import type { RslibConfig } from '../types';

export async function startMFDevServer(
config: RslibConfig,
Expand Down
25 changes: 11 additions & 14 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
calcLongestCommonPath,
checkMFPlugin,
color,
getAbsolutePath,
isEmptyObject,
isObject,
nodeBuiltInModules,
Expand Down Expand Up @@ -1084,9 +1085,13 @@ const composeExternalHelpersConfig = (
return defaultConfig;
};

async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
async function composeLibRsbuildConfig(config: LibConfig) {
checkMFPlugin(config);
const rootPath = dirname(configPath);

// Get the absolute path of the root directory to align with Rsbuild's default behavior
const rootPath = config.root
? getAbsolutePath(process.cwd(), config.root)
: process.cwd();
const pkgJson = readPackageJson(rootPath);
const { compilerOptions } = await loadTsconfig(
rootPath,
Expand Down Expand Up @@ -1148,7 +1153,7 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
const { entryConfig, lcp } = await composeEntryConfig(
config.source?.entry,
config.bundle,
dirname(configPath),
rootPath,
cssModulesAuto,
);
const cssConfig = composeCssConfig(lcp, config.bundle);
Expand Down Expand Up @@ -1192,10 +1197,8 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {

export async function composeCreateRsbuildConfig(
rslibConfig: RslibConfig,
path?: string,
): Promise<RsbuildConfigWithLibInfo[]> {
const constantRsbuildConfig = await createConstantRsbuildConfig();
const configPath = path ?? rslibConfig._privateMeta?.configFilePath!;
const { lib: libConfigsArray, ...sharedRsbuildConfig } = rslibConfig;

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

// Merge the configuration of each environment based on the shared Rsbuild
// configuration and Lib configuration in the settings.
const libRsbuildConfig = await composeLibRsbuildConfig(
userConfig,
configPath,
);
const libRsbuildConfig = await composeLibRsbuildConfig(userConfig);

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

export async function composeRsbuildEnvironments(
rslibConfig: RslibConfig,
path?: string,
): Promise<Record<string, EnvironmentConfig>> {
const rsbuildConfigWithLibInfo = await composeCreateRsbuildConfig(
rslibConfig,
path,
);
const rsbuildConfigWithLibInfo =
await composeCreateRsbuildConfig(rslibConfig);

// User provided ids should take precedence over generated ids.
const usedIds = rsbuildConfigWithLibInfo
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export { prepareCli } from './cli/prepare';
export { runCli } from './cli/commands';
export { build } from './cli/build';
export { inspect } from './cli/inspect';
export { startMFDevServer } from './cli/mf';
export {
defineConfig,
loadConfig,
composeCreateRsbuildConfig as unstable_composeCreateRsbuildConfig,
} from './config';
export { build } from './build';
export { logger } from './utils/logger';
export type * from './types';

Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'node:fs';
import fsP from 'node:fs/promises';
import path from 'node:path';
import path, { isAbsolute, join } from 'node:path';
import type { RsbuildPlugins } from '@rsbuild/core';
import color from 'picocolors';

Expand Down Expand Up @@ -109,6 +109,10 @@ export async function calcLongestCommonPath(
return lca;
}

export function getAbsolutePath(base: string, filepath: string): string {
return isAbsolute(filepath) ? filepath : join(base, filepath);
}

export const readPackageJson = (rootPath: string): undefined | PkgJson => {
const pkgJsonPath = path.join(rootPath, './package.json');

Expand Down
2 changes: 1 addition & 1 deletion packages/core/tests/__snapshots__/config.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1
"pnpapi",
],
"filename": {
"js": "[name].js",
"js": "[name].mjs",
Timeless0911 marked this conversation as resolved.
Show resolved Hide resolved
},
"filenameHash": false,
"minify": {
Expand Down
Loading
Loading