wip: use rolldown

This commit is contained in:
daiwei 2025-08-25 11:16:32 +08:00
parent a251b2ef23
commit 87190a2893
11 changed files with 43 additions and 51 deletions

View File

@ -94,8 +94,7 @@ $ pnpm i # install the dependencies of the project
A high level overview of tools used: A high level overview of tools used:
- [TypeScript](https://www.typescriptlang.org/) as the development language - [TypeScript](https://www.typescriptlang.org/) as the development language
- [Vite](https://vitejs.dev/) and [ESBuild](https://esbuild.github.io/) for development bundling - [Rolldown](https://rolldown.rs/) for bundling
- [Rollup](https://rollupjs.org) for production bundling
- [Vitest](https://vitest.dev/) for unit testing - [Vitest](https://vitest.dev/) for unit testing
- [Prettier](https://prettier.io/) for code formatting - [Prettier](https://prettier.io/) for code formatting
- [ESLint](https://eslint.org/) for static error prevention (outside of types) - [ESLint](https://eslint.org/) for static error prevention (outside of types)
@ -138,7 +137,7 @@ nr build runtime-core
nr build runtime --all nr build runtime --all
``` ```
Note that `nr build` uses `rollup-plugin-esbuild` for transpiling typescript and **does not perform type checking**. To run type check on the entire codebase, run `nr check`. Type checks are also automatically run on each commit. Note that `nr build` uses [`oxc-transform`](https://oxc.rs/docs/guide/usage/transformer.html) for transpiling typescript and **does not perform type checking**. To run type check on the entire codebase, run `nr check`. Type checks are also automatically run on each commit.
#### Build Formats #### Build Formats
@ -155,7 +154,7 @@ Additional formats that only apply to the main `vue` package:
- **`esm-bundler-runtime`** - **`esm-bundler-runtime`**
- **`esm-browser-runtime`** - **`esm-browser-runtime`**
More details about each of these formats can be found in the [`vue` package README](https://github.com/vuejs/core/blob/main/packages/vue/README.md#which-dist-file-to-use) and the [Rollup config file](https://github.com/vuejs/core/blob/main/rollup.config.js). More details about each of these formats can be found in the [`vue` package README](https://github.com/vuejs/core/blob/main/packages/vue/README.md#which-dist-file-to-use) and the [Rolldown config file](https://github.com/vuejs/core/blob/main/scripts/create-rolldown-config.js).
For example, to build `runtime-core` with the global build only: For example, to build `runtime-core` with the global build only:
@ -175,7 +174,7 @@ Use the `--sourcemap` or `-s` flag to build with source maps. Note this will mak
### `nr build-dts` ### `nr build-dts`
This command builds the type declarations for all packages. It first generates the raw `.d.ts` files in the `temp` directory, then uses [rollup-plugin-dts](https://github.com/Swatinem/rollup-plugin-dts) to roll the types into a single `.d.ts` file for each package. This command builds the type declarations for all packages. It first generates the raw `.d.ts` files in the `temp` directory, then uses [rolldown-plugin-dts](https://github.com/sxzz/rolldown-plugin-dts) to roll the types into a single `.d.ts` file for each package.
### `nr check` ### `nr check`
@ -283,7 +282,7 @@ import { h } from '@vue/runtime-core'
This is made possible via several configurations: This is made possible via several configurations:
- For TypeScript, `compilerOptions.paths` in `tsconfig.json` - For TypeScript, `compilerOptions.paths` in `tsconfig.json`
- Vitest and Rollup share the same set of aliases from `scripts/aliases.js` - Vitest and Rolldown share the same set of aliases from `scripts/aliases.js`
- For plain Node.js, they are linked using [PNPM Workspaces](https://pnpm.io/workspaces). - For plain Node.js, they are linked using [PNPM Workspaces](https://pnpm.io/workspaces).
### Package Dependencies ### Package Dependencies

View File

@ -28,10 +28,9 @@
groupName: 'build', groupName: 'build',
matchPackageNames: [ matchPackageNames: [
'vite', 'vite',
'@swc/core', 'rolldown{/,}**',
'rollup{/,}**', '@rolldown{/,}**',
'esbuild{/,}**', 'oxc{/,}**',
'@rollup{/,}**',
'@vitejs{/,}**', '@vitejs{/,}**',
], ],
}, },

View File

@ -124,7 +124,7 @@ export const transformAssetUrl: NodeTransform = (
const basePath = base.path || '/' const basePath = base.path || '/'
// when packaged in the browser, path will be using the posix- // when packaged in the browser, path will be using the posix-
// only version provided by rollup-plugin-node-builtins. // only version provided by @rolldown/plugin-node-polyfills.
attr.value.content = attr.value.content =
host + host +
(path.posix || path).join(basePath, url.path + (url.hash || '')) (path.posix || path).join(basePath, url.path + (url.hash || ''))

View File

@ -3,7 +3,7 @@
* is in that map. * is in that map.
* IMPORTANT: all calls of this function must be prefixed with * IMPORTANT: all calls of this function must be prefixed with
* \/\*#\_\_PURE\_\_\*\/ * \/\*#\_\_PURE\_\_\*\/
* So that rollup can tree-shake them if necessary. * So that they can be tree-shaken if necessary.
*/ */
/*! #__NO_SIDE_EFFECTS__ */ /*! #__NO_SIDE_EFFECTS__ */

View File

@ -22,7 +22,7 @@
- **`vue(.runtime).esm-bundler.js`**: - **`vue(.runtime).esm-bundler.js`**:
- For use with bundlers like `webpack`, `rollup` and `parcel`. - For use with bundlers like `rolldown`, `webpack`, `rollup` and `parcel`.
- Leaves prod/dev branches with `process.env.NODE_ENV` guards (must be replaced by bundler) - Leaves prod/dev branches with `process.env.NODE_ENV` guards (must be replaced by bundler)
- Does not ship minified builds (to be done together with the rest of the code after bundling) - Does not ship minified builds (to be done together with the rest of the code after bundling)
- Imports dependencies (e.g. `@vue/runtime-core`, `@vue/compiler-core`) - Imports dependencies (e.g. `@vue/runtime-core`, `@vue/compiler-core`)

View File

@ -1,5 +1,5 @@
// @ts-check // @ts-check
// these aliases are shared between vitest and rollup // these aliases are shared between vitest and rolldown
import { readdirSync, statSync } from 'node:fs' import { readdirSync, statSync } from 'node:fs'
import path from 'node:path' import path from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'

View File

@ -23,10 +23,7 @@ for (const file of await glob('packages/*/src/**/*.ts')) {
}) })
if (dts.errors.length) { if (dts.errors.length) {
dts.errors.forEach(err => { dts.errors.forEach(err => {
// temporary workaround for https://github.com/oxc-project/oxc/issues/5668 console.error(err)
if (!err.includes('set value(_: S)')) {
console.error(err)
}
errs += err + '\n' errs += err + '\n'
}) })
} }

View File

@ -147,7 +147,6 @@ export function createConfigsForPackage({
output.externalLiveBindings = false output.externalLiveBindings = false
// https://github.com/rollup/rollup/pull/5380
// @ts-expect-error Not supported yet // @ts-expect-error Not supported yet
output.reexportProtoFromExternal = false output.reexportProtoFromExternal = false
@ -158,7 +157,7 @@ export function createConfigsForPackage({
let entryFile = /runtime$/.test(format) ? `src/runtime.ts` : `src/index.ts` let entryFile = /runtime$/.test(format) ? `src/runtime.ts` : `src/index.ts`
// the compat build needs both default AND named exports. This will cause // the compat build needs both default AND named exports. This will cause
// Rollup to complain for non-ESM targets, so we use separate entries for // Rolldown to complain for non-ESM targets, so we use separate entries for
// esm vs. non-esm builds. // esm vs. non-esm builds.
if (isCompatPackage && (isBrowserESMBuild || isBundlerESMBuild)) { if (isCompatPackage && (isBrowserESMBuild || isBundlerESMBuild)) {
entryFile = /runtime$/.test(format) entryFile = /runtime$/.test(format)
@ -240,7 +239,11 @@ export function createConfigsForPackage({
} }
if (Object.keys(replacements).length) { if (Object.keys(replacements).length) {
return [replacePlugin(replacements)] return [
replacePlugin(replacements, {
preventAssignment: true,
}),
]
} else { } else {
return [] return []
} }
@ -328,7 +331,6 @@ export function createConfigsForPackage({
} }
}, },
treeshake: { treeshake: {
// https://github.com/rolldown/rolldown/issues/1917
moduleSideEffects: false, moduleSideEffects: false,
}, },
} }

View File

@ -44,11 +44,9 @@ const [config, prodConfig] = createConfigsForPackage({
const configToUse = prod ? prodConfig : config const configToUse = prod ? prodConfig : config
watch(configToUse).then(watcher => { console.log(`watching: ${configToUse.output.file}`)
console.log(`watching: ${configToUse.output.file}`) watch(configToUse).on('event', event => {
watcher.on('event', event => { if (event.code === 'BUNDLE_END') {
if (event.code === 'BUNDLE_END') { console.log(`rebuilt ${config.output.file} in ${event.duration}ms`)
console.log(`rebuilt ${config.output.file} in ${event.duration}ms`) }
}
})
}) })

View File

@ -52,7 +52,7 @@ function isStringOrNumberLiteral(exp) {
} }
// this is called in the build script entry once // this is called in the build script entry once
// so the data can be shared across concurrent Rollup processes // so the data can be shared across concurrent Rolldown processes
export function scanEnums() { export function scanEnums() {
/** @type {{ [file: string]: EnumDeclaration[] }} */ /** @type {{ [file: string]: EnumDeclaration[] }} */
const declarations = Object.create(null) const declarations = Object.create(null)
@ -72,7 +72,6 @@ export function scanEnums() {
] ]
// 2. parse matched files to collect enum info // 2. parse matched files to collect enum info
let i = 0
for (const relativeFile of files) { for (const relativeFile of files) {
const file = path.resolve(process.cwd(), relativeFile) const file = path.resolve(process.cwd(), relativeFile)
const content = readFileSync(file, 'utf-8') const content = readFileSync(file, 'utf-8')
@ -234,7 +233,7 @@ export function scanEnums() {
} }
/** /**
* @returns {[import('rollup').Plugin, Record<string, string>]} * @returns {[import('rolldown').Plugin, Record<string, string>]}
*/ */
export function inlineEnums() { export function inlineEnums() {
if (!existsSync(ENUM_CACHE_PATH)) { if (!existsSync(ENUM_CACHE_PATH)) {
@ -249,7 +248,7 @@ export function inlineEnums() {
// 3.1 files w/ enum declaration: rewrite declaration as object literal // 3.1 files w/ enum declaration: rewrite declaration as object literal
// 3.2 files using enum: inject into rolldown define // 3.2 files using enum: inject into rolldown define
/** /**
* @type {import('rollup').Plugin} * @type {import('rolldown').Plugin}
*/ */
const plugin = { const plugin = {
name: 'inline-enum', name: 'inline-enum',

View File

@ -2,9 +2,8 @@
import { mkdir, writeFile } from 'node:fs/promises' import { mkdir, writeFile } from 'node:fs/promises'
import path from 'node:path' import path from 'node:path'
import { rolldown } from 'rolldown' import { rolldown } from 'rolldown'
import nodeResolve from '@rollup/plugin-node-resolve'
import { minify } from 'oxc-minify' import { minify } from 'oxc-minify'
import replace from '@rollup/plugin-replace' import { replacePlugin } from 'rolldown/experimental'
import { brotliCompressSync, gzipSync } from 'node:zlib' import { brotliCompressSync, gzipSync } from 'node:zlib'
import { parseArgs } from 'node:util' import { parseArgs } from 'node:util'
import pico from 'picocolors' import pico from 'picocolors'
@ -108,28 +107,27 @@ async function generateBundle(preset) {
if (_id === id) return content if (_id === id) return content
}, },
}, },
nodeResolve(), replacePlugin(
replace({ {
'process.env.NODE_ENV': '"production"', 'process.env.NODE_ENV': '"production"',
__VUE_PROD_DEVTOOLS__: 'false', __VUE_PROD_DEVTOOLS__: 'false',
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false', __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
__VUE_OPTIONS_API__: 'true', __VUE_OPTIONS_API__: 'true',
preventAssignment: true, ...preset.replace,
...preset.replace, },
}), { preventAssignment: true },
),
], ],
}) })
const generated = await result.generate({}) const generated = await result.generate({})
const bundled = generated.output[0].code const bundled = generated.output[0].code
const file = preset.name + '.js' const file = preset.name + '.js'
const minified = ( const minified = minify(file, bundled, {
await minify(file, bundled, { mangle: {
mangle: { toplevel: true,
toplevel: true, },
}, }).code
})
).code
const size = minified.length const size = minified.length
const gzip = gzipSync(minified).length const gzip = gzipSync(minified).length