Skip to content

Commit

Permalink
feat: add --root cli option and make basic js api work
Browse files Browse the repository at this point in the history
  • Loading branch information
Timeless0911 committed Nov 19, 2024
1 parent 17f7c6e commit 824dfe9
Show file tree
Hide file tree
Showing 17 changed files with 225 additions and 75 deletions.
22 changes: 0 additions & 22 deletions packages/core/src/build.ts

This file was deleted.

26 changes: 26 additions & 0 deletions packages/core/src/cli/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { type RsbuildInstance, createRsbuild } from '@rsbuild/core';
import { composeRsbuildEnvironments, pruneEnvironments } from '../config';
import type { RslibConfig } from '../types/config';
import { getAbsolutePath } from '../utils/helper';
import type { BuildOptions } from './commands';

export async function build(
config: RslibConfig,
options: Pick<BuildOptions, 'root' | 'lib' | 'watch'> = {},
): Promise<RsbuildInstance> {
const cwd = process.cwd();
options.root = options.root ? getAbsolutePath(cwd, options.root) : cwd;

const environments = await composeRsbuildEnvironments(config, options.root);
const rsbuildInstance = await createRsbuild({
rsbuildConfig: {
environments: pruneEnvironments(environments, options.lib),
},
});

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

return rsbuildInstance;
}
57 changes: 26 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 { getRslibConfig } 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,12 @@ 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 { root, rslibConfig } = await getRslibConfig(options);
await build(rslibConfig, {
root,
lib: options.lib,
watch: options.watch,
});
await build(rslibConfig, options);
} catch (err) {
logger.error('Failed to build.');
logger.error(err);
Expand All @@ -88,21 +91,13 @@ 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 { root, rslibConfig } = await getRslibConfig(options);
await inspect(rslibConfig, {
root,
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,11 +110,11 @@ 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 { root, rslibConfig } = await getRslibConfig(options);
// TODO: support lib option in mf dev server
await startMFDevServer(rslibConfig, {
root,
});
await startMFDevServer(rslibConfig);
} catch (err) {
logger.error('Failed to start mf dev.');
logger.error(err);
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 getRslibConfig(
options: CommonOptions,
): Promise<{ root: string; rslibConfig: RslibConfig }> {
const cwd = process.cwd();
const root = options.root ? getAbsolutePath(cwd, options.root) : cwd;

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

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

export async function inspect(
config: RslibConfig,
options: Pick<
InspectOptions,
'root' | 'lib' | 'mode' | 'output' | 'verbose'
> = {},
): Promise<RsbuildInstance> {
const cwd = process.cwd();
options.root = options.root ? getAbsolutePath(cwd, options.root) : cwd;

const environments = await composeRsbuildEnvironments(config, options.root);
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;
}
18 changes: 13 additions & 5 deletions packages/core/src/mf.ts → packages/core/src/cli/mf.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
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';
import { getAbsolutePath } from '../utils/helper';
import type { CommonOptions } from './commands';

export async function startMFDevServer(
config: RslibConfig,
options: Pick<CommonOptions, 'root'> = {},
): Promise<RsbuildInstance | undefined> {
const rsbuildInstance = await initMFRsbuild(config);
const cwd = process.cwd();
options.root = options.root ? getAbsolutePath(cwd, options.root) : cwd;
const rsbuildInstance = await initMFRsbuild(config, options.root);
return rsbuildInstance;
}

async function initMFRsbuild(
rslibConfig: RslibConfig,
root: string,
): Promise<RsbuildInstance | undefined> {
const rsbuildConfigObject = await composeCreateRsbuildConfig(rslibConfig);
const rsbuildConfigObject = await composeCreateRsbuildConfig(
rslibConfig,
root,
);
const mfRsbuildConfig = rsbuildConfigObject.find(
(config) => config.format === 'mf',
);
Expand Down
21 changes: 8 additions & 13 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1075,12 +1075,11 @@ const composeExternalHelpersConfig = (
return defaultConfig;
};

async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
async function composeLibRsbuildConfig(config: LibConfig, root: string) {
checkMFPlugin(config);
const rootPath = dirname(configPath);
const pkgJson = readPackageJson(rootPath);
const pkgJson = readPackageJson(root);
const { compilerOptions } = await loadTsconfig(
rootPath,
root,
config.source?.tsconfigPath,
);
const cssModulesAuto = config.output?.cssModules?.auto ?? true;
Expand Down Expand Up @@ -1139,7 +1138,7 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
const { entryConfig, lcp } = await composeEntryConfig(
config.source?.entry,
config.bundle,
dirname(configPath),
root,
cssModulesAuto,
);
const cssConfig = composeCssConfig(lcp, config.bundle);
Expand Down Expand Up @@ -1183,10 +1182,9 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {

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

if (!libConfigsArray) {
Expand All @@ -1203,10 +1201,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, root);

// 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 @@ -1262,11 +1257,11 @@ export async function composeCreateRsbuildConfig(

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

// User provided ids should take precedence over generated ids.
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",
},
"filenameHash": false,
"minify": {
Expand Down
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions tests/integration/cli/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,40 @@ describe('build command', async () => {
]
`);
});

test('--config', async () => {
await fse.remove(path.join(__dirname, 'dist'));
execSync(
'npx rslib build --config ./custom-config/rslib.config.custom.ts',
{
cwd: __dirname,
},
);

const files = await globContentJSON(path.join(__dirname, 'dist'));
const fileNames = Object.keys(files).sort();
expect(fileNames).toMatchInlineSnapshot(`
[
"<ROOT>/tests/integration/cli/dist/custom/index.cjs",
"<ROOT>/tests/integration/cli/dist/custom/index.js",
]
`);
});

test('--root', async () => {
await fse.remove(path.join(__dirname, 'dist'));
console.log('__dirname: ', __dirname);
execSync('npx rslib build --root custom-root', {
cwd: __dirname,
});

const files = await globContentJSON(path.join(__dirname, 'dist'));
const fileNames = Object.keys(files).sort();
expect(fileNames).toMatchInlineSnapshot(`
[
"<ROOT>/tests/integration/cli/dist/root/index.cjs",
"<ROOT>/tests/integration/cli/dist/root/index.js",
]
`);
});
});
Loading

0 comments on commit 824dfe9

Please sign in to comment.