From 8959e5b668ed1ef5f98a487406ba8a645ed64368 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Sun, 22 Dec 2024 21:45:32 +0800 Subject: [PATCH 1/9] feat: support `--lib` param of `mf-dev` command --- .../mf-react-component/package.json | 2 +- packages/core/src/asset/assetConfig.ts | 4 +- packages/core/src/cli/build.ts | 7 +- packages/core/src/cli/commands.ts | 26 +++--- packages/core/src/cli/inspect.ts | 5 +- packages/core/src/cli/mf.ts | 80 ++++++++++--------- packages/core/src/config.ts | 72 +++++++++-------- packages/core/src/css/cssConfig.ts | 4 +- packages/core/src/plugins/EntryChunkPlugin.ts | 4 +- packages/core/src/types/config.ts | 12 +-- packages/core/src/types/utils.ts | 2 + packages/core/src/utils/syntax.ts | 8 +- .../tests/__snapshots__/config.test.ts.snap | 3 - packages/core/tests/config.test.ts | 6 +- packages/plugin-dts/src/index.ts | 10 ++- packages/plugin-dts/src/utils.ts | 4 +- pnpm-lock.yaml | 6 +- tests/integration/cli/build/build.test.ts | 8 +- .../cli/build/custom-root/rslib.config.ts | 6 ++ tests/integration/cli/mf-dev/dev.test.ts | 44 ++++++++++ .../{plugins => cli/mf-dev}/package.json | 2 +- tests/integration/cli/mf-dev/rslib.config.ts | 37 +++++++++ tests/integration/cli/mf-dev/src/index.ts | 1 + tests/integration/plugins/basic/package.json | 6 ++ .../plugins/{ => basic}/rslib.config.ts | 0 .../plugins/{ => basic}/src/index.ts | 0 tests/integration/plugins/index.test.ts | 26 +++++- tests/integration/plugins/mf-dev/package.json | 6 ++ .../plugins/mf-dev/rslib.config.ts | 37 +++++++++ tests/integration/plugins/mf-dev/src/index.ts | 1 + tests/integration/server/index.test.ts | 9 +-- .../integration/server/mf-dev/rslib.config.ts | 4 - 32 files changed, 310 insertions(+), 132 deletions(-) create mode 100644 tests/integration/cli/mf-dev/dev.test.ts rename tests/integration/{plugins => cli/mf-dev}/package.json (68%) create mode 100644 tests/integration/cli/mf-dev/rslib.config.ts create mode 100644 tests/integration/cli/mf-dev/src/index.ts create mode 100644 tests/integration/plugins/basic/package.json rename tests/integration/plugins/{ => basic}/rslib.config.ts (100%) rename tests/integration/plugins/{ => basic}/src/index.ts (100%) create mode 100644 tests/integration/plugins/mf-dev/package.json create mode 100644 tests/integration/plugins/mf-dev/rslib.config.ts create mode 100644 tests/integration/plugins/mf-dev/src/index.ts diff --git a/examples/module-federation/mf-react-component/package.json b/examples/module-federation/mf-react-component/package.json index 90b44b140..eea15a0a7 100644 --- a/examples/module-federation/mf-react-component/package.json +++ b/examples/module-federation/mf-react-component/package.json @@ -13,7 +13,7 @@ "types": "./dist/cjs/index.d.ts", "scripts": { "build": "rslib build", - "dev": "rslib mf dev", + "dev": "rslib mf-dev", "serve": "pnpm build & http-server -p 3001 ./dist/ --cors", "storybook": "storybook dev -p 6006" }, diff --git a/packages/core/src/asset/assetConfig.ts b/packages/core/src/asset/assetConfig.ts index fdbf763e8..81598e6ea 100644 --- a/packages/core/src/asset/assetConfig.ts +++ b/packages/core/src/asset/assetConfig.ts @@ -1,11 +1,11 @@ -import type { RsbuildConfig } from '@rsbuild/core'; +import type { EnvironmentConfig } from '@rsbuild/core'; import type { Format } from '../types'; // TODO: asset config document export const composeAssetConfig = ( bundle: boolean, format: Format, -): RsbuildConfig => { +): EnvironmentConfig => { if (format === 'esm' || format === 'cjs') { if (bundle) { return { diff --git a/packages/core/src/cli/build.ts b/packages/core/src/cli/build.ts index a44ce4688..254f15a60 100644 --- a/packages/core/src/cli/build.ts +++ b/packages/core/src/cli/build.ts @@ -6,12 +6,15 @@ import { onBeforeRestart } from './restart'; export async function build( config: RslibConfig, - options: Pick = {}, + options: Pick = {}, ): Promise { - const environments = await composeRsbuildEnvironments(config); + const { environments } = await composeRsbuildEnvironments(config); const rsbuildInstance = await createRsbuild({ rsbuildConfig: { + mode: 'production', + root: config.root, plugins: config.plugins, + dev: config.dev, server: config.server, environments: pruneEnvironments(environments, options.lib), }, diff --git a/packages/core/src/cli/commands.ts b/packages/core/src/cli/commands.ts index 0fe0323b1..195adeb0d 100644 --- a/packages/core/src/cli/commands.ts +++ b/packages/core/src/cli/commands.ts @@ -39,7 +39,12 @@ const applyCommonOptions = (command: Command) => { '--env-mode ', 'specify the env mode to load the `.env.[mode]` file', ) - .option('--env-dir ', 'specify the directory to load `.env` files'); + .option('--env-dir ', 'specify the directory to load `.env` files') + .option( + '--lib ', + 'specify the library (repeatable, e.g. --lib esm --lib cjs)', + repeatableOption, + ); }; const repeatableOption = (value: string, previous: string[]) => { @@ -51,16 +56,11 @@ export function runCli(): void { const buildCommand = program.command('build'); const inspectCommand = program.command('inspect'); - const mfDevCommand = program.command('mf dev'); + const mfDevCommand = program.command('mf-dev'); [buildCommand, inspectCommand, mfDevCommand].forEach(applyCommonOptions); buildCommand - .option( - '--lib ', - '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) => { @@ -87,11 +87,6 @@ export function runCli(): void { inspectCommand .description('inspect the Rsbuild / Rspack configs of Rslib projects') - .option( - '--lib ', - 'inspect the specified library (may be repeated)', - repeatableOption, - ) .option( '--output ', 'specify inspect content output path', @@ -121,8 +116,9 @@ export function runCli(): void { try { const cliMfDev = async () => { const { config, watchFiles } = await init(options); - // TODO: support lib option in mf dev server - await startMFDevServer(config); + await startMFDevServer(config, { + lib: options.lib, + }); watchFilesForRestart(watchFiles, async () => { await cliMfDev(); @@ -131,7 +127,7 @@ export function runCli(): void { await cliMfDev(); } catch (err) { - logger.error('Failed to start mf dev.'); + logger.error('Failed to start mf-dev.'); logger.error(err); process.exit(1); } diff --git a/packages/core/src/cli/inspect.ts b/packages/core/src/cli/inspect.ts index 350da1436..ace7b8a67 100644 --- a/packages/core/src/cli/inspect.ts +++ b/packages/core/src/cli/inspect.ts @@ -7,10 +7,13 @@ export async function inspect( config: RslibConfig, options: Pick = {}, ): Promise { - const environments = await composeRsbuildEnvironments(config); + const { environments } = await composeRsbuildEnvironments(config); const rsbuildInstance = await createRsbuild({ rsbuildConfig: { + mode: 'production', + root: config.root, plugins: config.plugins, + dev: config.dev, server: config.server, environments: pruneEnvironments(environments, options.lib), }, diff --git a/packages/core/src/cli/mf.ts b/packages/core/src/cli/mf.ts index 42d99e370..b24dde1de 100644 --- a/packages/core/src/cli/mf.ts +++ b/packages/core/src/cli/mf.ts @@ -1,42 +1,63 @@ -import { createRsbuild, mergeRsbuildConfig } from '@rsbuild/core'; -import type { RsbuildConfig, RsbuildInstance } from '@rsbuild/core'; -import { composeCreateRsbuildConfig } from '../config'; +import { createRsbuild } from '@rsbuild/core'; +import type { RsbuildInstance } from '@rsbuild/core'; +import { composeRsbuildEnvironments, pruneEnvironments } from '../config'; import type { RslibConfig } from '../types'; +import type { CommonOptions } from './commands'; import { onBeforeRestart } from './restart'; export async function startMFDevServer( config: RslibConfig, + options: Pick = {}, ): Promise { - const rsbuildInstance = await initMFRsbuild(config); + const rsbuildInstance = await initMFRsbuild(config, options); return rsbuildInstance; } async function initMFRsbuild( rslibConfig: RslibConfig, + options: Pick = {}, ): Promise { - const rsbuildConfigObject = await composeCreateRsbuildConfig(rslibConfig); - const mfRsbuildConfig = rsbuildConfigObject.find( - (config) => config.format === 'mf', - ); + const { environments, environmentWithInfos } = + await composeRsbuildEnvironments(rslibConfig); + + const selectedEnvironmentIds = environmentWithInfos + .filter((env) => { + const isMf = env.format === 'mf'; + if (!options?.lib) { + return isMf; + } + return env.id && options.lib.includes(env.id); + }) + .map((env) => env.id); - if (!mfRsbuildConfig) { - // no mf format, return. - return; + if (!selectedEnvironmentIds.length) { + throw new Error('No mf format found, please check your config.'); } - mfRsbuildConfig.config = changeEnvToDev(mfRsbuildConfig.config); + const selectedEnvironments = pruneEnvironments( + environments, + selectedEnvironmentIds, + ); const rsbuildInstance = await createRsbuild({ rsbuildConfig: { - ...mfRsbuildConfig.config, - plugins: [ - ...(rslibConfig.plugins || []), - ...(mfRsbuildConfig.config.plugins || []), - ], - server: mergeRsbuildConfig( - rslibConfig.server, - mfRsbuildConfig.config.server, - ), + mode: 'development', + root: rslibConfig.root, + plugins: rslibConfig.plugins, + dev: { + ...(rslibConfig.dev ?? {}), + writeToDisk: true, + }, + server: rslibConfig.server, + tools: { + rspack: { + optimization: { + nodeEnv: 'development', + moduleIds: 'named', + }, + }, + }, + environments: selectedEnvironments, }, }); @@ -45,20 +66,3 @@ async function initMFRsbuild( onBeforeRestart(devServer.server.close); return rsbuildInstance; } - -function changeEnvToDev(rsbuildConfig: RsbuildConfig) { - return mergeRsbuildConfig(rsbuildConfig, { - mode: 'development', - dev: { - writeToDisk: true, - }, - tools: { - rspack: { - optimization: { - nodeEnv: 'development', - moduleIds: 'named', - }, - }, - }, - }); -} diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 7d9f23292..86c156bb1 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -44,6 +44,7 @@ import type { LibOnlyConfig, PkgJson, Redirect, + RequireKey, RsbuildConfigEntry, RsbuildConfigEntryItem, RsbuildConfigOutputTarget, @@ -141,13 +142,13 @@ export async function loadConfig({ const composeExternalsWarnConfig = ( format: Format, - ...externalsArray: NonNullable['externals'][] -): RsbuildConfig => { + ...externalsArray: NonNullable['externals'][] +): EnvironmentConfig => { if (format !== 'esm') { return {}; } - const externals: NonNullable['externals'] = []; + const externals: NonNullable['externals'] = []; for (const e of externalsArray.filter(Boolean)) { if (Array.isArray(e)) { externals.push(...e); @@ -159,7 +160,7 @@ const composeExternalsWarnConfig = ( // Match logic is derived from https://github.com/webpack/webpack/blob/94aba382eccf3de1004d235045d4462918dfdbb7/lib/ExternalModuleFactoryPlugin.js#L166-L293. const matchUserExternals = ( - externals: NonNullable['externals'], + externals: NonNullable['externals'], request: string, callback: (matched?: true) => void, ) => { @@ -252,8 +253,8 @@ export const composeAutoExternalConfig = (options: { format: Format; autoExternal?: AutoExternal; pkgJson?: PkgJson; - userExternals?: NonNullable['externals']; -}): RsbuildConfig => { + userExternals?: NonNullable['externals']; +}): EnvironmentConfig => { const { format, pkgJson, userExternals } = options; const autoExternal = getAutoExternalDefaultValue( @@ -317,7 +318,7 @@ export const composeAutoExternalConfig = (options: { : {}; }; -export function composeMinifyConfig(config: LibConfig): RsbuildConfig { +export function composeMinifyConfig(config: LibConfig): EnvironmentConfig { const minify = config.output?.minify; const format = config.format; if (minify !== undefined) { @@ -358,7 +359,7 @@ export function composeMinifyConfig(config: LibConfig): RsbuildConfig { export function composeBannerFooterConfig( banner: BannerAndFooter, footer: BannerAndFooter, -): RsbuildConfig { +): EnvironmentConfig { const bannerConfig = pick(banner, ['js', 'css']); const footerConfig = pick(footer, ['js', 'css']); @@ -428,9 +429,9 @@ export function composeBannerFooterConfig( export function composeDecoratorsConfig( compilerOptions?: Record, version?: NonNullable< - NonNullable['decorators'] + NonNullable['decorators'] >['version'], -): RsbuildConfig { +): EnvironmentConfig { if (version || !compilerOptions?.experimentalDecorators) { return {}; } @@ -444,9 +445,8 @@ export function composeDecoratorsConfig( }; } -export async function createConstantRsbuildConfig(): Promise { +export async function createConstantRsbuildConfig(): Promise { return defineRsbuildConfig({ - mode: 'production', dev: { progressBar: false, }, @@ -508,7 +508,7 @@ const composeFormatConfig = ({ pkgJson: PkgJson; bundle?: boolean; umdName?: string; -}): RsbuildConfig => { +}): EnvironmentConfig => { const jsParserOptions = { cjs: { requireResolve: false, @@ -583,7 +583,7 @@ const composeFormatConfig = ({ ); } - const config: RsbuildConfig = { + const config: EnvironmentConfig = { tools: { rspack: { module: { @@ -653,7 +653,7 @@ const formatRsbuildPlugin = (): RsbuildPlugin => ({ const composeShimsConfig = ( format: Format, shims?: Shims, -): { rsbuildConfig: RsbuildConfig; enabledShims: DeepRequired } => { +): { rsbuildConfig: EnvironmentConfig; enabledShims: DeepRequired } => { const resolvedShims = { cjs: { 'import.meta.url': shims?.cjs?.['import.meta.url'] ?? true, @@ -682,7 +682,7 @@ const composeShimsConfig = ( }, }; - let rsbuildConfig: RsbuildConfig = {}; + let rsbuildConfig: EnvironmentConfig = {}; switch (format) { case 'esm': { rsbuildConfig = { @@ -725,8 +725,8 @@ export const composeModuleImportWarn = (request: string): string => { const composeExternalsConfig = ( format: Format, - externals: NonNullable['externals'], -): RsbuildConfig => { + externals: NonNullable['externals'], +): EnvironmentConfig => { // TODO: Define the internal externals config in Rsbuild's externals instead // Rspack's externals as they will not be merged from different fields. All externals // should to be unified and merged together in the future. @@ -768,7 +768,7 @@ const composeAutoExtensionConfig = ( autoExtension: boolean, pkgJson?: PkgJson, ): { - config: RsbuildConfig; + config: EnvironmentConfig; jsExtension: string; dtsExtension: string; } => { @@ -778,7 +778,7 @@ const composeAutoExtensionConfig = ( autoExtension, }); - const updatedConfig: RsbuildConfig = { + const updatedConfig: EnvironmentConfig = { output: { filename: { js: `[name]${jsExtension}`, @@ -803,7 +803,7 @@ const composeAutoExtensionConfig = ( const composeSyntaxConfig = ( target: RsbuildConfigOutputTarget, syntax?: Syntax, -): RsbuildConfig => { +): EnvironmentConfig => { // Defaults to ESNext, Rslib will assume all of the latest JavaScript and CSS features are supported. if (syntax) { return { @@ -865,7 +865,7 @@ const composeEntryConfig = async ( bundle: LibConfig['bundle'], root: string, cssModulesAuto: CssLoaderOptionsAuto, -): Promise<{ entryConfig: RsbuildConfig; lcp: string | null }> => { +): Promise<{ entryConfig: EnvironmentConfig; lcp: string | null }> => { if (!entries) { return { entryConfig: {}, lcp: null }; } @@ -948,7 +948,7 @@ const composeEntryConfig = async ( } const lcp = await calcLongestCommonPath(Object.values(resolvedEntries)); - const entryConfig: RsbuildConfig = { + const entryConfig: EnvironmentConfig = { source: { entry: appendEntryQuery(resolvedEntries), }, @@ -966,7 +966,7 @@ const composeBundlelessExternalConfig = ( cssModulesAuto: CssLoaderOptionsAuto, bundle: boolean, ): { - config: RsbuildConfig; + config: EnvironmentConfig; resolvedJsRedirect?: DeepRequired; } => { if (bundle) return { config: {} }; @@ -1074,7 +1074,7 @@ const composeBundlelessExternalConfig = ( const composeDtsConfig = async ( libConfig: LibConfig, dtsExtension: string, -): Promise => { +): Promise => { const { format, autoExternal, banner, footer } = libConfig; let { dts } = libConfig; @@ -1110,8 +1110,8 @@ const composeTargetConfig = ( userTarget: RsbuildConfigOutputTarget, format: Format, ): { - config: RsbuildConfig; - externalsConfig: RsbuildConfig; + config: EnvironmentConfig; + externalsConfig: EnvironmentConfig; target: RsbuildConfigOutputTarget; } => { const target = userTarget ?? (format === 'mf' ? 'web' : 'node'); @@ -1204,14 +1204,13 @@ const composeExternalHelpersConfig = ( async function composeLibRsbuildConfig( config: LibConfig, + root?: string, sharedPlugins?: RsbuildPlugins, ) { checkMFPlugin(config, sharedPlugins); // 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 rootPath = root ? getAbsolutePath(process.cwd(), root) : process.cwd(); const pkgJson = readPackageJson(rootPath); const { compilerOptions } = await loadTsconfig( rootPath, @@ -1334,7 +1333,10 @@ export async function composeCreateRsbuildConfig( const constantRsbuildConfig = await createConstantRsbuildConfig(); const { lib: libConfigsArray, + mode, + root, plugins: sharedPlugins, + dev, server, ...sharedRsbuildConfig } = rslibConfig; @@ -1355,6 +1357,7 @@ export async function composeCreateRsbuildConfig( // configuration and Lib configuration in the settings. const libRsbuildConfig = await composeLibRsbuildConfig( userConfig, + root, sharedPlugins, ); @@ -1412,9 +1415,13 @@ export async function composeCreateRsbuildConfig( export async function composeRsbuildEnvironments( rslibConfig: RslibConfig, -): Promise> { +): Promise<{ + environments: Record; + environmentWithInfos: RequireKey[]; +}> { const rsbuildConfigWithLibInfo = await composeCreateRsbuildConfig(rslibConfig); + const environmentWithInfos: RequireKey[] = []; // User provided ids should take precedence over generated ids. const usedIds = rsbuildConfigWithLibInfo @@ -1446,6 +1453,7 @@ export async function composeRsbuildEnvironments( for (const { format, id, config } of rsbuildConfigWithLibInfo) { const libId = typeof id === 'string' ? id : composeDefaultId(format); environments[libId] = config; + environmentWithInfos.push({ id: libId, format, config }); } const conflictIds = usedIds.filter( @@ -1457,7 +1465,7 @@ export async function composeRsbuildEnvironments( ); } - return environments; + return { environments, environmentWithInfos }; } export const pruneEnvironments = ( diff --git a/packages/core/src/css/cssConfig.ts b/packages/core/src/css/cssConfig.ts index b57feac32..fd4559a55 100644 --- a/packages/core/src/css/cssConfig.ts +++ b/packages/core/src/css/cssConfig.ts @@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; import path from 'node:path'; import type { CSSLoaderOptions, - RsbuildConfig, + EnvironmentConfig, RsbuildPlugin, } from '@rsbuild/core'; import { CSS_EXTENSIONS_PATTERN } from '../constant'; @@ -147,7 +147,7 @@ const pluginLibCss = (rootDir: string): RsbuildPlugin => ({ export const composeCssConfig = ( rootDir: string | null, bundle = true, -): RsbuildConfig => { +): EnvironmentConfig => { if (bundle || rootDir === null) { return {}; } diff --git a/packages/core/src/plugins/EntryChunkPlugin.ts b/packages/core/src/plugins/EntryChunkPlugin.ts index 0f183cada..c9377f74e 100644 --- a/packages/core/src/plugins/EntryChunkPlugin.ts +++ b/packages/core/src/plugins/EntryChunkPlugin.ts @@ -1,7 +1,7 @@ import { chmodSync } from 'node:fs'; import { createRequire } from 'node:module'; import { - type RsbuildConfig, + type EnvironmentConfig, type RsbuildPlugin, type Rspack, rspack, @@ -194,7 +194,7 @@ export const composeEntryChunkConfig = ({ enabledImportMetaUrlShim, }: { enabledImportMetaUrlShim: boolean; -}): RsbuildConfig => { +}): EnvironmentConfig => { return { plugins: [entryModuleLoaderRsbuildPlugin()], tools: { diff --git a/packages/core/src/types/config.ts b/packages/core/src/types/config.ts index 8a45c09ed..74f3b141e 100644 --- a/packages/core/src/types/config.ts +++ b/packages/core/src/types/config.ts @@ -1,4 +1,4 @@ -import type { RsbuildConfig, Rspack } from '@rsbuild/core'; +import type { EnvironmentConfig, RsbuildConfig, Rspack } from '@rsbuild/core'; import type { PluginDtsOptions } from 'rsbuild-plugin-dts'; import type { GetAsyncFunctionFromUnion } from './utils'; @@ -22,11 +22,11 @@ export type EcmaScriptVersion = FixedEcmaVersions | LatestEcmaVersions; export type RsbuildConfigWithLibInfo = { id?: string; format: Format; - config: RsbuildConfig; + config: EnvironmentConfig; }; export type RsbuildConfigEntry = NonNullable< - NonNullable['entry'] + NonNullable['entry'] >; export type RsbuildConfigEntryItem = RsbuildConfigEntry[string]; export type RspackResolver = GetAsyncFunctionFromUnion< @@ -34,7 +34,7 @@ export type RspackResolver = GetAsyncFunctionFromUnion< >; export type RsbuildConfigOutputTarget = NonNullable< - RsbuildConfig['output'] + EnvironmentConfig['output'] >['target']; export type Syntax = @@ -107,7 +107,7 @@ export type Redirect = { // dts?: DtsRedirect; }; -export interface LibConfig extends RsbuildConfig { +export interface LibConfig extends EnvironmentConfig { /** * The unique identifier of the library. * @defaultValue `undefined` @@ -201,7 +201,7 @@ export interface LibConfig extends RsbuildConfig { umdName?: string; } -export type LibOnlyConfig = Omit; +export type LibOnlyConfig = Omit; export interface RslibConfig extends RsbuildConfig { lib: LibConfig[]; diff --git a/packages/core/src/types/utils.ts b/packages/core/src/types/utils.ts index ac9b0bb8f..0b4209c92 100644 --- a/packages/core/src/types/utils.ts +++ b/packages/core/src/types/utils.ts @@ -11,6 +11,8 @@ export type DeepRequired = Required<{ [K in keyof T]: T[K] extends Required ? T[K] : DeepRequired; }>; +export type RequireKey = T & { [P in K]-?: T[P] }; + export type ExcludesFalse = (x: T | false | undefined | null) => x is T; export type GetAsyncFunctionFromUnion = T extends ( diff --git a/packages/core/src/utils/syntax.ts b/packages/core/src/utils/syntax.ts index 7ab9aa0c9..b07ab1236 100644 --- a/packages/core/src/utils/syntax.ts +++ b/packages/core/src/utils/syntax.ts @@ -1,4 +1,4 @@ -import type { RsbuildConfig, Rspack } from '@rsbuild/core'; +import type { EnvironmentConfig, Rspack } from '@rsbuild/core'; import type { EcmaScriptVersion, FixedEcmaVersions, @@ -191,8 +191,10 @@ export function transformSyntaxToRspackTarget( export function transformSyntaxToBrowserslist( syntax: Syntax, - target: NonNullable['target'], -): NonNullable['overrideBrowserslist']> { + target: NonNullable['target'], +): NonNullable< + NonNullable['overrideBrowserslist'] +> { const handleSyntaxItem = ( syntaxItem: EcmaScriptVersion | string, ): string[] => { diff --git a/packages/core/tests/__snapshots__/config.test.ts.snap b/packages/core/tests/__snapshots__/config.test.ts.snap index 4fe3fc0ed..b83bea934 100644 --- a/packages/core/tests/__snapshots__/config.test.ts.snap +++ b/packages/core/tests/__snapshots__/config.test.ts.snap @@ -7,7 +7,6 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1 "dev": { "progressBar": false, }, - "mode": "production", "output": { "dataUriLimit": 0, "distPath": { @@ -249,7 +248,6 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1 "dev": { "progressBar": false, }, - "mode": "production", "output": { "dataUriLimit": 0, "distPath": { @@ -483,7 +481,6 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1 "dev": { "progressBar": false, }, - "mode": "production", "output": { "distPath": { "css": "./", diff --git a/packages/core/tests/config.test.ts b/packages/core/tests/config.test.ts index a353b311c..ebf27a9c6 100644 --- a/packages/core/tests/config.test.ts +++ b/packages/core/tests/config.test.ts @@ -415,7 +415,8 @@ describe('id', () => { ], }; - const composedRsbuildConfig = await composeRsbuildEnvironments(rslibConfig); + const { environments: composedRsbuildConfig } = + await composeRsbuildEnvironments(rslibConfig); expect(Object.keys(composedRsbuildConfig)).toMatchInlineSnapshot(` [ @@ -452,7 +453,8 @@ describe('id', () => { ], }; - const composedRsbuildConfig = await composeRsbuildEnvironments(rslibConfig); + const { environments: composedRsbuildConfig } = + await composeRsbuildEnvironments(rslibConfig); expect(Object.keys(composedRsbuildConfig)).toMatchInlineSnapshot(` [ "esm1", diff --git a/packages/plugin-dts/src/index.ts b/packages/plugin-dts/src/index.ts index b7fba3def..6ec70e5dc 100644 --- a/packages/plugin-dts/src/index.ts +++ b/packages/plugin-dts/src/index.ts @@ -1,7 +1,11 @@ import { type ChildProcess, fork } from 'node:child_process'; import { dirname, extname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { type RsbuildConfig, type RsbuildPlugin, logger } from '@rsbuild/core'; +import { + type EnvironmentConfig, + type RsbuildPlugin, + logger, +} from '@rsbuild/core'; import ts from 'typescript'; import { loadTsconfig, processSourceEntry } from './utils'; @@ -39,8 +43,8 @@ export type DtsGenOptions = PluginDtsOptions & { tsconfigPath: string; tsConfigResult: ts.ParsedCommandLine; rootDistPath: string; - cleanDistPath: NonNullable['cleanDistPath']; - userExternals?: NonNullable['externals']; + cleanDistPath: NonNullable['cleanDistPath']; + userExternals?: NonNullable['externals']; }; interface TaskResult { diff --git a/packages/plugin-dts/src/utils.ts b/packages/plugin-dts/src/utils.ts index ff93bfa25..c22729570 100644 --- a/packages/plugin-dts/src/utils.ts +++ b/packages/plugin-dts/src/utils.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import fsP from 'node:fs/promises'; import { platform } from 'node:os'; import path, { basename, dirname, join, relative, resolve } from 'node:path'; -import { type RsbuildConfig, logger } from '@rsbuild/core'; +import { type EnvironmentConfig, logger } from '@rsbuild/core'; import MagicString from 'magic-string'; import color from 'picocolors'; import { convertPathToPattern, glob } from 'tinyglobby'; @@ -167,7 +167,7 @@ export async function processDtsFiles( export function processSourceEntry( bundle: boolean, - entryConfig: NonNullable['entry'], + entryConfig: NonNullable['entry'], ): DtsEntry { if (!bundle) { return { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4200510bf..2e2a68170 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -568,6 +568,8 @@ importers: tests/integration/cli/inspect: {} + tests/integration/cli/mf-dev: {} + tests/integration/copy: {} tests/integration/decorators/default: {} @@ -702,7 +704,9 @@ importers: specifier: ^1.2.0 version: 1.2.0(@rsbuild/core@1.1.12) - tests/integration/plugins: {} + tests/integration/plugins/basic: {} + + tests/integration/plugins/mf-dev: {} tests/integration/polyfill: dependencies: diff --git a/tests/integration/cli/build/build.test.ts b/tests/integration/cli/build/build.test.ts index e52d77055..c10a4ed3b 100644 --- a/tests/integration/cli/build/build.test.ts +++ b/tests/integration/cli/build/build.test.ts @@ -77,12 +77,14 @@ describe('build command', async () => { cwd: __dirname, }); - const files = await globContentJSON(path.join(__dirname, 'dist')); + const files = await globContentJSON( + path.join(__dirname, 'custom-root/dist'), + ); const fileNames = Object.keys(files).sort(); expect(fileNames).toMatchInlineSnapshot(` [ - "/tests/integration/cli/build/dist/root/index.cjs", - "/tests/integration/cli/build/dist/root/index.js", + "/tests/integration/cli/build/custom-root/dist/root/index.cjs", + "/tests/integration/cli/build/custom-root/dist/root/index.js", ] `); }); diff --git a/tests/integration/cli/build/custom-root/rslib.config.ts b/tests/integration/cli/build/custom-root/rslib.config.ts index 3285ebec0..c34299196 100644 --- a/tests/integration/cli/build/custom-root/rslib.config.ts +++ b/tests/integration/cli/build/custom-root/rslib.config.ts @@ -1,3 +1,4 @@ +import { join } from 'node:path'; import { defineConfig } from '@rslib/core'; import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; @@ -18,4 +19,9 @@ export default defineConfig({ }, }), ], + source: { + entry: { + index: join(__dirname, '../src/index.ts'), + }, + }, }); diff --git a/tests/integration/cli/mf-dev/dev.test.ts b/tests/integration/cli/mf-dev/dev.test.ts new file mode 100644 index 000000000..bc7fd79b2 --- /dev/null +++ b/tests/integration/cli/mf-dev/dev.test.ts @@ -0,0 +1,44 @@ +import { exec } from 'node:child_process'; +import { join } from 'node:path'; +import { describe } from 'node:test'; +import fse, { existsSync } from 'fs-extra'; +import { awaitFileExists } from 'test-helper'; +import { expect, test } from 'vitest'; + +const distFolder = join(__dirname, 'dist'); + +describe('mf-dev', () => { + test('mf-dev --lib', async () => { + const fixturePath = join(__dirname); + fse.removeSync(distFolder); + const distPath = join(distFolder, 'mf0', 'index.js'); + + const childProcess = exec('npx rslib mf-dev --lib mf0', { + cwd: fixturePath, + }); + + await awaitFileExists(distPath); + + expect(existsSync(distPath)).toBe(true); + childProcess.kill(); + }); + + test('mf-dev --lib multiple', async () => { + const fixturePath = join(__dirname); + fse.removeSync(distFolder); + const distPath1 = join(distFolder, 'mf1', 'index.js'); + const distPath2 = join(distFolder, 'mf2', 'index.js'); + + const childProcess = exec('npx rslib mf-dev --lib mf1 --lib mf2', { + cwd: fixturePath, + }); + + await awaitFileExists(distPath1); + await awaitFileExists(distPath2); + + expect(existsSync(distPath1)).toBe(true); + expect(existsSync(distPath2)).toBe(true); + + childProcess.kill(); + }); +}); diff --git a/tests/integration/plugins/package.json b/tests/integration/cli/mf-dev/package.json similarity index 68% rename from tests/integration/plugins/package.json rename to tests/integration/cli/mf-dev/package.json index e89a7a76b..c6b058e87 100644 --- a/tests/integration/plugins/package.json +++ b/tests/integration/cli/mf-dev/package.json @@ -1,5 +1,5 @@ { - "name": "plugins-test", + "name": "cli-mf-dev-test", "version": "1.0.0", "private": true, "type": "module" diff --git a/tests/integration/cli/mf-dev/rslib.config.ts b/tests/integration/cli/mf-dev/rslib.config.ts new file mode 100644 index 000000000..958ccfc2f --- /dev/null +++ b/tests/integration/cli/mf-dev/rslib.config.ts @@ -0,0 +1,37 @@ +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + { + format: 'mf', + output: { + distPath: { + root: 'dist/mf0', + }, + }, + }, + { + format: 'mf', + output: { + distPath: { + root: 'dist/mf1', + }, + }, + }, + { + id: 'mf2', + format: 'mf', + output: { + distPath: { + root: 'dist/mf2', + }, + }, + }, + ], + plugins: [ + pluginModuleFederation({ + name: 'test', + }), + ], +}); diff --git a/tests/integration/cli/mf-dev/src/index.ts b/tests/integration/cli/mf-dev/src/index.ts new file mode 100644 index 000000000..3329a7d97 --- /dev/null +++ b/tests/integration/cli/mf-dev/src/index.ts @@ -0,0 +1 @@ +export const foo = 'foo'; diff --git a/tests/integration/plugins/basic/package.json b/tests/integration/plugins/basic/package.json new file mode 100644 index 000000000..64bab199e --- /dev/null +++ b/tests/integration/plugins/basic/package.json @@ -0,0 +1,6 @@ +{ + "name": "plugins-basic-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/plugins/rslib.config.ts b/tests/integration/plugins/basic/rslib.config.ts similarity index 100% rename from tests/integration/plugins/rslib.config.ts rename to tests/integration/plugins/basic/rslib.config.ts diff --git a/tests/integration/plugins/src/index.ts b/tests/integration/plugins/basic/src/index.ts similarity index 100% rename from tests/integration/plugins/src/index.ts rename to tests/integration/plugins/basic/src/index.ts diff --git a/tests/integration/plugins/index.test.ts b/tests/integration/plugins/index.test.ts index 5fac540ba..1881aaa56 100644 --- a/tests/integration/plugins/index.test.ts +++ b/tests/integration/plugins/index.test.ts @@ -1,12 +1,32 @@ +import { exec } from 'node:child_process'; import fs from 'node:fs'; -import { buildAndGetResults } from 'test-helper'; +import { join } from 'node:path'; +import { awaitFileExists, buildAndGetResults } from 'test-helper'; import { expect, test } from 'vitest'; -import { distIndex } from './rslib.config'; +import { distIndex } from './basic/rslib.config'; +import { plugin1Path, plugin2Path } from './mf-dev/rslib.config'; test('should run shared plugins only once', async () => { - const fixturePath = __dirname; + const fixturePath = join(__dirname, 'basic'); await buildAndGetResults({ fixturePath }); const content = fs.readFileSync(distIndex, 'utf-8'); expect(content).toEqual('count: 1'); }); + +test('should merge plugins correctly', async () => { + const fixturePath = join(__dirname, 'mf-dev'); + const childProcess = exec('npx rslib mf-dev', { + cwd: fixturePath, + }); + + await awaitFileExists(plugin1Path); + await awaitFileExists(plugin2Path); + + const content1 = fs.readFileSync(plugin1Path, 'utf-8'); + const content2 = fs.readFileSync(plugin2Path, 'utf-8'); + expect(content1).toEqual('plugin1 count: 1'); + expect(content2).toEqual('plugin2'); + + childProcess.kill(); +}); diff --git a/tests/integration/plugins/mf-dev/package.json b/tests/integration/plugins/mf-dev/package.json new file mode 100644 index 000000000..4a5d80789 --- /dev/null +++ b/tests/integration/plugins/mf-dev/package.json @@ -0,0 +1,6 @@ +{ + "name": "plugins-mf-dev-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/plugins/mf-dev/rslib.config.ts b/tests/integration/plugins/mf-dev/rslib.config.ts new file mode 100644 index 000000000..4d539d437 --- /dev/null +++ b/tests/integration/plugins/mf-dev/rslib.config.ts @@ -0,0 +1,37 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import type { RsbuildPlugin } from '@rsbuild/core'; +import { defineConfig } from '@rslib/core'; + +let count = 0; +export const plugin1Path = path.resolve(__dirname, 'dist/plugin1.txt'); +export const plugin2Path = path.resolve(__dirname, 'dist/plugin2.txt'); + +const testPlugin1: RsbuildPlugin = { + name: 'test1', + setup(api) { + api.onDevCompileDone(() => { + fs.writeFileSync(plugin1Path, `plugin1 count: ${++count}`); + }); + }, +}; + +const testPlugin2: RsbuildPlugin = { + name: 'test2', + setup(api) { + api.onDevCompileDone(() => { + fs.writeFileSync(plugin2Path, 'plugin2'); + }); + }, +}; + +export default defineConfig({ + lib: [ + { + format: 'mf', + plugins: [pluginModuleFederation({ name: 'test-plugins' }), testPlugin2], + }, + ], + plugins: [testPlugin1], +}); diff --git a/tests/integration/plugins/mf-dev/src/index.ts b/tests/integration/plugins/mf-dev/src/index.ts new file mode 100644 index 000000000..54cc258f8 --- /dev/null +++ b/tests/integration/plugins/mf-dev/src/index.ts @@ -0,0 +1 @@ +export const test = 'hello'; diff --git a/tests/integration/server/index.test.ts b/tests/integration/server/index.test.ts index e80566952..91495b4df 100644 --- a/tests/integration/server/index.test.ts +++ b/tests/integration/server/index.test.ts @@ -16,13 +16,13 @@ describe('server config', async () => { expect(logoExists).toBe(false); }); - test('mf dev command', async () => { + test('mf-dev command', async () => { const fixturePath = join(__dirname, 'mf-dev'); const distPath = join(fixturePath, 'dist'); const rsbuildConfigFile = join(distPath, '.rsbuild/rsbuild.config.mjs'); fse.removeSync(distPath); - const childProcess = exec('npx rslib mf dev', { + const childProcess = exec('npx rslib mf-dev', { cwd: fixturePath, env: { ...process.env, @@ -32,12 +32,9 @@ describe('server config', async () => { await awaitFileExists(rsbuildConfigFile); - // Check if the server config is merged correctly const rsbuildConfigContent = await fse.readFile(rsbuildConfigFile, 'utf-8'); - expect(rsbuildConfigContent).toContain(`base: '/'`); expect(rsbuildConfigContent).toContain('open: true'); - expect(rsbuildConfigContent).toContain('port: 3002'); - expect(rsbuildConfigContent).toContain('printUrls: false'); + expect(rsbuildConfigContent).toContain('port: 3001'); childProcess.kill(); }); diff --git a/tests/integration/server/mf-dev/rslib.config.ts b/tests/integration/server/mf-dev/rslib.config.ts index 3ad7e4e96..a483a3f36 100644 --- a/tests/integration/server/mf-dev/rslib.config.ts +++ b/tests/integration/server/mf-dev/rslib.config.ts @@ -5,10 +5,6 @@ export default defineConfig({ lib: [ { format: 'mf', - server: { - port: 3002, - printUrls: false, - }, }, ], server: { From 2000511c12c8d381994729f53b718c6bd916e269 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Sun, 22 Dec 2024 22:13:42 +0800 Subject: [PATCH 2/9] chore: update --- packages/core/src/cli/mf.ts | 12 ++++---- packages/plugin-dts/src/index.ts | 10 ++----- packages/plugin-dts/src/utils.ts | 4 +-- website/docs/en/config/lib/index.mdx | 2 +- .../en/guide/advanced/module-federation.mdx | 8 ++--- website/docs/en/guide/basic/cli.mdx | 21 +++++++------- website/docs/zh/config/lib/index.mdx | 29 +++++++++++++++++++ .../zh/guide/advanced/module-federation.mdx | 8 ++--- website/docs/zh/guide/basic/cli.mdx | 13 +++++---- 9 files changed, 67 insertions(+), 40 deletions(-) diff --git a/packages/core/src/cli/mf.ts b/packages/core/src/cli/mf.ts index b24dde1de..8dad91a3b 100644 --- a/packages/core/src/cli/mf.ts +++ b/packages/core/src/cli/mf.ts @@ -14,11 +14,11 @@ export async function startMFDevServer( } async function initMFRsbuild( - rslibConfig: RslibConfig, + config: RslibConfig, options: Pick = {}, ): Promise { const { environments, environmentWithInfos } = - await composeRsbuildEnvironments(rslibConfig); + await composeRsbuildEnvironments(config); const selectedEnvironmentIds = environmentWithInfos .filter((env) => { @@ -42,13 +42,13 @@ async function initMFRsbuild( const rsbuildInstance = await createRsbuild({ rsbuildConfig: { mode: 'development', - root: rslibConfig.root, - plugins: rslibConfig.plugins, + root: config.root, + plugins: config.plugins, dev: { - ...(rslibConfig.dev ?? {}), + ...(config.dev ?? {}), writeToDisk: true, }, - server: rslibConfig.server, + server: config.server, tools: { rspack: { optimization: { diff --git a/packages/plugin-dts/src/index.ts b/packages/plugin-dts/src/index.ts index 6ec70e5dc..b7fba3def 100644 --- a/packages/plugin-dts/src/index.ts +++ b/packages/plugin-dts/src/index.ts @@ -1,11 +1,7 @@ import { type ChildProcess, fork } from 'node:child_process'; import { dirname, extname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { - type EnvironmentConfig, - type RsbuildPlugin, - logger, -} from '@rsbuild/core'; +import { type RsbuildConfig, type RsbuildPlugin, logger } from '@rsbuild/core'; import ts from 'typescript'; import { loadTsconfig, processSourceEntry } from './utils'; @@ -43,8 +39,8 @@ export type DtsGenOptions = PluginDtsOptions & { tsconfigPath: string; tsConfigResult: ts.ParsedCommandLine; rootDistPath: string; - cleanDistPath: NonNullable['cleanDistPath']; - userExternals?: NonNullable['externals']; + cleanDistPath: NonNullable['cleanDistPath']; + userExternals?: NonNullable['externals']; }; interface TaskResult { diff --git a/packages/plugin-dts/src/utils.ts b/packages/plugin-dts/src/utils.ts index c22729570..ff93bfa25 100644 --- a/packages/plugin-dts/src/utils.ts +++ b/packages/plugin-dts/src/utils.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import fsP from 'node:fs/promises'; import { platform } from 'node:os'; import path, { basename, dirname, join, relative, resolve } from 'node:path'; -import { type EnvironmentConfig, logger } from '@rsbuild/core'; +import { type RsbuildConfig, logger } from '@rsbuild/core'; import MagicString from 'magic-string'; import color from 'picocolors'; import { convertPathToPattern, glob } from 'tinyglobby'; @@ -167,7 +167,7 @@ export async function processDtsFiles( export function processSourceEntry( bundle: boolean, - entryConfig: NonNullable['entry'], + entryConfig: NonNullable['entry'], ): DtsEntry { if (!bundle) { return { diff --git a/website/docs/en/config/lib/index.mdx b/website/docs/en/config/lib/index.mdx index 48fb0254a..93b6d3b80 100644 --- a/website/docs/en/config/lib/index.mdx +++ b/website/docs/en/config/lib/index.mdx @@ -3,7 +3,7 @@ - **Type:** ```ts -interface LibConfig extends RsbuildConfig { +interface LibConfig extends EnvironmentConfig { format?: Format; bundle?: boolean; autoExtension?: boolean; diff --git a/website/docs/en/guide/advanced/module-federation.mdx b/website/docs/en/guide/advanced/module-federation.mdx index 73d85f23c..5217f177b 100644 --- a/website/docs/en/guide/advanced/module-federation.mdx +++ b/website/docs/en/guide/advanced/module-federation.mdx @@ -94,14 +94,14 @@ However, if you want this Rslib Module to consume other producers at the same ti Rslib support developing Module Federation Rslib project with a host application. -#### 1. Start `rslib mf dev` command of library +#### 1. Start `rslib mf-dev` command of library Adding the `dev` command to the `package.json` file: ```json title="package.json" { "scripts": { - "dev": "rslib mf dev" + "dev": "rslib mf-dev" } } ``` @@ -152,14 +152,14 @@ Then start the host app with `rsbuild dev`. Rslib support developing Module Federation Rslib project with Storybook. -#### 1. Start `rslib mf dev` command of library +#### 1. Start `rslib mf-dev` command of library Adding the `dev` command to the `package.json` file: ```json title="package.json" { "scripts": { - "dev": "rslib mf dev" + "dev": "rslib mf-dev" } } ``` diff --git a/website/docs/en/guide/basic/cli.mdx b/website/docs/en/guide/basic/cli.mdx index 93b681d63..b90506f16 100644 --- a/website/docs/en/guide/basic/cli.mdx +++ b/website/docs/en/guide/basic/cli.mdx @@ -16,14 +16,14 @@ The output is shown below: Usage: rslib [options] Options: - -V, --version output the version number - -h, --help display help for command + -V, --version output the version number + -h, --help display help for command Commands: - build [options] build the library for production - inspect [options] inspect the Rsbuild / Rspack configs of Rslib projects - mf [options] start Rsbuild dev server of Module Federation format - help [command] display help for command + build [options] build the library for production + inspect [options] inspect the Rsbuild / Rspack configs of Rslib projects + mf-dev [options] start Rsbuild dev server of Module Federation format + help [command] display help for command ``` ## rslib build @@ -40,7 +40,7 @@ Options: -r --root specify the project root directory, can be an absolute path or a path relative to cwd --env-mode specify the env mode to load the `.env.[mode]` file --env-dir specify the directory to load `.env` files - --lib build the specified library (may be repeated) + --lib specify the library (repeatable, e.g. --lib esm --lib cjs) -w --watch turn on watch mode, watch for changes and rebuild -h, --help display help for command ``` @@ -149,7 +149,7 @@ Options: -r --root specify the project root directory, can be an absolute path or a path relative to cwd --env-mode specify the env mode to load the `.env.[mode]` file --env-dir specify the directory to load `.env` files - --lib inspect the specified library (may be repeated) + --lib specify the library (repeatable, e.g. --lib esm --lib cjs) --output specify inspect content output path (default: ".rsbuild") --verbose show full function definitions in output -h, --help display help for command @@ -192,9 +192,9 @@ Inspect config succeed, open following files to view the content: - Rspack Config (cjs): /project/dist/.rsbuild/rspack.config.cjs.mjs ``` -## rslib mf dev +## rslib mf-dev -The `rslib mf dev` command is utilized to start Rsbuild dev server for the [Module Federation](/guide/advanced/module-federation) format. +The `rslib mf-dev` command is utilized to start Rsbuild dev server for the [Module Federation](/guide/advanced/module-federation) format. This enables you to develop and debug your mf format module within the host app. @@ -208,6 +208,7 @@ Options: -r --root specify the project root directory, can be an absolute path or a path relative to cwd --env-mode specify the env mode to load the `.env.[mode]` file --env-dir specify the directory to load `.env` files + --lib specify the library (repeatable, e.g. --lib esm --lib cjs) -h, --help display help for command ``` diff --git a/website/docs/zh/config/lib/index.mdx b/website/docs/zh/config/lib/index.mdx index b034987cf..4b2510a75 100644 --- a/website/docs/zh/config/lib/index.mdx +++ b/website/docs/zh/config/lib/index.mdx @@ -1 +1,30 @@ # Lib 配置 + +- **类型:** + +```ts +interface LibConfig extends EnvironmentConfig { + format?: Format; + bundle?: boolean; + autoExtension?: boolean; + autoExternal?: AutoExternal; + redirect?: Redirect; + syntax?: Syntax; + externalHelpers?: boolean; + banner?: BannerAndFooter; + footer?: BannerAndFooter; + shims?: Shims; + dts?: Dts; + umdName?: string; +} + +interface RslibConfig extends RsbuildConfig { + lib: LibConfig[]; +} +``` + +- **默认值:** `undefined` + +- **必选:** `true` + +`lib` 配置是一个对象数组,每个对象代表一组不同的配置。这些配置包括所有 Rsbuild 配置以及 Rslib 特定的配置,可以生成不同格式的产物。 diff --git a/website/docs/zh/guide/advanced/module-federation.mdx b/website/docs/zh/guide/advanced/module-federation.mdx index 04a8db24f..979661411 100644 --- a/website/docs/zh/guide/advanced/module-federation.mdx +++ b/website/docs/zh/guide/advanced/module-federation.mdx @@ -94,14 +94,14 @@ export default defineConfig({ Rslib 支持宿主应用和 Rslib 模块联邦项目同时开发。 -#### 1. 启动库的 `rslib mf dev` 命令 +#### 1. 启动库的 `rslib mf-dev` 命令 添加 `dev` 命令在 `package.json` 文件: ```json title="package.json" { "scripts": { - "dev": "rslib mf dev" + "dev": "rslib mf-dev" } } ``` @@ -151,14 +151,14 @@ export default defineConfig({ Rslib 支持使用 Storybook 开发 Rslib 模块联邦项目。 -#### 1. 启动库的 `rslib mf dev` 命令 +#### 1. 启动库的 `rslib mf-dev` 命令 添加 `dev` 命令在 `package.json` 文件: ```json title="package.json" { "scripts": { - "dev": "rslib mf dev" + "dev": "rslib mf-dev" } } ``` diff --git a/website/docs/zh/guide/basic/cli.mdx b/website/docs/zh/guide/basic/cli.mdx index 34040b08a..bd31387ab 100644 --- a/website/docs/zh/guide/basic/cli.mdx +++ b/website/docs/zh/guide/basic/cli.mdx @@ -22,7 +22,7 @@ Options: Commands: build [options] 构建用于生产环境的产物 inspect [options] 检查 Rslib 项目的 Rsbuild 配置和 Rspack 配置 - mf [options] 为 Module Federation 格式的库启用 Rsbuild 开发服务器。 + mf-dev [options] 为 Module Federation 格式的库启用 Rsbuild 开发服务器。 help [command] 显示命令帮助 ``` @@ -40,7 +40,7 @@ Options: -r --root 指定项目根目录,可以是绝对路径或者相对于 cwd 的路径 --env-mode 指定 env 模式来加载 `.env.[mode]` 文件 --env-dir 指定目录来加载 `.env` 文件 - --lib 仅构建指定的库(可以重复) + --lib 指定库(可重复,例如 --lib esm --lib cjs) -w --watch 开启 watch 模式, 监听文件变更并重新构建 -h, --help 显示命令帮助 ``` @@ -149,8 +149,8 @@ Options: -r --root 指定项目根目录,可以是绝对路径或者相对于 cwd 的路径 --env-mode 指定 env 模式来加载 `.env.[mode]` 文件 --env-dir 指定目录来加载 `.env` 文件 - --lib 检查指定的库(可以重复) - --output 指定检查内容输出路径(默认:".rsbuild") + --lib 指定库(可重复,例如 --lib esm --lib cjs) + --output 指定检查内容输出路径(默认:".rsbuild") --verbose 在输出中显示完整的函数定义 -h, --help 显示命令帮助 ``` @@ -192,9 +192,9 @@ Inspect config succeed, open following files to view the content: - Rspack Config (cjs): /project/dist/.rsbuild/rspack.config.cjs.mjs ``` -## rslib mf dev +## rslib mf-dev -`rslib mf dev` 命令用于为 [Module Federation](/guide/advanced/module-federation) 格式的库启用 Rsbuild 开发服务器。 +`rslib mf-dev` 命令用于为 [Module Federation](/guide/advanced/module-federation) 格式的库启用 Rsbuild 开发服务器。 这允许你在 host 应用中访问和调试 mf 格式的模块。 @@ -208,6 +208,7 @@ Options: -r --root 指定项目根目录,可以是绝对路径或者相对于 cwd 的路径 --env-mode 指定 env 模式来加载 `.env.[mode]` 文件 --env-dir 指定目录来加载 `.env` 文件 + --lib 指定库(可重复,例如 --lib esm --lib cjs) -h, --help 显示命令帮助 ``` From 9a14e181cbd257546d886efa286d29e3b7819e48 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Sun, 22 Dec 2024 22:18:58 +0800 Subject: [PATCH 3/9] chore: update --- website/docs/en/guide/basic/cli.mdx | 2 +- website/docs/zh/guide/basic/cli.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/en/guide/basic/cli.mdx b/website/docs/en/guide/basic/cli.mdx index b90506f16..f587005e6 100644 --- a/website/docs/en/guide/basic/cli.mdx +++ b/website/docs/en/guide/basic/cli.mdx @@ -199,7 +199,7 @@ The `rslib mf-dev` command is utilized to start Rsbuild dev server for the [Modu This enables you to develop and debug your mf format module within the host app. ```text -Usage: rslib mf [options] +Usage: rslib mf-dev [options] start Rsbuild dev server of Module Federation format diff --git a/website/docs/zh/guide/basic/cli.mdx b/website/docs/zh/guide/basic/cli.mdx index bd31387ab..924892157 100644 --- a/website/docs/zh/guide/basic/cli.mdx +++ b/website/docs/zh/guide/basic/cli.mdx @@ -199,7 +199,7 @@ Inspect config succeed, open following files to view the content: 这允许你在 host 应用中访问和调试 mf 格式的模块。 ```text -Usage: rslib mf [options] +Usage: rslib mf-dev [options] 为 Module Federation 格式的库启用 Rsbuild 开发服务器。 From 2a918858977c9596d303d33c1247acb349fe7e46 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Mon, 23 Dec 2024 17:40:24 +0800 Subject: [PATCH 4/9] chore: update --- .../module-federation/mf-react-component/rslib.config.ts | 8 ++++---- website/docs/en/guide/advanced/module-federation.mdx | 8 ++++---- website/docs/zh/guide/advanced/module-federation.mdx | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/module-federation/mf-react-component/rslib.config.ts b/examples/module-federation/mf-react-component/rslib.config.ts index 2f3b6e792..998c4de97 100644 --- a/examples/module-federation/mf-react-component/rslib.config.ts +++ b/examples/module-federation/mf-react-component/rslib.config.ts @@ -34,10 +34,6 @@ export default defineConfig({ dev: { assetPrefix: 'http://localhost:3001/mf', }, - // just for dev - server: { - port: 3001, - }, plugins: [ pluginModuleFederation({ name: 'rslib_provider', @@ -56,5 +52,9 @@ export default defineConfig({ ], }, ], + // just for dev + server: { + port: 3001, + }, plugins: [pluginReact()], }); diff --git a/website/docs/en/guide/advanced/module-federation.mdx b/website/docs/en/guide/advanced/module-federation.mdx index 5217f177b..9b33f51a1 100644 --- a/website/docs/en/guide/advanced/module-federation.mdx +++ b/website/docs/en/guide/advanced/module-federation.mdx @@ -51,10 +51,6 @@ export default defineConfig({ dev: { assetPrefix: 'http://localhost:3001/mf', }, - // for Storybook to dev - server: { - port: 3001, - }, plugins: [ pluginModuleFederation({ name: 'rslib_provider', @@ -75,6 +71,10 @@ export default defineConfig({ ], }, ], + // for Storybook to dev + server: { + port: 3001, + }, output: { target: 'web', }, diff --git a/website/docs/zh/guide/advanced/module-federation.mdx b/website/docs/zh/guide/advanced/module-federation.mdx index 979661411..3af43d191 100644 --- a/website/docs/zh/guide/advanced/module-federation.mdx +++ b/website/docs/zh/guide/advanced/module-federation.mdx @@ -51,10 +51,6 @@ export default defineConfig({ dev: { assetPrefix: 'http://localhost:3001/mf', }, - // Storybook 在 dev 下使用 - server: { - port: 3001, - }, plugins: [ pluginModuleFederation({ name: 'rslib_provider', @@ -75,6 +71,10 @@ export default defineConfig({ ], }, ], + // Storybook 在 dev 下使用 + server: { + port: 3001, + }, output: { target: 'web', }, From 5ef1bf43755b06032335783f7dfdd17fd8ce89f5 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Mon, 23 Dec 2024 18:46:37 +0800 Subject: [PATCH 5/9] chore: update --- tests/playwright.config.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/playwright.config.ts b/tests/playwright.config.ts index f7d979370..758464e4c 100644 --- a/tests/playwright.config.ts +++ b/tests/playwright.config.ts @@ -13,17 +13,17 @@ export default defineConfig({ webServer: [ { command: 'cd ../examples/module-federation && npm run dev:host', - url: 'http://127.0.0.1:3000', + url: 'http://localhost:3000', timeout: 120 * 1000, }, { command: 'cd ../examples/module-federation && npm run serve:lib', - url: 'http://127.0.0.1:3001', + url: 'http://localhost:3001', timeout: 120 * 1000, }, { command: 'cd ../examples/module-federation && npm run dev:remote', - url: 'http://127.0.0.1:3002', + url: 'http://localhost:3002', timeout: 120 * 1000, }, ], From 330e8cf66e48fcddcdc5f7118c337f80dfbccdb7 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Mon, 23 Dec 2024 19:04:45 +0800 Subject: [PATCH 6/9] chore: update --- tests/playwright.config.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/playwright.config.ts b/tests/playwright.config.ts index 758464e4c..fbe09ea5b 100644 --- a/tests/playwright.config.ts +++ b/tests/playwright.config.ts @@ -14,16 +14,19 @@ export default defineConfig({ { command: 'cd ../examples/module-federation && npm run dev:host', url: 'http://localhost:3000', + reuseExistingServer: !process.env.CI, timeout: 120 * 1000, }, { command: 'cd ../examples/module-federation && npm run serve:lib', url: 'http://localhost:3001', + reuseExistingServer: !process.env.CI, timeout: 120 * 1000, }, { command: 'cd ../examples/module-federation && npm run dev:remote', url: 'http://localhost:3002', + reuseExistingServer: !process.env.CI, timeout: 120 * 1000, }, ], From 32692517d6bcc5f6c03da3db218612b6e6e2a173 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Mon, 23 Dec 2024 19:15:15 +0800 Subject: [PATCH 7/9] chore: update --- tests/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/package.json b/tests/package.json index cd34ed350..3d2f32b10 100644 --- a/tests/package.json +++ b/tests/package.json @@ -4,7 +4,7 @@ "type": "module", "scripts": { "test:benchmark": "vitest bench", - "test:e2e": "playwright test --pass-with-no-tests" + "test:e2e": "cross-env DEBUG=pw:webserver playwright test --pass-with-no-tests" }, "dependencies": { "react": "^19.0.0", From 5e9b176e2caa1b3cb2f35c437c3ea270c9f0a786 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Mon, 23 Dec 2024 20:01:04 +0800 Subject: [PATCH 8/9] chore: update --- tests/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/package.json b/tests/package.json index 3d2f32b10..e3fd60edc 100644 --- a/tests/package.json +++ b/tests/package.json @@ -4,7 +4,7 @@ "type": "module", "scripts": { "test:benchmark": "vitest bench", - "test:e2e": "cross-env DEBUG=pw:webserver playwright test --pass-with-no-tests" + "test:e2e": "lsof -i:3000 && lsof -i:3001 && lsof -i:3002 && cross-env DEBUG=pw:webserver playwright test --pass-with-no-tests" }, "dependencies": { "react": "^19.0.0", From 7e8bc0300a17c2ade78f5d476c447be51d0138ff Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Mon, 23 Dec 2024 20:42:04 +0800 Subject: [PATCH 9/9] chore: update --- tests/integration/cli/mf-dev/rslib.config.ts | 3 +++ tests/integration/plugins/mf-dev/rslib.config.ts | 3 +++ tests/integration/server/index.test.ts | 2 +- tests/integration/server/mf-dev/rslib.config.ts | 2 +- tests/package.json | 2 +- tests/playwright.config.ts | 3 --- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/integration/cli/mf-dev/rslib.config.ts b/tests/integration/cli/mf-dev/rslib.config.ts index 958ccfc2f..8db39f5f6 100644 --- a/tests/integration/cli/mf-dev/rslib.config.ts +++ b/tests/integration/cli/mf-dev/rslib.config.ts @@ -29,6 +29,9 @@ export default defineConfig({ }, }, ], + server: { + port: 3007, + }, plugins: [ pluginModuleFederation({ name: 'test', diff --git a/tests/integration/plugins/mf-dev/rslib.config.ts b/tests/integration/plugins/mf-dev/rslib.config.ts index 4d539d437..74fbe8e34 100644 --- a/tests/integration/plugins/mf-dev/rslib.config.ts +++ b/tests/integration/plugins/mf-dev/rslib.config.ts @@ -33,5 +33,8 @@ export default defineConfig({ plugins: [pluginModuleFederation({ name: 'test-plugins' }), testPlugin2], }, ], + server: { + port: 3009, + }, plugins: [testPlugin1], }); diff --git a/tests/integration/server/index.test.ts b/tests/integration/server/index.test.ts index 91495b4df..6139f8b4b 100644 --- a/tests/integration/server/index.test.ts +++ b/tests/integration/server/index.test.ts @@ -34,7 +34,7 @@ describe('server config', async () => { const rsbuildConfigContent = await fse.readFile(rsbuildConfigFile, 'utf-8'); expect(rsbuildConfigContent).toContain('open: true'); - expect(rsbuildConfigContent).toContain('port: 3001'); + expect(rsbuildConfigContent).toContain('port: 3011'); childProcess.kill(); }); diff --git a/tests/integration/server/mf-dev/rslib.config.ts b/tests/integration/server/mf-dev/rslib.config.ts index a483a3f36..5bfa949f9 100644 --- a/tests/integration/server/mf-dev/rslib.config.ts +++ b/tests/integration/server/mf-dev/rslib.config.ts @@ -8,7 +8,7 @@ export default defineConfig({ }, ], server: { - port: 3001, + port: 3011, open: true, }, plugins: [ diff --git a/tests/package.json b/tests/package.json index e3fd60edc..cd34ed350 100644 --- a/tests/package.json +++ b/tests/package.json @@ -4,7 +4,7 @@ "type": "module", "scripts": { "test:benchmark": "vitest bench", - "test:e2e": "lsof -i:3000 && lsof -i:3001 && lsof -i:3002 && cross-env DEBUG=pw:webserver playwright test --pass-with-no-tests" + "test:e2e": "playwright test --pass-with-no-tests" }, "dependencies": { "react": "^19.0.0", diff --git a/tests/playwright.config.ts b/tests/playwright.config.ts index fbe09ea5b..758464e4c 100644 --- a/tests/playwright.config.ts +++ b/tests/playwright.config.ts @@ -14,19 +14,16 @@ export default defineConfig({ { command: 'cd ../examples/module-federation && npm run dev:host', url: 'http://localhost:3000', - reuseExistingServer: !process.env.CI, timeout: 120 * 1000, }, { command: 'cd ../examples/module-federation && npm run serve:lib', url: 'http://localhost:3001', - reuseExistingServer: !process.env.CI, timeout: 120 * 1000, }, { command: 'cd ../examples/module-federation && npm run dev:remote', url: 'http://localhost:3002', - reuseExistingServer: !process.env.CI, timeout: 120 * 1000, }, ],