Skip to content

Commit e0285a9

Browse files
authored
feat: support rolldown as an experimental engine (#688)
1 parent 9aaa5bb commit e0285a9

File tree

16 files changed

+564
-12
lines changed

16 files changed

+564
-12
lines changed

.changeset/giant-seahorses-call.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@ice/pkg': minor
3+
---
4+
5+
feat: support rolldown as an experimental engine

packages/pkg/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"picocolors": "^1.0.0",
6868
"postcss": "^8.4.31",
6969
"postcss-plugin-rpx2vw": "^1.0.0",
70+
"rolldown": "^0.15.1",
7071
"rollup": "^4.0.0",
7172
"rollup-plugin-styler": "^1.8.0",
7273
"rollup-plugin-visualizer": "^5.12.0",
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { RolldownOptions, Plugin, OutputOptions } from 'rolldown';
2+
import { Context, StylesRollupPluginOptions, TaskRunnerContext, PackageJson } from '../../types.js';
3+
import { getExternalsAndGlobals, getRollupOutputs } from '../rollup/options.js';
4+
import { assertTaskBundleConfig } from '../../helpers/taskConfig.js';
5+
import path from 'node:path';
6+
import getDefaultDefineValues from '../../helpers/getDefaultDefineValues.js';
7+
import styles from 'rollup-plugin-styler';
8+
import image from '@rollup/plugin-image';
9+
import autoprefixer from 'autoprefixer';
10+
import PostcssPluginRpxToVw from 'postcss-plugin-rpx2vw';
11+
import { visualizer } from 'rollup-plugin-visualizer';
12+
import { JSX_RUNTIME_SOURCE } from '../../constants.js';
13+
import { RollupOptions } from 'rollup';
14+
15+
export function getRolldownOptions(context: Context, taskRunnerContext: TaskRunnerContext): RolldownOptions {
16+
const { pkg, commandArgs, command, rootDir } = context;
17+
const { buildTask } = taskRunnerContext;
18+
const { name: taskName, config: taskConfig } = buildTask;
19+
20+
assertTaskBundleConfig(taskConfig);
21+
22+
const options: RolldownOptions = {};
23+
24+
const [external, globals] = getExternalsAndGlobals(taskConfig, pkg as PackageJson);
25+
26+
options.input = taskConfig.entry;
27+
options.external = external;
28+
// TODO: should warning if output is multiple
29+
options.output = getRollupOutputs({
30+
globals,
31+
bundleTaskConfig: taskConfig,
32+
pkg: pkg as PackageJson,
33+
mode: taskRunnerContext.mode,
34+
command,
35+
})[0] as OutputOptions;
36+
37+
const alias: Record<string, string> = {};
38+
if (taskConfig.alias) {
39+
for (const key of Object.keys(taskConfig.alias)) {
40+
// Add full path for relative path alias
41+
alias[key] = taskConfig.alias[key].startsWith('.')
42+
? path.resolve(rootDir, taskConfig.alias[key])
43+
: taskConfig.alias[key];
44+
}
45+
}
46+
47+
const plugins: Plugin[] = [];
48+
49+
options.resolve = {
50+
alias,
51+
};
52+
options.define = {
53+
...getDefaultDefineValues(taskRunnerContext.mode),
54+
// User define can override above.
55+
...taskConfig.define,
56+
};
57+
58+
options.jsx = {
59+
mode: taskConfig.jsxRuntime ?? 'automatic',
60+
jsxImportSource: JSX_RUNTIME_SOURCE,
61+
};
62+
63+
const cssMinify = taskConfig.cssMinify!(taskRunnerContext.mode, command);
64+
const defaultStylesOptions: StylesRollupPluginOptions = {
65+
plugins: [autoprefixer(), PostcssPluginRpxToVw],
66+
mode: 'extract',
67+
autoModules: true,
68+
minimize: typeof cssMinify === 'boolean' ? cssMinify : cssMinify.options,
69+
sourceMap: taskConfig.sourcemap,
70+
};
71+
72+
plugins.push(
73+
styles(
74+
(taskConfig.modifyStylesOptions ?? [(options) => options]).reduce<StylesRollupPluginOptions>(
75+
(prevStylesOptions, modifyStylesOptions) => modifyStylesOptions(prevStylesOptions),
76+
defaultStylesOptions,
77+
),
78+
) as unknown as Plugin<any>,
79+
image() as unknown as Plugin<any>,
80+
);
81+
82+
if (commandArgs.analyzer) {
83+
plugins.push(
84+
visualizer({
85+
title: `Rollup Visualizer(${taskName})`,
86+
open: true,
87+
filename: `${taskName}-stats.html`,
88+
}) as unknown as Plugin,
89+
);
90+
}
91+
92+
options.plugins = plugins;
93+
94+
return (taskConfig.modifyRollupOptions ?? [(options) => options]).reduce(
95+
(prevOptions, modifyRollupOptions) =>
96+
modifyRollupOptions(prevOptions as unknown as RollupOptions) as RolldownOptions,
97+
options,
98+
);
99+
}

packages/pkg/src/engine/rollup/options.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,14 @@ interface GetRollupOutputsOptions {
168168
mode: NodeEnvMode;
169169
command: Context['command'];
170170
}
171-
function getRollupOutputs({ globals, bundleTaskConfig, pkg, mode, command }: GetRollupOutputsOptions): OutputOptions[] {
171+
172+
export function getRollupOutputs({
173+
globals,
174+
bundleTaskConfig,
175+
pkg,
176+
mode,
177+
command,
178+
}: GetRollupOutputsOptions): OutputOptions[] {
172179
const { outputDir, vendorName = 'vendor' } = bundleTaskConfig;
173180

174181
const outputFormats = bundleTaskConfig.formats ?? [];

packages/pkg/src/helpers/taskConfig.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ export function assertTaskBuildableConfig(
77
throw new Error('Only accept bundle or transform task.');
88
}
99
}
10+
11+
export function assertTaskBundleConfig(taskConfig: TaskConfig): asserts taskConfig is BundleTaskConfig {
12+
if (taskConfig.type !== 'bundle') {
13+
throw new Error('Only accept bundle task.');
14+
}
15+
}

packages/pkg/src/tasks/bundle.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import type { FSWatcher } from 'chokidar';
1818
import type { RslibConfig, rsbuild } from '@rslib/core';
1919
import { getRollupOptions } from '../engine/rollup/options.js';
2020
import { Runner } from '../helpers/runner.js';
21+
import { RolldownOptions } from 'rolldown';
2122
import { noop } from 'es-toolkit';
2223
import { consola } from 'consola';
2324

@@ -28,6 +29,7 @@ export function createBundleTask(taskRunningContext: TaskRunnerContext) {
2829
export class BundleRunner extends Runner<OutputResult> {
2930
private rollupOptions?: RollupOptions;
3031
private rslibConfig?: RslibConfig;
32+
private rolldownOptions?: RolldownOptions;
3133
private engine: EngineType;
3234
private watcher: Watcher | null = null;
3335
private result: Error | OutputResult | null = null;
@@ -45,6 +47,8 @@ export class BundleRunner extends Runner<OutputResult> {
4547
return this.handleRollupBuild(changedFiles);
4648
case 'rslib':
4749
return this.handleRslibBuild(changedFiles);
50+
case 'rolldown':
51+
return this.handleRolldownBuild(changedFiles);
4852
default:
4953
throw new Error(`Unsupported engine: ${this.engine}`);
5054
}
@@ -193,6 +197,23 @@ export class BundleRunner extends Runner<OutputResult> {
193197
outputFiles: stats?.assets as any,
194198
} as OutputResult;
195199
}
200+
201+
private async handleRolldownBuild(changedFiles: WatchChangedFile[]): Promise<OutputResult> {
202+
const { context } = this;
203+
const { build } = await import('rolldown');
204+
if (!this.rolldownOptions) {
205+
const { getRolldownOptions } = await import('../engine/rolldown/options.js');
206+
this.rolldownOptions = getRolldownOptions(context.buildContext, context);
207+
}
208+
const bundle = await build(this.rolldownOptions);
209+
210+
return {
211+
taskName: context.buildTask.name,
212+
// TODO: correct type and value
213+
outputs: bundle.output as any,
214+
outputFiles: bundle.output as any,
215+
};
216+
}
196217
}
197218

198219
// 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
312333

313334
const bundle = await rollup.rollup(rollupOptions);
314335

315-
const buildResult = await writeFiles((rollupOutputOptions as OutputOptions[]).filter(Boolean), bundle.write);
336+
const buildResult = await writeFiles((rollupOutputOptions as OutputOptions[]).filter(Boolean), bundle.write.bind(bundle));
316337

317338
await bundle.close();
318339

packages/pkg/src/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,11 @@ interface _TaskConfig {
312312
*/
313313
define?: PlainObject;
314314
/**
315-
* Define which bundler engine to use
315+
* Define which bundler engine to use.
316+
* - 'rollup'
317+
* - 'rslib' common used for mf build
318+
* - 'rolldown' experimental
319+
* @default 'rollup'
316320
*/
317321
engine?: EngineType;
318322
/**
@@ -361,7 +365,7 @@ interface _TaskConfig {
361365
pkg?: PkgResolvedConfig;
362366
}
363367

364-
export type EngineType = 'rollup' | 'rslib';
368+
export type EngineType = 'rollup' | 'rslib' | 'rolldown';
365369

366370
export interface BundleTaskConfig extends _TaskConfig, Omit<BundleUserConfig, 'minify' | 'formats'> {
367371
type: 'bundle';

0 commit comments

Comments
 (0)