From 358f4cbe1aa78ed1815f37aa43df0fe34d0ddf74 Mon Sep 17 00:00:00 2001 From: XGHeaven Date: Thu, 7 Nov 2024 18:03:04 +0800 Subject: [PATCH] feat: support rolldown as an experimental engine --- .changeset/giant-seahorses-call.md | 5 + packages/pkg/package.json | 1 + packages/pkg/src/engine/rolldown/options.ts | 97 ++++++++ packages/pkg/src/engine/rollup/options.ts | 11 +- packages/pkg/src/helpers/taskConfig.ts | 6 + packages/pkg/src/tasks/bundle.ts | 23 +- packages/pkg/src/types.ts | 2 +- pnpm-lock.yaml | 231 +++++++++++++++++- tests/helpers/run.ts | 12 +- .../default/__snapshots__/index.test.ts.snap | 19 ++ tests/integration/default/index.test.ts | 14 ++ .../react/__snapshots__/index.test.ts.snap | 128 ++++++++++ tests/integration/react/index.test.ts | 50 ++++ tests/integration/react/package.json | 14 ++ tests/integration/react/src/index.tsx | 8 + tests/package.json | 4 +- 16 files changed, 607 insertions(+), 18 deletions(-) create mode 100644 .changeset/giant-seahorses-call.md create mode 100644 packages/pkg/src/engine/rolldown/options.ts create mode 100644 tests/integration/react/__snapshots__/index.test.ts.snap create mode 100644 tests/integration/react/index.test.ts create mode 100644 tests/integration/react/package.json create mode 100644 tests/integration/react/src/index.tsx 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 7054bfc4..f0326319 100644 --- a/packages/pkg/package.json +++ b/packages/pkg/package.json @@ -65,6 +65,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..a74bf53c --- /dev/null +++ b/packages/pkg/src/engine/rolldown/options.ts @@ -0,0 +1,97 @@ +import { RolldownOptions, Plugin, OutputOptions } from 'rolldown'; +import { Context, StylesRollupPluginOptions, TaskRunnerContext } from '../../types.js'; +import { getExternalsAndGlobals, getRollupOutputs, PkgJson } 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 PkgJson); + + options.input = taskConfig.entry; + options.external = external; + // TODO: should warning if output is multiple + options.output = getRollupOutputs({ + globals, + bundleTaskConfig: taskConfig, + pkg: pkg as PkgJson, + mode: taskRunnerContext.mode, + command, + })[0] as OutputOptions; + + const alias = {}; + Object.keys(taskConfig.alias).forEach((key) => { + // 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 5bba820a..242ab6e2 100644 --- a/packages/pkg/src/engine/rollup/options.ts +++ b/packages/pkg/src/engine/rollup/options.ts @@ -21,7 +21,7 @@ import { getFilenameConfig } from '../shared/filename.js'; import { getTaskSwcOptions } from '../../helpers/defaultSwcConfig.js'; import { assertTaskBuildableConfig } from '../../helpers/taskConfig.js'; -interface PkgJson { +export interface PkgJson { name: string; version?: string; dependencies?: Record; @@ -167,7 +167,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 e14932a8..87c149be 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, Rspack, 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; @@ -43,6 +45,8 @@ export class BundleRunner extends Runner { return this.handleRollupBuild(changedFiles); case 'rslib': return this.handleRslibBuild(changedFiles); + case 'rolldown': + return this.handleRolldownBuild(changedFiles); } } @@ -189,6 +193,23 @@ export class BundleRunner extends Runner { outputFiles: stats.assets as any, }; } + + 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 @@ -300,7 +321,7 @@ async function rawBuild(rollupOptions: RollupOptions, taskRunnerContext: TaskRun const bundle = await rollup.rollup(rollupOptions); - const buildResult = await writeFiles(rollupOutputOptions, bundle.write); + const buildResult = await writeFiles(rollupOutputOptions, bundle.write.bind(bundle)); await bundle.close(); diff --git a/packages/pkg/src/types.ts b/packages/pkg/src/types.ts index ae845d52..93e50170 100644 --- a/packages/pkg/src/types.ts +++ b/packages/pkg/src/types.ts @@ -342,7 +342,7 @@ interface _TaskConfig { pkg?: PackageResolvedConfig; } -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 46425403..fe73f560 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -391,6 +391,9 @@ importers: postcss-plugin-rpx2vw: specifier: ^1.0.0 version: 1.0.0(postcss@8.4.47) + rolldown: + specifier: ^0.15.1 + version: 0.15.1(@babel/runtime@7.20.7) rollup: specifier: ^4.0.0 version: 4.24.2 @@ -474,6 +477,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: @@ -513,6 +522,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': @@ -1653,6 +1681,15 @@ packages: react: ^16.14.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 + '@emnapi/core@1.5.0': + resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + + '@emnapi/runtime@1.5.0': + resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@endemolshinegroup/cosmiconfig-typescript-loader@3.0.2': resolution: {integrity: sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==} engines: {node: '>=10.0.0'} @@ -1864,6 +1901,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: @@ -2025,6 +2067,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==} + '@node-rs/jieba-android-arm-eabi@1.6.1': resolution: {integrity: sha512-R1YQfsPr7sK3Tq1sM0//6lNAGJK9RnMT0ShITT+7EJYr5OufUBb38lf/mRhrLxR0NF1pycEsMjdCAwrWrHd8rA==} engines: {node: '>= 10'} @@ -2126,6 +2171,66 @@ packages: '@polka/url@1.0.0-next.21': resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} + '@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'} @@ -2613,6 +2718,9 @@ packages: '@tsconfig/node16@1.0.3': resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} + '@tybys/wasm-util@0.10.0': + resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} + '@types/aria-query@5.0.1': resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} @@ -2778,6 +2886,9 @@ packages: '@types/semver@6.2.3': resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} + '@types/serialize-javascript@5.0.4': + resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==} + '@types/serve-index@1.9.1': resolution: {integrity: sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==} @@ -7738,6 +7849,15 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported 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} @@ -8006,6 +8126,9 @@ packages: serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + serve-handler@6.1.3: resolution: {integrity: sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==} @@ -11224,6 +11347,22 @@ snapshots: - vue-template-compiler - webpack-cli + '@emnapi/core@1.5.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.5.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + '@endemolshinegroup/cosmiconfig-typescript-loader@3.0.2(cosmiconfig@7.0.1)(typescript@4.9.5)': dependencies: cosmiconfig: 7.0.1 @@ -11372,6 +11511,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@4.9.4))(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@13.13.1)(typescript@4.9.4)': dependencies: '@eslint/js': 9.24.0 @@ -11700,6 +11845,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.5.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.0 + optional: true + '@node-rs/jieba-android-arm-eabi@1.6.1': optional: true @@ -11771,6 +11923,44 @@ snapshots: '@polka/url@1.0.0-next.21': {} + '@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.24.2)': dependencies: slash: 4.0.0 @@ -12202,6 +12392,11 @@ snapshots: '@tsconfig/node16@1.0.3': {} + '@tybys/wasm-util@0.10.0': + dependencies: + tslib: 2.8.1 + optional: true + '@types/aria-query@5.0.1': {} '@types/babel__core@7.1.20': @@ -12398,6 +12593,8 @@ snapshots: '@types/semver@6.2.3': {} + '@types/serialize-javascript@5.0.4': {} + '@types/serve-index@1.9.1': dependencies: '@types/express': 4.17.13 @@ -15841,7 +16038,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 17.0.45 - ts-node: 10.8.2(@swc/core@1.7.40(@swc/helpers@0.5.17))(@types/node@17.0.45)(typescript@4.9.5) + ts-node: 10.8.2(@swc/core@1.7.40)(@types/node@17.0.45)(typescript@4.9.5) transitivePeerDependencies: - supports-color @@ -18088,6 +18285,24 @@ snapshots: dependencies: glob: 7.2.3 + rolldown@0.15.1(@babel/runtime@7.20.7): + dependencies: + zod: 3.24.2 + optionalDependencies: + '@babel/runtime': 7.20.7 + '@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.24.2)(typescript@4.9.5): dependencies: '@rollup/pluginutils': 5.1.3(rollup@4.24.2) @@ -18377,6 +18592,10 @@ snapshots: dependencies: randombytes: 2.1.0 + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + serve-handler@6.1.3: dependencies: bytes: 3.0.0 @@ -19085,7 +19304,7 @@ snapshots: '@jest/types': 29.4.3 babel-jest: 29.4.3(@babel/core@7.21.3) - ts-node@10.8.2(@swc/core@1.7.40(@swc/helpers@0.5.17))(@types/node@17.0.45)(typescript@4.9.5): + ts-node@10.8.2(@swc/core@1.7.40)(@types/node@17.0.45)(typescript@4.9.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 @@ -19099,14 +19318,13 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 4.9.5 + typescript: 4.9.4 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: '@swc/core': 1.7.40(@swc/helpers@0.5.17) - optional: true - ts-node@10.8.2(@swc/core@1.7.40)(@types/node@17.0.45)(typescript@4.9.4): + ts-node@10.8.2(@swc/core@1.7.40)(@types/node@17.0.45)(typescript@4.9.5): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 @@ -19120,11 +19338,12 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 4.9.4 + typescript: 4.9.5 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: '@swc/core': 1.7.40(@swc/helpers@0.5.17) + optional: true ts-node@9.1.1(typescript@4.9.5): dependencies: diff --git a/tests/helpers/run.ts b/tests/helpers/run.ts index e4320f96..7c5b001f 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']; @@ -100,12 +101,9 @@ export function runProjectTest(fileUrl: string, userConfigs: ProjectTestConfigs) test( `Run config ${config.name}`, async () => { - try { - await runBuild(config); - await runSnapshot(config); - } finally { - await resetProject(config); - } + await resetProject(config); + await runBuild(config); + await runSnapshot(config); }, { timeout: 30 * 1000, @@ -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 0fd51f17..aea779a6 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 12deedb9..61110470 100644 --- a/tests/integration/default/index.test.ts +++ b/tests/integration/default/index.test.ts @@ -101,4 +101,18 @@ runProjectTest(import.meta.url, [ ], }, }, + { + name: 'bundle-rolldown', + config: { + pkgs: [ + { + module: 'esm', + target: 'es2017', + bundle: true, + engine: 'rolldown', + }, + ], + }, + only: true, + }, ]); 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..ef85f0fe --- /dev/null +++ b/tests/integration/react/__snapshots__/index.test.ts.snap @@ -0,0 +1,128 @@ +// Vitest Snapshot v1 + +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 /*#__PURE__*/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=()=>/*#__PURE__*/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" } }