Skip to content

Commit

Permalink
feat(command): support --lib arguments (#390)
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework authored Nov 11, 2024
1 parent c42383a commit 30b0ec1
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 55 deletions.
11 changes: 8 additions & 3 deletions packages/core/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import type { RsbuildInstance } from '@rsbuild/core';
import { type RsbuildInstance, createRsbuild } from '@rsbuild/core';
import type { BuildOptions } from './cli/commands';
import { initRsbuild } from './config';
import { composeRsbuildEnvironments, pruneEnvironments } from './config';
import type { RslibConfig } from './types/config';

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

await rsbuildInstance.build({
watch: options?.watch,
Expand Down
30 changes: 27 additions & 3 deletions packages/core/src/cli/commands.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import type { RsbuildMode } from '@rsbuild/core';
import { type RsbuildMode, createRsbuild } from '@rsbuild/core';
import { type Command, program } from 'commander';
import { build } from '../build';
import { initRsbuild, loadConfig } from '../config';
import {
composeRsbuildEnvironments,
loadConfig,
pruneEnvironments,
} from '../config';
import { logger } from '../utils/logger';

export type CommonOptions = {
config?: string;
envMode?: string;
lib?: string[];
};

export type BuildOptions = CommonOptions & {
Expand All @@ -31,6 +36,10 @@ const applyCommonOptions = (command: Command) => {
);
};

const repeatableOption = (value: string, previous: string[]) => {
return (previous ?? []).concat([value]);
};

export function runCli(): void {
program.name('rslib').usage('<command> [options]').version(RSLIB_VERSION);

Expand All @@ -40,6 +49,11 @@ export function runCli(): void {
[buildCommand, inspectCommand].forEach(applyCommonOptions);

buildCommand
.option(
'--lib <name>',
'build the specified library (may be repeated)',
repeatableOption,
)
.option('-w --watch', 'turn on watch mode, watch for changes and rebuild')
.description('build the library for production')
.action(async (options: BuildOptions) => {
Expand All @@ -58,6 +72,11 @@ export function runCli(): void {

inspectCommand
.description('inspect the Rsbuild / Rspack configs of Rslib projects')
.option(
'--lib <name>',
'inspect the specified library (may be repeated)',
repeatableOption,
)
.option(
'--output <output>',
'specify inspect content output path',
Expand All @@ -71,7 +90,12 @@ export function runCli(): void {
path: options.config,
envMode: options.envMode,
});
const rsbuildInstance = await initRsbuild(rslibConfig);
const environments = await composeRsbuildEnvironments(rslibConfig);
const rsbuildInstance = await createRsbuild({
rsbuildConfig: {
environments: pruneEnvironments(environments, options.lib),
},
});
await rsbuildInstance.inspectConfig({
mode: options.mode,
verbose: options.verbose,
Expand Down
26 changes: 17 additions & 9 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import fs from 'node:fs';
import path, { dirname, extname, isAbsolute, join } from 'node:path';
import {
type EnvironmentConfig,
type RsbuildConfig,
type RsbuildInstance,
createRsbuild,
defineConfig as defineRsbuildConfig,
loadConfig as loadRsbuildConfig,
mergeRsbuildConfig,
Expand Down Expand Up @@ -1191,9 +1190,9 @@ export async function composeCreateRsbuildConfig(
return composedRsbuildConfig;
}

export async function initRsbuild(
export async function composeRsbuildEnvironments(
rslibConfig: RslibConfig,
): Promise<RsbuildInstance> {
): Promise<Record<string, EnvironmentConfig>> {
const rsbuildConfigObject = await composeCreateRsbuildConfig(rslibConfig);
const environments: RsbuildConfig['environments'] = {};
const formatCount: Record<Format, number> = rsbuildConfigObject.reduce(
Expand All @@ -1220,9 +1219,18 @@ export async function initRsbuild(
] = config;
}

return createRsbuild({
rsbuildConfig: {
environments,
},
});
return environments;
}

export const pruneEnvironments = (
environments: Record<string, EnvironmentConfig>,
libs?: string[],
): Record<string, EnvironmentConfig> => {
if (!libs) {
return environments;
}

return Object.fromEntries(
Object.entries(environments).filter(([name]) => libs.includes(name)),
);
};
54 changes: 54 additions & 0 deletions tests/integration/cli/build.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { execSync } from 'node:child_process';
import path from 'node:path';
import fse from 'fs-extra';
import { globContentJSON } from 'test-helper';
import { describe, expect, test } from 'vitest';

describe('build command', async () => {
test('basic', async () => {
await fse.remove(path.join(__dirname, 'dist'));
execSync('npx rslib build', {
cwd: __dirname,
});

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

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

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

test('--lib multiple', async () => {
await fse.remove(path.join(__dirname, 'dist'));
execSync('npx rslib build --lib esm --lib cjs', {
cwd: __dirname,
});

const files = await globContentJSON(path.join(__dirname, 'dist'));
const fileNames = Object.keys(files).sort();
expect(fileNames).toMatchInlineSnapshot(`
[
"<ROOT>/tests/integration/cli/dist/cjs/index.cjs",
"<ROOT>/tests/integration/cli/dist/esm/index.js",
]
`);
});
});
40 changes: 0 additions & 40 deletions tests/integration/cli/index.test.ts

This file was deleted.

95 changes: 95 additions & 0 deletions tests/integration/cli/inspect.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { execSync } from 'node:child_process';
import path from 'node:path';
import { describe } from 'node:test';
import fse from 'fs-extra';
import { globContentJSON } from 'test-helper';
import { expect, test } from 'vitest';

describe('inspect command', async () => {
test('basic', async () => {
await fse.remove(path.join(__dirname, 'dist'));
execSync('npx rslib inspect', {
cwd: __dirname,
});

const files = await globContentJSON(path.join(__dirname, 'dist/.rsbuild'));
const fileNames = Object.keys(files).sort();

expect(fileNames).toMatchInlineSnapshot(`
[
"<ROOT>/tests/integration/cli/dist/.rsbuild/rsbuild.config.cjs.mjs",
"<ROOT>/tests/integration/cli/dist/.rsbuild/rsbuild.config.esm.mjs",
"<ROOT>/tests/integration/cli/dist/.rsbuild/rspack.config.cjs.mjs",
"<ROOT>/tests/integration/cli/dist/.rsbuild/rspack.config.esm.mjs",
]
`);

// esm rsbuild config
const rsbuildConfigEsm = fileNames.find((item) =>
item.includes('rsbuild.config.esm.mjs'),
);
expect(rsbuildConfigEsm).toBeTruthy();
expect(files[rsbuildConfigEsm!]).toContain("type: 'modern-module'");

// esm rspack config
const rspackConfigEsm = fileNames.find((item) =>
item.includes('rspack.config.esm.mjs'),
);
expect(rspackConfigEsm).toBeTruthy();
expect(files[rspackConfigEsm!]).toContain("type: 'modern-module'");
});

test('--lib', async () => {
await fse.remove(path.join(__dirname, 'dist'));
execSync('npx rslib inspect --lib esm', {
cwd: __dirname,
});

const files = await globContentJSON(
path.join(__dirname, 'dist/esm/.rsbuild'),
);
const fileNames = Object.keys(files).sort();

// Rsbuild will emit dump files to `dist/esm` if only one environment is specified.
expect(fileNames).toMatchInlineSnapshot(`
[
"<ROOT>/tests/integration/cli/dist/esm/.rsbuild/rsbuild.config.mjs",
"<ROOT>/tests/integration/cli/dist/esm/.rsbuild/rspack.config.esm.mjs",
]
`);

// esm rsbuild config
const rsbuildConfigEsm = fileNames.find((item) =>
item.includes('rsbuild.config.mjs'),
);
expect(rsbuildConfigEsm).toBeTruthy();
expect(files[rsbuildConfigEsm!]).toContain("type: 'modern-module'");

// esm rspack config
const rspackConfigEsm = fileNames.find((item) =>
item.includes('rspack.config.esm.mjs'),
);
expect(rspackConfigEsm).toBeTruthy();
expect(files[rspackConfigEsm!]).toContain("type: 'modern-module'");
});

test('--lib multiple', async () => {
await fse.remove(path.join(__dirname, 'dist'));
execSync('npx rslib inspect --lib esm --lib cjs', {
cwd: __dirname,
});

const files = await globContentJSON(path.join(__dirname, 'dist/.rsbuild'));
const fileNames = Object.keys(files).sort();

// Rsbuild will emit dump files to `dist/esm` if only one environment is specified.
expect(fileNames).toMatchInlineSnapshot(`
[
"<ROOT>/tests/integration/cli/dist/.rsbuild/rsbuild.config.cjs.mjs",
"<ROOT>/tests/integration/cli/dist/.rsbuild/rsbuild.config.esm.mjs",
"<ROOT>/tests/integration/cli/dist/.rsbuild/rspack.config.cjs.mjs",
"<ROOT>/tests/integration/cli/dist/.rsbuild/rspack.config.esm.mjs",
]
`);
});
});
1 change: 1 addition & 0 deletions tests/integration/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const foo = 'foo';
2 changes: 2 additions & 0 deletions website/docs/en/guide/basic/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ build the library for production
Options:
-c --config <config> specify the configuration file, can be a relative or absolute path
--env-mode <mode> specify the env mode to load the `.env.[mode]` file
--lib <name> build the specified library (may be repeated)
-w --watch turn on watch mode, watch for changes and rebuild
-h, --help display help for command
```
Expand All @@ -58,6 +59,7 @@ inspect the Rsbuild / Rspack configs of Rslib projects
Options:
-c --config <config> specify the configuration file, can be a relative or absolute path
--env-mode <mode> specify the env mode to load the `.env.[mode]` file
--lib <name> build the specified library (may be repeated)
--output <output> specify inspect content output path (default: ".rsbuild")
--verbose show full function definitions in output
-h, --help display help for command
Expand Down

0 comments on commit 30b0ec1

Please sign in to comment.