diff --git a/.changeset/giant-seahorses-call.md b/.changeset/giant-seahorses-call.md new file mode 100644 index 00000000..6c749470 --- /dev/null +++ b/.changeset/giant-seahorses-call.md @@ -0,0 +1,5 @@ +--- +'@ice/pkg': minor +--- + +feat: support rolldown as an experimental engine diff --git a/packages/pkg/package.json b/packages/pkg/package.json index 64996451..c8608860 100644 --- a/packages/pkg/package.json +++ b/packages/pkg/package.json @@ -67,6 +67,7 @@ "picocolors": "^1.0.0", "postcss": "^8.4.31", "postcss-plugin-rpx2vw": "^1.0.0", + "rolldown": "^0.15.1", "rollup": "^4.0.0", "rollup-plugin-styler": "^1.8.0", "rollup-plugin-visualizer": "^5.12.0", diff --git a/packages/pkg/src/engine/rolldown/options.ts b/packages/pkg/src/engine/rolldown/options.ts new file mode 100644 index 00000000..7e75c3f5 --- /dev/null +++ b/packages/pkg/src/engine/rolldown/options.ts @@ -0,0 +1,99 @@ +import { RolldownOptions, Plugin, OutputOptions } from 'rolldown'; +import { Context, StylesRollupPluginOptions, TaskRunnerContext, PackageJson } from '../../types.js'; +import { getExternalsAndGlobals, getRollupOutputs } from '../rollup/options.js'; +import { assertTaskBundleConfig } from '../../helpers/taskConfig.js'; +import path from 'node:path'; +import getDefaultDefineValues from '../../helpers/getDefaultDefineValues.js'; +import styles from 'rollup-plugin-styler'; +import image from '@rollup/plugin-image'; +import autoprefixer from 'autoprefixer'; +import PostcssPluginRpxToVw from 'postcss-plugin-rpx2vw'; +import { visualizer } from 'rollup-plugin-visualizer'; +import { JSX_RUNTIME_SOURCE } from '../../constants.js'; +import { RollupOptions } from 'rollup'; + +export function getRolldownOptions(context: Context, taskRunnerContext: TaskRunnerContext): RolldownOptions { + const { pkg, commandArgs, command, rootDir } = context; + const { buildTask } = taskRunnerContext; + const { name: taskName, config: taskConfig } = buildTask; + + assertTaskBundleConfig(taskConfig); + + const options: RolldownOptions = {}; + + const [external, globals] = getExternalsAndGlobals(taskConfig, pkg as PackageJson); + + options.input = taskConfig.entry; + options.external = external; + // TODO: should warning if output is multiple + options.output = getRollupOutputs({ + globals, + bundleTaskConfig: taskConfig, + pkg: pkg as PackageJson, + mode: taskRunnerContext.mode, + command, + })[0] as OutputOptions; + + const alias: Record = {}; + if (taskConfig.alias) { + for (const key of Object.keys(taskConfig.alias)) { + // Add full path for relative path alias + alias[key] = taskConfig.alias[key].startsWith('.') + ? path.resolve(rootDir, taskConfig.alias[key]) + : taskConfig.alias[key]; + } + } + + const plugins: Plugin[] = []; + + options.resolve = { + alias, + }; + options.define = { + ...getDefaultDefineValues(taskRunnerContext.mode), + // User define can override above. + ...taskConfig.define, + }; + + options.jsx = { + mode: taskConfig.jsxRuntime ?? 'automatic', + jsxImportSource: JSX_RUNTIME_SOURCE, + }; + + const cssMinify = taskConfig.cssMinify!(taskRunnerContext.mode, command); + const defaultStylesOptions: StylesRollupPluginOptions = { + plugins: [autoprefixer(), PostcssPluginRpxToVw], + mode: 'extract', + autoModules: true, + minimize: typeof cssMinify === 'boolean' ? cssMinify : cssMinify.options, + sourceMap: taskConfig.sourcemap, + }; + + plugins.push( + styles( + (taskConfig.modifyStylesOptions ?? [(options) => options]).reduce( + (prevStylesOptions, modifyStylesOptions) => modifyStylesOptions(prevStylesOptions), + defaultStylesOptions, + ), + ) as unknown as Plugin, + image() as unknown as Plugin, + ); + + if (commandArgs.analyzer) { + plugins.push( + visualizer({ + title: `Rollup Visualizer(${taskName})`, + open: true, + filename: `${taskName}-stats.html`, + }) as unknown as Plugin, + ); + } + + options.plugins = plugins; + + return (taskConfig.modifyRollupOptions ?? [(options) => options]).reduce( + (prevOptions, modifyRollupOptions) => + modifyRollupOptions(prevOptions as unknown as RollupOptions) as RolldownOptions, + options, + ); +} diff --git a/packages/pkg/src/engine/rollup/options.ts b/packages/pkg/src/engine/rollup/options.ts index 530b27f4..9f6b7452 100644 --- a/packages/pkg/src/engine/rollup/options.ts +++ b/packages/pkg/src/engine/rollup/options.ts @@ -168,7 +168,14 @@ interface GetRollupOutputsOptions { mode: NodeEnvMode; command: Context['command']; } -function getRollupOutputs({ globals, bundleTaskConfig, pkg, mode, command }: GetRollupOutputsOptions): OutputOptions[] { + +export function getRollupOutputs({ + globals, + bundleTaskConfig, + pkg, + mode, + command, +}: GetRollupOutputsOptions): OutputOptions[] { const { outputDir, vendorName = 'vendor' } = bundleTaskConfig; const outputFormats = bundleTaskConfig.formats ?? []; diff --git a/packages/pkg/src/helpers/taskConfig.ts b/packages/pkg/src/helpers/taskConfig.ts index f2869e4b..416831a2 100644 --- a/packages/pkg/src/helpers/taskConfig.ts +++ b/packages/pkg/src/helpers/taskConfig.ts @@ -7,3 +7,9 @@ export function assertTaskBuildableConfig( throw new Error('Only accept bundle or transform task.'); } } + +export function assertTaskBundleConfig(taskConfig: TaskConfig): asserts taskConfig is BundleTaskConfig { + if (taskConfig.type !== 'bundle') { + throw new Error('Only accept bundle task.'); + } +} diff --git a/packages/pkg/src/tasks/bundle.ts b/packages/pkg/src/tasks/bundle.ts index 98267b40..ece18a20 100644 --- a/packages/pkg/src/tasks/bundle.ts +++ b/packages/pkg/src/tasks/bundle.ts @@ -18,6 +18,7 @@ import type { FSWatcher } from 'chokidar'; import type { RslibConfig, rsbuild } from '@rslib/core'; import { getRollupOptions } from '../engine/rollup/options.js'; import { Runner } from '../helpers/runner.js'; +import { RolldownOptions } from 'rolldown'; import { noop } from 'es-toolkit'; import { consola } from 'consola'; @@ -28,6 +29,7 @@ export function createBundleTask(taskRunningContext: TaskRunnerContext) { export class BundleRunner extends Runner { private rollupOptions?: RollupOptions; private rslibConfig?: RslibConfig; + private rolldownOptions?: RolldownOptions; private engine: EngineType; private watcher: Watcher | null = null; private result: Error | OutputResult | null = null; @@ -45,6 +47,8 @@ export class BundleRunner extends Runner { return this.handleRollupBuild(changedFiles); case 'rslib': return this.handleRslibBuild(changedFiles); + case 'rolldown': + return this.handleRolldownBuild(changedFiles); default: throw new Error(`Unsupported engine: ${this.engine}`); } @@ -193,6 +197,23 @@ export class BundleRunner extends Runner { outputFiles: stats?.assets as any, } as OutputResult; } + + private async handleRolldownBuild(changedFiles: WatchChangedFile[]): Promise { + const { context } = this; + const { build } = await import('rolldown'); + if (!this.rolldownOptions) { + const { getRolldownOptions } = await import('../engine/rolldown/options.js'); + this.rolldownOptions = getRolldownOptions(context.buildContext, context); + } + const bundle = await build(this.rolldownOptions); + + return { + taskName: context.buildTask.name, + // TODO: correct type and value + outputs: bundle.output as any, + outputFiles: bundle.output as any, + }; + } } // Fork from https://github.com/rollup/rollup/blob/v2.79.1/src/watch/WatchEmitter.ts @@ -312,7 +333,7 @@ async function rawBuild(rollupOptions: RollupOptions, taskRunnerContext: TaskRun const bundle = await rollup.rollup(rollupOptions); - const buildResult = await writeFiles((rollupOutputOptions as OutputOptions[]).filter(Boolean), bundle.write); + const buildResult = await writeFiles((rollupOutputOptions as OutputOptions[]).filter(Boolean), bundle.write.bind(bundle)); await bundle.close(); diff --git a/packages/pkg/src/types.ts b/packages/pkg/src/types.ts index 835fd07d..0b76b796 100644 --- a/packages/pkg/src/types.ts +++ b/packages/pkg/src/types.ts @@ -312,7 +312,11 @@ interface _TaskConfig { */ define?: PlainObject; /** - * Define which bundler engine to use + * Define which bundler engine to use. + * - 'rollup' + * - 'rslib' common used for mf build + * - 'rolldown' experimental + * @default 'rollup' */ engine?: EngineType; /** @@ -361,7 +365,7 @@ interface _TaskConfig { pkg?: PkgResolvedConfig; } -export type EngineType = 'rollup' | 'rslib'; +export type EngineType = 'rollup' | 'rslib' | 'rolldown'; export interface BundleTaskConfig extends _TaskConfig, Omit { type: 'bundle'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1437801d..7297cbb5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -421,6 +421,9 @@ importers: postcss-plugin-rpx2vw: specifier: ^1.0.0 version: 1.0.0(postcss@8.5.6) + rolldown: + specifier: ^0.15.1 + version: 0.15.1(@babel/runtime@7.28.4) rollup: specifier: ^4.0.0 version: 4.53.2 @@ -504,6 +507,12 @@ importers: '@ice/pkg': specifier: workspace:* version: link:../packages/pkg + '@types/serialize-javascript': + specifier: ^5.0.4 + version: 5.0.4 + serialize-javascript: + specifier: ^6.0.2 + version: 6.0.2 tests/integration/alias: dependencies: @@ -552,6 +561,25 @@ importers: specifier: workspace:* version: link:../../../packages/pkg + tests/integration/react: + dependencies: + '@ice/jsx-runtime': + specifier: ^0.3.0 + version: 0.3.2(react@18.2.0) + '@ice/pkg': + specifier: workspace:* + version: link:../../../packages/pkg + '@swc/helpers': + specifier: ^0.5.15 + version: 0.5.17 + react: + specifier: ^18.0.0 + version: 18.2.0 + devDependencies: + '@types/react': + specifier: ^18.0.0 + version: 18.0.15 + website: dependencies: '@docusaurus/core': @@ -2298,6 +2326,11 @@ packages: peerDependencies: react: ^16 || ^17 || ^18 + '@ice/jsx-runtime@0.3.2': + resolution: {integrity: sha512-4JLg6dLHbXQOAPviIstHWHcvYpDfgzUR1KedBnrLSDD0xPLEJYGcwTkwyiwdjTx/cufwylsNv75qw4GyMjU/Yw==} + peerDependencies: + react: ^16 || ^17 || ^18 + '@ice/spec@2.0.0-beta.3': resolution: {integrity: sha512-pVyNvDBI638xZi2tlPgj2HeEILLZtpDQQsGGMFvVaD8O3hCPL0h1z4e9AGd0PVf8TM8ErS9B8U/B28BRCn3XJQ==} peerDependencies: @@ -2495,6 +2528,9 @@ packages: '@module-federation/webpack-bundler-runtime@0.14.0': resolution: {integrity: sha512-POWS6cKBicAAQ3DNY5X7XEUSfOfUsRaBNxbuwEfSGlrkTE9UcWheO06QP2ndHi8tHQuUKcIHi2navhPkJ+k5xg==} + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@napi-rs/wasm-runtime@1.0.7': resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} @@ -2786,6 +2822,66 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@rolldown/binding-darwin-arm64@0.15.1': + resolution: {integrity: sha512-eHszEW3Tpf2MNCOB3Qq+ypXBJl5MY+QNmb32AfUkcjGLtS6A84CkzjLLRBCIAJJ07WR0dD2EbOEjFXyp9JpdxA==} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@0.15.1': + resolution: {integrity: sha512-0IczkPBKzftwezo19wR/W7b2uXrPIgU5sDpic2DGndqZwcqtO0LBg1SvRoTUFzs0sSqIK/e2fo0VUzOe1wShLQ==} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@0.15.1': + resolution: {integrity: sha512-yad0CKnx9H3NQZCfV4gTzsfTQxqFEJvJSzyXxxA/RhGa6nq/3S/JugQAis37xjaVmQ39NMRrRQ7NokbagHlJVA==} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@0.15.1': + resolution: {integrity: sha512-B4YuHSz18yvZ7ng0qy7ZhzWe+IyeZ1EUAIvBH7O7Fg69oDUp3TqCkh/nnY7mLNPoA2BCwwweIMAOX7U778J1Ww==} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@0.15.1': + resolution: {integrity: sha512-2v4ZE/a75XA96f7Hmw8RibVIHktpREHTvAG/jG+0718UAVl0XS1o3gCcfJHOzq0vxRM6JrJxL0An6Blqx0zo/g==} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@0.15.1': + resolution: {integrity: sha512-ICZANEBNJxpaZPspK3Xd5+pG6CO/0pEOMPJEBiUi67Gy6NexyN9ILPwXoF3ZWEmBMizcURt52xkqoUuEGpJMQg==} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@0.15.1': + resolution: {integrity: sha512-PldpjbytgMM0eKmnRAvKM6F4bwpRS3aoFr5AAOtbdIxC08ABG/ab+xXuwjdVyo2xxM3nTItbma76verU8lkCgA==} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@0.15.1': + resolution: {integrity: sha512-ydIgDOKQi92RQjgFFuMeO09IWe0fWLcmhv7opAjutcGwEgqediamlhgmDW2eRJTqHwhT56zMVpivvejMR2KT8g==} + cpu: [x64] + os: [linux] + + '@rolldown/binding-wasm32-wasi@0.15.1': + resolution: {integrity: sha512-tNE0tEX+h0WmFx2hL3s1zZOrJtB3hVJkyrMMdyCGwB+ockaeBpinqLsbWzd130RODODLXnMIDXKZcFA8yATMpg==} + engines: {node: '>=14.21.3'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@0.15.1': + resolution: {integrity: sha512-/t1r1tT95cZ2Qt+GO+9pCmgwSNzBRQnX9TL+FJOi9js2PYTnftGq7oU7/VbITpAvwd3bsuWoVncCBnOhgRjxRw==} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-ia32-msvc@0.15.1': + resolution: {integrity: sha512-x/IImodHRMXeUVUg/BslxYfbBCVTyR1vToEkBiyDt7QVdWBOVAnn/hHOwDRNXBsLLhNB8s74EGzwCihC0TZRgw==} + cpu: [ia32] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@0.15.1': + resolution: {integrity: sha512-8h55cfyhl2WVXZz+FRFhcBAS7cZUZscZ9Uu5lTq+21+wC7LShiBTe8slbACZDNShSW1vskx/bvOQ4PienU1ovA==} + cpu: [x64] + os: [win32] + '@rollup/plugin-alias@5.0.1': resolution: {integrity: sha512-JObvbWdOHoMy9W7SU0lvGhDtWq9PllP5mjpAy+TUslZG/WzOId9u80Hsqq1vCUn9pFJ0cxpdcnAv+QzU2zFH3Q==} engines: {node: '>=14.0.0'} @@ -3492,6 +3588,9 @@ packages: '@types/send@1.2.1': resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + '@types/serialize-javascript@5.0.4': + resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==} + '@types/serve-index@1.9.4': resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} @@ -8751,6 +8850,15 @@ packages: engines: {node: '>=14'} hasBin: true + rolldown@0.15.1: + resolution: {integrity: sha512-i368PJXHjqyYm9ZXdnI0j/etPF2euP5OG/C0RnhO/bHkZEo4WmorWbaYfeRqe6MEo/H3wkXxGz/y1Vnaq5FiuQ==} + hasBin: true + peerDependencies: + '@babel/runtime': '>=7' + peerDependenciesMeta: + '@babel/runtime': + optional: true + rollup-plugin-styler@1.8.0: resolution: {integrity: sha512-RbPfWydOTE/X/4h7NpIVY0IhP46tzJI/nylCEf6ICpJwvE/7v7Y9sfQnRW/kfXIesbsAVkZl1vEhSGW+elyCFA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -12932,6 +13040,12 @@ snapshots: react: 18.2.0 style-unit: 3.0.5 + '@ice/jsx-runtime@0.3.2(react@18.2.0)': + dependencies: + '@swc/helpers': 0.5.17 + react: 18.2.0 + style-unit: 3.0.5 + '@ice/spec@2.0.0-beta.3(@types/eslint@8.4.5)(@typescript-eslint/parser@8.30.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.9.2))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.24.0(jiti@2.4.2)))(eslint-plugin-jsx-plus@0.1.0)(eslint@9.24.0(jiti@2.4.2))(postcss@8.5.6)(prettier@3.5.3)(stylelint@16.25.0(typescript@5.9.2))(typescript@5.9.2)': dependencies: '@eslint/js': 9.24.0 @@ -13301,6 +13415,13 @@ snapshots: '@module-federation/runtime': 0.14.0 '@module-federation/sdk': 0.14.0 + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.7.0 + '@emnapi/runtime': 1.7.0 + '@tybys/wasm-util': 0.10.1 + optional: true + '@napi-rs/wasm-runtime@1.0.7': dependencies: '@emnapi/core': 1.7.0 @@ -13501,6 +13622,44 @@ snapshots: '@polka/url@1.0.0-next.29': {} + '@rolldown/binding-darwin-arm64@0.15.1': + optional: true + + '@rolldown/binding-darwin-x64@0.15.1': + optional: true + + '@rolldown/binding-freebsd-x64@0.15.1': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@0.15.1': + optional: true + + '@rolldown/binding-linux-arm64-gnu@0.15.1': + optional: true + + '@rolldown/binding-linux-arm64-musl@0.15.1': + optional: true + + '@rolldown/binding-linux-x64-gnu@0.15.1': + optional: true + + '@rolldown/binding-linux-x64-musl@0.15.1': + optional: true + + '@rolldown/binding-wasm32-wasi@0.15.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@rolldown/binding-win32-arm64-msvc@0.15.1': + optional: true + + '@rolldown/binding-win32-ia32-msvc@0.15.1': + optional: true + + '@rolldown/binding-win32-x64-msvc@0.15.1': + optional: true + '@rollup/plugin-alias@5.0.1(rollup@4.53.2)': dependencies: slash: 4.0.0 @@ -14186,6 +14345,8 @@ snapshots: dependencies: '@types/node': 20.19.25 + '@types/serialize-javascript@5.0.4': {} + '@types/serve-index@1.9.4': dependencies: '@types/express': 4.17.25 @@ -20527,6 +20688,24 @@ snapshots: dependencies: glob: 9.3.5 + rolldown@0.15.1(@babel/runtime@7.28.4): + dependencies: + zod: 3.24.2 + optionalDependencies: + '@babel/runtime': 7.28.4 + '@rolldown/binding-darwin-arm64': 0.15.1 + '@rolldown/binding-darwin-x64': 0.15.1 + '@rolldown/binding-freebsd-x64': 0.15.1 + '@rolldown/binding-linux-arm-gnueabihf': 0.15.1 + '@rolldown/binding-linux-arm64-gnu': 0.15.1 + '@rolldown/binding-linux-arm64-musl': 0.15.1 + '@rolldown/binding-linux-x64-gnu': 0.15.1 + '@rolldown/binding-linux-x64-musl': 0.15.1 + '@rolldown/binding-wasm32-wasi': 0.15.1 + '@rolldown/binding-win32-arm64-msvc': 0.15.1 + '@rolldown/binding-win32-ia32-msvc': 0.15.1 + '@rolldown/binding-win32-x64-msvc': 0.15.1 + rollup-plugin-styler@1.8.0(rollup@4.53.2)(typescript@5.9.2): dependencies: '@rollup/pluginutils': 5.1.3(rollup@4.53.2) diff --git a/tests/helpers/run.ts b/tests/helpers/run.ts index 3c433f11..d6c5e2b2 100644 --- a/tests/helpers/run.ts +++ b/tests/helpers/run.ts @@ -5,6 +5,7 @@ import * as fse from 'fs-extra'; import fs from 'fs-extra'; import { execSync } from 'node:child_process'; import { UserConfig } from '@ice/pkg'; +import stringifyJavascript from 'serialize-javascript'; const CHECK_DIRS = ['es2017', 'esm', 'dist', 'cjs']; @@ -103,12 +104,9 @@ export function runProjectTest(fileUrl: string, userConfigs: ProjectTestUserConf timeout: 30 * 1000, }, async () => { - try { - await runBuild(config); - await runSnapshot(config); - } finally { - await resetProject(config); - } + await resetProject(config); + await runBuild(config); + await runSnapshot(config); }, ); } @@ -164,6 +162,6 @@ function buildIcePkgConfigScript(config: UserConfig) { return ` import { defineConfig } from '@ice/pkg' -export default defineConfig(${JSON.stringify(config, null, 2)}) +export default defineConfig(${stringifyJavascript(config, { space: 2 })}) `.trim(); } diff --git a/tests/integration/default/__snapshots__/index.test.ts.snap b/tests/integration/default/__snapshots__/index.test.ts.snap index 86831e09..daa01279 100644 --- a/tests/integration/default/__snapshots__/index.test.ts.snap +++ b/tests/integration/default/__snapshots__/index.test.ts.snap @@ -52,6 +52,25 @@ exports[`Run config bundle-full > es2017 structure 1`] = `null`; exports[`Run config bundle-full > esm structure 1`] = `null`; +exports[`Run config bundle-rolldown > cjs structure 1`] = `null`; + +exports[`Run config bundle-rolldown > dist structure 1`] = ` +{ + "files": [ + { + "name": "index.esm.es2017.production.js", + }, + ], + "name": "dist", +} +`; + +exports[`Run config bundle-rolldown > es2017 structure 1`] = `null`; + +exports[`Run config bundle-rolldown > esm structure 1`] = `null`; + +exports[`Run config bundle-rolldown > file content dist/index.esm.es2017.production.js 1`] = `"let o=1;export{o as foo};"`; + exports[`Run config bundle-with-dev-mode > cjs structure 1`] = `null`; exports[`Run config bundle-with-dev-mode > dist structure 1`] = ` diff --git a/tests/integration/default/index.test.ts b/tests/integration/default/index.test.ts index 3045788e..6a4268ad 100644 --- a/tests/integration/default/index.test.ts +++ b/tests/integration/default/index.test.ts @@ -126,4 +126,17 @@ runProjectTest(import.meta.url, [ }, }, }, + { + name: 'bundle-rolldown', + config: { + pkgs: [ + { + module: 'esm', + target: 'es2017', + bundle: true, + engine: 'rolldown', + }, + ], + }, + }, ]); diff --git a/tests/integration/react/__snapshots__/index.test.ts.snap b/tests/integration/react/__snapshots__/index.test.ts.snap new file mode 100644 index 00000000..f56e3fe5 --- /dev/null +++ b/tests/integration/react/__snapshots__/index.test.ts.snap @@ -0,0 +1,126 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Run config default > cjs structure 1`] = `null`; + +exports[`Run config default > dist structure 1`] = ` +{ + "files": [ + { + "name": "index.esm.es5.production.js", + }, + ], + "name": "dist", +} +`; + +exports[`Run config default > es2017 structure 1`] = `null`; + +exports[`Run config default > esm structure 1`] = ` +{ + "files": [ + { + "name": "index.d.ts", + }, + { + "name": "index.js", + }, + ], + "name": "esm", +} +`; + +exports[`Run config default > file content dist/index.esm.es5.production.js 1`] = ` +"import{_ as e}from"@swc/helpers/_/_object_spread";import{_ as r}from"@swc/helpers/_/_object_spread_props";import{jsx as o}from"@ice/jsx-runtime/jsx-runtime";import"react";function s(){return o("div",r(e({},{className:"common-class-name"}),{children:"Hello World"}))}export{s as default}; +" +`; + +exports[`Run config default > file content esm/index.d.ts 1`] = ` +"declare const _default: () => JSX.Element; +export default _default; +" +`; + +exports[`Run config default > file content esm/index.js 1`] = ` +"import { _ as _object_spread } from "@swc/helpers/_/_object_spread"; +import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props"; +import { jsx as _jsx } from "@ice/jsx-runtime/jsx-runtime"; +import React from 'react'; +export default function() { + var commonProps = { + className: 'common-class-name' + }; + return /*#__PURE__*/ _jsx("div", _object_spread_props(_object_spread({}, commonProps), { + children: "Hello World" + })); +}; +" +`; + +exports[`Run config pkg > cjs structure 1`] = `null`; + +exports[`Run config pkg > dist structure 1`] = ` +{ + "files": [ + { + "name": "index.esm.es2017.production.js", + }, + ], + "name": "dist", +} +`; + +exports[`Run config pkg > es2017 structure 1`] = `null`; + +exports[`Run config pkg > esm structure 1`] = ` +{ + "files": [ + { + "name": "index.d.ts", + }, + { + "name": "index.js", + }, + ], + "name": "esm", +} +`; + +exports[`Run config pkg > file content dist/index.esm.es2017.production.js 1`] = ` +"import{_ as e}from"@swc/helpers/_/_object_spread";import{_ as r}from"@swc/helpers/_/_object_spread_props";import{jsx as o}from"@ice/jsx-runtime/jsx-runtime";import"react";var s=()=>o("div",r(e({},{className:"common-class-name"}),{children:"Hello World"}));export{s as default}; +" +`; + +exports[`Run config pkg > file content esm/index.d.ts 1`] = ` +"declare const _default: () => JSX.Element; +export default _default; +" +`; + +exports[`Run config pkg > file content esm/index.js 1`] = ` +"import { _ as _object_spread } from "@swc/helpers/_/_object_spread"; +import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props"; +import { jsx as _jsx } from "@ice/jsx-runtime/jsx-runtime"; +import React from 'react'; +export default (()=>{ + const commonProps = { + className: 'common-class-name' + }; + return /*#__PURE__*/ _jsx("div", _object_spread_props(_object_spread({}, commonProps), { + children: "Hello World" + })); +}); +" +`; + +exports[`Run config rolldown > dist structure 1`] = ` +{ + "files": [ + { + "name": "index.esm.es2017.production.js", + }, + ], + "name": "dist", +} +`; + +exports[`Run config rolldown > file content dist/index.esm.es2017.production.js 1`] = `"import"react";import{jsx as e}from"@ice/jsx-runtime/jsx-runtime";var r=()=>e("div",{className:"common-class-name",children:"Hello World"});export{r as default};"`; diff --git a/tests/integration/react/index.test.ts b/tests/integration/react/index.test.ts new file mode 100644 index 00000000..87d12aad --- /dev/null +++ b/tests/integration/react/index.test.ts @@ -0,0 +1,50 @@ +import { runProjectTest } from '../../helpers/run'; + +const externals = [/^react/, /^@swc\/helpers/, /^@ice\/jsx-runtime/]; + +runProjectTest(import.meta.url, [ + { + name: 'default', + config: { + transform: { + formats: ['esm'], + }, + bundle: { + formats: ['esm'], + externals, + }, + }, + }, + { + name: 'pkg', + config: { + pkgs: [ + { + module: 'esm', + }, + { + module: 'esm', + bundle: true, + }, + ], + bundle: { + externals, + }, + }, + }, + { + name: 'rolldown', + snapshotFolders: ['dist'], + config: { + pkgs: [ + { + bundle: true, + engine: 'rolldown', + }, + ], + bundle: { + externals, + }, + }, + }, +]); diff --git a/tests/integration/react/package.json b/tests/integration/react/package.json new file mode 100644 index 00000000..003e6c26 --- /dev/null +++ b/tests/integration/react/package.json @@ -0,0 +1,14 @@ +{ + "name": "@ice/pkg-tests-react", + "version": "0.0.0", + "private": true, + "dependencies": { + "@ice/pkg": "workspace:*", + "@ice/jsx-runtime": "^0.3.0", + "@swc/helpers": "^0.5.15", + "react": "^18.0.0" + }, + "devDependencies": { + "@types/react": "^18.0.0" + } +} diff --git a/tests/integration/react/src/index.tsx b/tests/integration/react/src/index.tsx new file mode 100644 index 00000000..5d0288a9 --- /dev/null +++ b/tests/integration/react/src/index.tsx @@ -0,0 +1,8 @@ +import React from 'react'; + +export default () => { + const commonProps: Record = { + className: 'common-class-name', + }; + return
Hello World
; +}; diff --git a/tests/package.json b/tests/package.json index a239acae..e461c762 100644 --- a/tests/package.json +++ b/tests/package.json @@ -5,6 +5,8 @@ "type": "module", "scripts": {}, "devDependencies": { - "@ice/pkg": "workspace:*" + "@ice/pkg": "workspace:*", + "@types/serialize-javascript": "^5.0.4", + "serialize-javascript": "^6.0.2" } }