From 2ed952a73c20794c9a0620fdcbb00811c3c6a8a3 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Fri, 9 May 2025 17:31:13 +0800 Subject: [PATCH 1/5] feat: format default to `'esm'` --- packages/core/src/config.ts | 30 ++++++------ packages/core/src/types/config.ts | 2 +- pnpm-lock.yaml | 6 ++- .../format/cjs-static-export/package.json | 6 +++ .../format/{ => default}/package.json | 2 +- .../format/default/rslib.config.ts | 37 ++++++++++++++ tests/integration/format/default/src/foo.js | 1 + tests/integration/format/default/src/index.js | 3 ++ .../format/import-meta-url/package.json | 6 +++ tests/integration/format/index.test.ts | 48 +++++++++++++++++++ tests/integration/minify/index.test.ts | 2 +- tests/scripts/shared.ts | 13 +++-- website/docs/en/config/lib/format.mdx | 3 +- website/docs/zh/config/lib/format.mdx | 3 +- 14 files changed, 133 insertions(+), 29 deletions(-) create mode 100644 tests/integration/format/cjs-static-export/package.json rename tests/integration/format/{ => default}/package.json (65%) create mode 100644 tests/integration/format/default/rslib.config.ts create mode 100644 tests/integration/format/default/src/foo.js create mode 100644 tests/integration/format/default/src/index.js create mode 100644 tests/integration/format/import-meta-url/package.json diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 3d61ef6b8..b0b20144a 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -841,6 +841,7 @@ const composeExternalsConfig = ( const composeAutoExtensionConfig = ( config: LibConfig, + format: Format, autoExtension: boolean, pkgJson?: PkgJson, ): { @@ -849,7 +850,7 @@ const composeAutoExtensionConfig = ( dtsExtension: string; } => { const { jsExtension, dtsExtension } = getDefaultExtension({ - format: config.format!, + format, pkgJson, autoExtension, }); @@ -1307,9 +1308,10 @@ const composeBundlelessExternalConfig = ( const composeDtsConfig = async ( libConfig: LibConfig, + format: Format, dtsExtension: string, ): Promise => { - const { format, autoExternal, banner, footer, redirect } = libConfig; + const { autoExternal, banner, footer, redirect } = libConfig; let { dts } = libConfig; @@ -1332,7 +1334,7 @@ const composeDtsConfig = async ( build: dts?.build, abortOnError: dts?.abortOnError, dtsExtension: dts?.autoExtension ? dtsExtension : '.d.ts', - autoExternal: getAutoExternalDefaultValue(format!, autoExternal), + autoExternal: getAutoExternalDefaultValue(format, autoExternal), banner: banner?.dts, footer: footer?.dts, redirect: redirect?.dts, @@ -1454,7 +1456,7 @@ async function composeLibRsbuildConfig( const cssModulesAuto = config.output?.cssModules?.auto ?? true; const { - format, + format = 'esm', shims, bundle = true, banner = {}, @@ -1466,11 +1468,11 @@ async function composeLibRsbuildConfig( umdName, } = config; const { rsbuildConfig: shimsConfig, enabledShims } = composeShimsConfig( - format!, + format, shims, ); const formatConfig = composeFormatConfig({ - format: format!, + format: format, pkgJson: pkgJson!, bundle, umdName, @@ -1480,14 +1482,14 @@ async function composeLibRsbuildConfig( pkgJson, ); const userExternalsConfig = composeExternalsConfig( - format!, + format, config.output?.externals, ); const { config: autoExtensionConfig, jsExtension, dtsExtension, - } = composeAutoExtensionConfig(config, autoExtension, pkgJson); + } = composeAutoExtensionConfig(config, format, autoExtension, pkgJson); const { entryConfig, outBase } = await composeEntryConfig( config.source?.entry!, config.bundle, @@ -1506,11 +1508,11 @@ async function composeLibRsbuildConfig( config: targetConfig, externalsConfig: targetExternalsConfig, target, - } = composeTargetConfig(config.output?.target, format!); + } = composeTargetConfig(config.output?.target, format); const syntaxConfig = composeSyntaxConfig(target, config?.syntax); const autoExternalConfig = composeAutoExternalConfig({ bundle, - format: format!, + format: format, autoExternal, pkgJson, userExternals: config.output?.externals, @@ -1522,15 +1524,15 @@ async function composeLibRsbuildConfig( banner?.css, footer?.css, ); - const assetConfig = composeAssetConfig(bundle, format!); + const assetConfig = composeAssetConfig(bundle, format); const entryChunkConfig = composeEntryChunkConfig({ enabledImportMetaUrlShim: enabledShims.cjs['import.meta.url'], contextToWatch: outBase, }); - const dtsConfig = await composeDtsConfig(config, dtsExtension); + const dtsConfig = await composeDtsConfig(config, format, dtsExtension); const externalsWarnConfig = composeExternalsWarnConfig( - format!, + format, userExternalsConfig?.output?.externals, autoExternalConfig?.output?.externals, ); @@ -1619,7 +1621,7 @@ export async function composeCreateRsbuildConfig( delete userConfig.output.externals; const config: RsbuildConfigWithLibInfo = { - format: libConfig.format!, + format: libConfig.format ?? 'esm', // The merge order represents the priority of the configuration // The priorities from high to low are as follows: // 1 - userConfig: users can configure any Rsbuild and Rspack config diff --git a/packages/core/src/types/config.ts b/packages/core/src/types/config.ts index 2551e112e..89f3928d9 100644 --- a/packages/core/src/types/config.ts +++ b/packages/core/src/types/config.ts @@ -215,7 +215,7 @@ export interface LibConfig extends EnvironmentConfig { id?: string; /** * Output format for the generated JavaScript files. - * @defaultValue `undefined` + * @defaultValue `'esm'` * @see {@link https://lib.rsbuild.dev/config/lib/format} */ format?: Format; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a4db11817..18a7da05a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -781,7 +781,11 @@ importers: specifier: ^4.17.16 version: 4.17.16 - tests/integration/format: {} + tests/integration/format/cjs-static-export: {} + + tests/integration/format/default: {} + + tests/integration/format/import-meta-url: {} tests/integration/json: {} diff --git a/tests/integration/format/cjs-static-export/package.json b/tests/integration/format/cjs-static-export/package.json new file mode 100644 index 000000000..cd20b6f77 --- /dev/null +++ b/tests/integration/format/cjs-static-export/package.json @@ -0,0 +1,6 @@ +{ + "name": "format-cjs-static-export-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/format/package.json b/tests/integration/format/default/package.json similarity index 65% rename from tests/integration/format/package.json rename to tests/integration/format/default/package.json index ce11e9b9d..a975c4963 100644 --- a/tests/integration/format/package.json +++ b/tests/integration/format/default/package.json @@ -1,5 +1,5 @@ { - "name": "format-test", + "name": "format-default-test", "version": "1.0.0", "private": true, "type": "module" diff --git a/tests/integration/format/default/rslib.config.ts b/tests/integration/format/default/rslib.config.ts new file mode 100644 index 000000000..2996ff400 --- /dev/null +++ b/tests/integration/format/default/rslib.config.ts @@ -0,0 +1,37 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + output: { + distPath: { + root: './dist/bundle-esm', + }, + }, + }), + generateBundleCjsConfig({ + output: { + distPath: { + root: './dist/bundle-cjs', + }, + }, + }), + generateBundleEsmConfig({ + bundle: false, + output: { + distPath: { + root: './dist/bundleless-esm', + }, + }, + }), + generateBundleCjsConfig({ + bundle: false, + output: { + distPath: { + root: './dist/bundleless-cjs', + }, + }, + }), + ], +}); diff --git a/tests/integration/format/default/src/foo.js b/tests/integration/format/default/src/foo.js new file mode 100644 index 000000000..3329a7d97 --- /dev/null +++ b/tests/integration/format/default/src/foo.js @@ -0,0 +1 @@ +export const foo = 'foo'; diff --git a/tests/integration/format/default/src/index.js b/tests/integration/format/default/src/index.js new file mode 100644 index 000000000..0e75310b2 --- /dev/null +++ b/tests/integration/format/default/src/index.js @@ -0,0 +1,3 @@ +import { foo } from './foo'; + +export const str = 'hello' + foo + ' world'; diff --git a/tests/integration/format/import-meta-url/package.json b/tests/integration/format/import-meta-url/package.json new file mode 100644 index 000000000..c6c100111 --- /dev/null +++ b/tests/integration/format/import-meta-url/package.json @@ -0,0 +1,6 @@ +{ + "name": "format-import-meta-url-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/format/index.test.ts b/tests/integration/format/index.test.ts index 2a25d791a..74d8a6405 100644 --- a/tests/integration/format/index.test.ts +++ b/tests/integration/format/index.test.ts @@ -1,7 +1,55 @@ +import exp from 'node:constants'; import path from 'node:path'; import { buildAndGetResults } from 'test-helper'; import { expect, test } from 'vitest'; +test('format default to esm', async () => { + const fixturePath = path.resolve(__dirname, 'default'); + const { files, contents } = await buildAndGetResults({ + fixturePath, + }); + + expect(files).toMatchInlineSnapshot(` + { + "cjs0": [ + "/tests/integration/format/default/dist/bundle-cjs/index.cjs", + ], + "cjs1": [ + "/tests/integration/format/default/dist/bundleless-cjs/foo.cjs", + "/tests/integration/format/default/dist/bundleless-cjs/index.cjs", + ], + "esm0": [ + "/tests/integration/format/default/dist/bundle-esm/index.js", + ], + "esm1": [ + "/tests/integration/format/default/dist/bundleless-esm/foo.js", + "/tests/integration/format/default/dist/bundleless-esm/index.js", + ], + } + `); + + expect(contents.esm0).toMatchInlineSnapshot(` + { + "/tests/integration/format/default/dist/bundle-esm/index.js": "const foo = 'foo'; + const str = 'hello' + foo + ' world'; + export { str }; + ", + } + `); + + expect(contents.esm1).toMatchInlineSnapshot(` + { + "/tests/integration/format/default/dist/bundleless-esm/foo.js": "const foo = 'foo'; + export { foo }; + ", + "/tests/integration/format/default/dist/bundleless-esm/index.js": "import * as __WEBPACK_EXTERNAL_MODULE__foo_js_fdf5aa2d__ from "./foo.js"; + const str = 'hello' + __WEBPACK_EXTERNAL_MODULE__foo_js_fdf5aa2d__.foo + ' world'; + export { str }; + ", + } + `); +}); + test('import.meta.url should be preserved', async () => { const fixturePath = path.resolve(__dirname, 'import-meta-url'); const { files, entries, entryFiles } = await buildAndGetResults({ diff --git a/tests/integration/minify/index.test.ts b/tests/integration/minify/index.test.ts index 6f7464dac..67bf49e66 100644 --- a/tests/integration/minify/index.test.ts +++ b/tests/integration/minify/index.test.ts @@ -67,7 +67,7 @@ describe('minify config (mf)', () => { expect(mfExposeEntry).toMatchInlineSnapshot(` ""use strict"; (globalThis["disable_minify"] = globalThis["disable_minify"] || []).push([["249"], { - 759: (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { + 729: (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { Button: () => (Button), diff --git a/tests/scripts/shared.ts b/tests/scripts/shared.ts index c73abbb25..e8a35700f 100644 --- a/tests/scripts/shared.ts +++ b/tests/scripts/shared.ts @@ -20,7 +20,6 @@ export function getCwdByExample(exampleName: string) { export function generateBundleEsmConfig(config: LibConfig = {}): LibConfig { const esmBasicConfig: LibConfig = { - format: 'esm', output: { distPath: { root: './dist/esm', @@ -107,19 +106,19 @@ export async function getResults( let key = ''; const formatCount: Record = rslibConfig.lib.reduce( - (acc, { format }) => { - acc[format!] = (acc[format!] ?? 0) + 1; + (acc, { format = 'esm' }) => { + acc[format] = (acc[format] ?? 0) + 1; return acc; }, {} as Record, ); for (const libConfig of rslibConfig.lib) { - const { format } = libConfig; - const currentFormatCount = formatCount[format!]; - const currentFormatIndex = formatIndex[format!]++; + const { format = 'esm' } = libConfig; + const currentFormatCount = formatCount[format]; + const currentFormatIndex = formatIndex[format]++; - key = currentFormatCount === 1 ? format! : `${format}${currentFormatIndex}`; + key = currentFormatCount === 1 ? format : `${format}${currentFormatIndex}`; let globFolder = ''; if (type === 'js' || type === 'css') { diff --git a/website/docs/en/config/lib/format.mdx b/website/docs/en/config/lib/format.mdx index 860f92c57..95dd58464 100644 --- a/website/docs/en/config/lib/format.mdx +++ b/website/docs/en/config/lib/format.mdx @@ -1,8 +1,7 @@ # lib.format - **Type:** `'esm' | 'cjs' | 'umd' | 'mf'` -- **Default:** `undefined` -- **Required**: true +- **Default:** `'esm'` Specify the output format for the generated JavaScript output files. diff --git a/website/docs/zh/config/lib/format.mdx b/website/docs/zh/config/lib/format.mdx index 48b7569de..fc3377fb3 100644 --- a/website/docs/zh/config/lib/format.mdx +++ b/website/docs/zh/config/lib/format.mdx @@ -1,8 +1,7 @@ # lib.format - **类型:** `'esm' | 'cjs' | 'umd' | 'mf'` -- **默认值:** `undefined` -- **必填:** 是 +- **默认值:** `'esm'` 指定生成的 JavaScript 产物的输出格式。 From 4d313cefe978256e253732250b4e5f1f03db7f16 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Fri, 9 May 2025 17:35:42 +0800 Subject: [PATCH 2/5] chore: update --- tests/integration/format/index.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/format/index.test.ts b/tests/integration/format/index.test.ts index 74d8a6405..9f6c0f873 100644 --- a/tests/integration/format/index.test.ts +++ b/tests/integration/format/index.test.ts @@ -1,4 +1,3 @@ -import exp from 'node:constants'; import path from 'node:path'; import { buildAndGetResults } from 'test-helper'; import { expect, test } from 'vitest'; From de8c9edcdc750f027fdc122fee6337bd37155b88 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Fri, 9 May 2025 17:36:32 +0800 Subject: [PATCH 3/5] chore: update --- packages/core/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index b0b20144a..a0cd9d46d 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -1512,7 +1512,7 @@ async function composeLibRsbuildConfig( const syntaxConfig = composeSyntaxConfig(target, config?.syntax); const autoExternalConfig = composeAutoExternalConfig({ bundle, - format: format, + format, autoExternal, pkgJson, userExternals: config.output?.externals, From d7ea56528c555231fdbcf5a8ede47e34e0dc1178 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Fri, 9 May 2025 17:54:52 +0800 Subject: [PATCH 4/5] chore: update --- tests/integration/minify/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/minify/index.test.ts b/tests/integration/minify/index.test.ts index 67bf49e66..6f7464dac 100644 --- a/tests/integration/minify/index.test.ts +++ b/tests/integration/minify/index.test.ts @@ -67,7 +67,7 @@ describe('minify config (mf)', () => { expect(mfExposeEntry).toMatchInlineSnapshot(` ""use strict"; (globalThis["disable_minify"] = globalThis["disable_minify"] || []).push([["249"], { - 729: (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { + 759: (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { Button: () => (Button), From 3f7b6d8eb8c1eb5af07aef4fbe88f6aeed2faeb2 Mon Sep 17 00:00:00 2001 From: Timeless0911 <50201324+Timeless0911@users.noreply.github.com> Date: Tue, 13 May 2025 15:19:15 +0800 Subject: [PATCH 5/5] Update packages/core/src/config.ts Co-authored-by: Wei --- packages/core/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index a0cd9d46d..4116c524e 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -1472,7 +1472,7 @@ async function composeLibRsbuildConfig( shims, ); const formatConfig = composeFormatConfig({ - format: format, + format, pkgJson: pkgJson!, bundle, umdName,