Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ name: Preview Release

on:
push:
branches: [main]
branches:
- main
- beta
workflow_dispatch:

permissions:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/reusable-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ jobs:
if: ${{ steps.changes.outputs.changed == 'true' && inputs.task == 'integration' }}
run: pnpm run test:integration

- name: Integration Test with Advanced ESM (Rstest)
if: ${{ steps.changes.outputs.changed == 'true' && inputs.task == 'integration-advanced-esm' }}
run: pnpm run test:integration:advanced-esm

- name: E2E Test (Playwright)
if: ${{ steps.changes.outputs.changed == 'true' && inputs.task == 'e2e' }}
run: pnpm run test:e2e
11 changes: 11 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ jobs:
node-version: ${{ matrix.node-version }}
task: integration

integration-advanced-esm:
strategy:
matrix:
runner: [ubuntu-latest, windows-latest]
node-version: [22]
uses: ./.github/workflows/reusable-test.yml
with:
runner: ${{ matrix.runner }}
node-version: ${{ matrix.node-version }}
task: integration-advanced-esm

e2e:
strategy:
matrix:
Expand Down
3 changes: 3 additions & 0 deletions examples/express-plugin/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export default defineConfig({
output: {
distPath: './dist/esm',
},
experiments: {
advancedEsm: true,
},
},
{
format: 'cjs',
Expand Down
3 changes: 3 additions & 0 deletions examples/module-federation/mf-react-component/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export default defineConfig({
output: {
distPath: './dist/esm',
},
experiments: {
advancedEsm: true,
},
},
{
format: 'cjs',
Expand Down
3 changes: 3 additions & 0 deletions examples/react-component-bundle/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export default defineConfig({
output: {
distPath: './dist/esm',
},
experiments: {
advancedEsm: true,
},
},
{
format: 'cjs',
Expand Down
3 changes: 3 additions & 0 deletions examples/solid-component-bundle/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export default defineConfig({
{
format: 'esm',
dts: true,
experiments: {
advancedEsm: true,
},
},
],
output: {
Expand Down
9 changes: 8 additions & 1 deletion examples/vue-component-bundle/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { pluginUnpluginVue } from 'rsbuild-plugin-unplugin-vue';

export default defineConfig({
plugins: [pluginUnpluginVue()],
lib: [{ format: 'esm' }],
lib: [
{
format: 'esm',
experiments: {
advancedEsm: true,
},
},
],
output: {
target: 'web',
},
Expand Down
7 changes: 6 additions & 1 deletion examples/vue-component-bundleless/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { pluginUnpluginVue } from 'rsbuild-plugin-unplugin-vue';

export default defineConfig({
plugins: [pluginUnpluginVue()],
lib: [{ bundle: false, format: 'esm' }],
lib: [
{
format: 'esm',
bundle: false,
},
],
output: {
target: 'web',
},
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
"prebundle": "nx run-many -t prebundle",
"prepare": "pnpm run build && simple-git-hooks",
"sort-package-json": "npx sort-package-json \"packages/*/package.json\"",
"test": "pnpm run test:unit && pnpm run test:integration && pnpm run test:e2e",
"test": "pnpm run test:unit && pnpm run test:integration && pnpm run test:integration:advanced-esm && pnpm run test:e2e",
"test:benchmark": "cd ./tests && pnpm run test:benchmark",
"test:e2e": "pnpm run build:examples && cd tests && pnpm run test:e2e",
"test:ecosystem-ci": "pnpm run test:unit && cross-env ECO_CI=1 pnpm run test:integration && pnpm run test:e2e",
"test:ecosystem-ci": "pnpm run test:unit && cross-env ECO_CI=1 pnpm run test:integration && cross-env ECO_CI=1 pnpm run test:integration:advanced-esm && pnpm run test:e2e",
"test:integration": "rstest run --project integration",
"test:integration:advanced-esm": "cross-env ADVANCED_ESM=1 rstest run --project integration",
"test:unit": "rstest run --project unit*",
"testu": "pnpm run test:unit -u && pnpm run test:integration -u",
"testu": "pnpm run test:unit -u && pnpm run test:integration -u && pnpm test:integration:advanced-esm -u",
"type-check": "pnpm -r run type-check",
"update:rsbuild": "npx taze minor --include /rsbuild/ -w -r -l",
"watch": "pnpm build --watch"
Expand Down
25 changes: 19 additions & 6 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,14 @@ const composeFormatConfig = ({
umdName,
pkgJson,
enabledShims,
advancedEsm,
}: {
format: Format;
pkgJson: PkgJson;
bundle?: boolean;
umdName?: Rspack.LibraryName;
enabledShims: DeepRequired<Shims>;
advancedEsm: boolean;
}): EnvironmentConfig => {
const jsParserOptions: Record<string, Rspack.JavascriptParserOptions> = {
cjs: {
Expand All @@ -632,14 +634,17 @@ const composeFormatConfig = ({
},
};

const experimentalEsmOutput = bundle && format === 'esm' && advancedEsm;

// The built-in Rslib plugin will apply to all formats except the `mf` format.
// The `mf` format functions more like an application than a library and requires additional webpack runtime.
const plugins = [
new rspack.experiments.RslibPlugin({
interceptApiPlugin: true,
forceNodeShims: enabledShims.esm.__dirname || enabledShims.esm.__filename,
}),
];
experimentalEsmOutput && new rspack.experiments.EsmLibraryPlugin(),
].filter(Boolean);

switch (format) {
case 'esm':
Expand All @@ -656,8 +661,10 @@ const composeFormatConfig = ({
},
},
optimization: {
concatenateModules: true,
// experimentalEsmOutput don't need concatenateModules
concatenateModules: !experimentalEsmOutput,
sideEffects: 'flag',
runtimeChunk: experimentalEsmOutput ? 'single' : undefined,
avoidEntryIife: true,
splitChunks: {
// Splitted "sync" chunks will make entry modules can't be inlined.
Expand All @@ -666,10 +673,12 @@ const composeFormatConfig = ({
},
output: {
module: true,
chunkFormat: 'module',
library: {
type: 'modern-module',
},
chunkFormat: experimentalEsmOutput ? false : 'module',
library: experimentalEsmOutput
? undefined
: {
type: 'modern-module',
},
chunkLoading: 'import',
workerChunkLoading: 'import',
},
Expand Down Expand Up @@ -1732,7 +1741,9 @@ async function composeLibRsbuildConfig(
externalHelpers = false,
redirect = {},
umdName,
experiments,
} = config;
const advancedEsm = experiments?.advancedEsm;
const { rsbuildConfig: bundleConfig } = composeBundleConfig(bundle);
const { rsbuildConfig: shimsConfig, enabledShims } = composeShimsConfig(
format,
Expand All @@ -1744,6 +1755,7 @@ async function composeLibRsbuildConfig(
bundle,
umdName,
enabledShims,
advancedEsm: advancedEsm ?? false,
});
const externalHelpersConfig = composeExternalHelpersConfig(
externalHelpers,
Expand Down Expand Up @@ -1933,6 +1945,7 @@ export async function composeCreateRsbuildConfig(
shims: true,
umdName: true,
outBase: true,
experiments: true,
}),
),
};
Expand Down
15 changes: 15 additions & 0 deletions packages/core/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,15 @@ export type Redirect = {
dts?: DtsRedirect;
};

export type LibExperiments = {
/**
* Whether to enable Rspack advanced ESM output.
* @defaultValue `false`
* @see {@link https://rslib.rs/config/lib/experiments#experimentsadvancedesm}
*/
advancedEsm?: boolean;
};

export interface LibConfig extends EnvironmentConfig {
/**
* The unique identifier of the library.
Expand Down Expand Up @@ -343,6 +352,12 @@ export interface LibConfig extends EnvironmentConfig {
* @inheritdoc
*/
output?: RslibOutputConfig;
/**
* Options for experimental features.
* @defaultValue `{}`
* @see {@link https://rslib.rs/config/lib/experiments}
*/
experiments?: LibExperiments;
}

export type LibOnlyConfig = Omit<LibConfig, keyof EnvironmentConfig>;
Expand Down
Loading
Loading