Skip to content

Commit 6241902

Browse files
committed
chore: use rolldown to bundle Vite itself
1 parent e41f48d commit 6241902

File tree

4 files changed

+236
-134
lines changed

4 files changed

+236
-134
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
"bcrypt",
138138
"esbuild",
139139
"playwright-chromium",
140+
"rolldown",
140141
"simple-git-hooks",
141142
"workerd"
142143
]

packages/vite/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@
7373
"scripts": {
7474
"dev": "tsx scripts/dev.ts",
7575
"build": "premove dist && pnpm build-bundle && pnpm build-types",
76-
"build-bundle": "rollup --config rollup.config.ts --configPlugin esbuild",
76+
"build-bundle": "ROLLDOWN_OPTIONS_VALIDATION=loose rolldown --config rollup.config.ts",
7777
"build-types": "pnpm build-types-temp && pnpm build-types-roll && pnpm build-types-check",
7878
"build-types-temp": "tsc --emitDeclarationOnly --outDir temp -p src/node/tsconfig.build.json",
79-
"build-types-roll": "rollup --config rollup.dts.config.ts --configPlugin esbuild && premove temp",
79+
"build-types-roll": "NODE_OPTIONS='--import tsx' rollup --config rollup.dts.config.ts && premove temp",
8080
"build-types-check": "tsc --project tsconfig.check.json",
8181
"typecheck": "tsc --noEmit && tsc --noEmit -p src/node",
8282
"lint": "eslint --cache --ext .ts src/**",
@@ -99,6 +99,7 @@
9999
"@ampproject/remapping": "^2.3.0",
100100
"@babel/parser": "^7.27.0",
101101
"@jridgewell/trace-mapping": "^0.3.25",
102+
"@oxc-project/runtime": "^0.65.0",
102103
"@polka/compression": "^1.0.0-next.25",
103104
"@rollup/plugin-alias": "^5.1.1",
104105
"@rollup/plugin-commonjs": "^28.0.3",
@@ -139,8 +140,8 @@
139140
"postcss-load-config": "^6.0.1",
140141
"postcss-modules": "^6.0.1",
141142
"resolve.exports": "^2.0.3",
143+
"rolldown": "^1.0.0-beta.8",
142144
"rollup-plugin-dts": "^6.2.1",
143-
"rollup-plugin-esbuild": "^6.2.1",
144145
"rollup-plugin-license": "^3.6.0",
145146
"sass": "^1.86.3",
146147
"sass-embedded": "^1.86.3",

packages/vite/rollup.config.ts

Lines changed: 57 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
import { readFileSync } from 'node:fs'
22
import path from 'node:path'
33
import { fileURLToPath } from 'node:url'
4-
import alias from '@rollup/plugin-alias'
5-
import nodeResolve from '@rollup/plugin-node-resolve'
6-
import commonjs from '@rollup/plugin-commonjs'
7-
import json from '@rollup/plugin-json'
84
import MagicString from 'magic-string'
9-
import type { Plugin } from 'rollup'
10-
import { defineConfig } from 'rollup'
11-
import esbuild, { type Options as esbuildOptions } from 'rollup-plugin-esbuild'
5+
import type { Plugin } from 'rolldown'
6+
import { defineConfig } from 'rolldown'
127
import { init, parse } from 'es-module-lexer'
138
import licensePlugin from './rollupLicensePlugin'
149

@@ -20,46 +15,40 @@ const __dirname = fileURLToPath(new URL('.', import.meta.url))
2015

2116
const envConfig = defineConfig({
2217
input: path.resolve(__dirname, 'src/client/env.ts'),
23-
plugins: [
24-
esbuild({
25-
tsconfig: path.resolve(__dirname, 'src/client/tsconfig.json'),
26-
}),
27-
],
18+
platform: 'browser',
2819
output: {
29-
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
20+
dir: path.resolve(__dirname, 'dist'),
21+
entryFileNames: 'client/env.mjs',
22+
target: 'es2020',
3023
},
3124
})
3225

3326
const clientConfig = defineConfig({
3427
input: path.resolve(__dirname, 'src/client/client.ts'),
28+
platform: 'browser',
3529
external: ['@vite/env'],
36-
plugins: [
37-
nodeResolve({ preferBuiltins: true }),
38-
esbuild({
39-
tsconfig: path.resolve(__dirname, 'src/client/tsconfig.json'),
40-
}),
41-
],
4230
output: {
43-
file: path.resolve(__dirname, 'dist/client', 'client.mjs'),
31+
dir: path.resolve(__dirname, 'dist'),
32+
entryFileNames: 'client/client.mjs',
33+
target: 'es2020',
4434
},
4535
})
4636

4737
const sharedNodeOptions = defineConfig({
38+
platform: 'node',
4839
treeshake: {
49-
moduleSideEffects(id, external) {
50-
id = id.replaceAll('\\', '/')
51-
// These nested dependencies should be considered side-effect free
52-
// as it's not set within their package.json
53-
if (
54-
id.includes('node_modules/astring') ||
55-
id.includes('node_modules/acorn')
56-
) {
57-
return false
58-
}
59-
return !external
60-
},
61-
propertyReadSideEffects: false,
62-
tryCatchDeoptimization: false,
40+
moduleSideEffects: [
41+
{
42+
test: /acorn|astring|escape-html/,
43+
sideEffects: false,
44+
},
45+
{
46+
external: true,
47+
sideEffects: false,
48+
},
49+
],
50+
// TODO: not supported yet
51+
// propertyReadSideEffects: false,
6352
},
6453
output: {
6554
dir: './dist',
@@ -68,7 +57,6 @@ const sharedNodeOptions = defineConfig({
6857
exports: 'named',
6958
format: 'esm',
7059
externalLiveBindings: false,
71-
freeze: false,
7260
},
7361
onwarn(warning, warn) {
7462
if (warning.message.includes('Circular dependency')) {
@@ -78,77 +66,45 @@ const sharedNodeOptions = defineConfig({
7866
},
7967
})
8068

81-
function createSharedNodePlugins({
82-
esbuildOptions,
83-
}: {
84-
esbuildOptions?: esbuildOptions
85-
}): Plugin[] {
86-
return [
87-
alias({
88-
entries: {
89-
// we can always use node version (the default entry point has browser support)
90-
debug: 'debug/src/node.js',
91-
},
92-
}),
93-
nodeResolve({ preferBuiltins: true }),
94-
esbuild({
95-
tsconfig: path.resolve(__dirname, 'src/node/tsconfig.json'),
96-
target: 'node18',
97-
...esbuildOptions,
98-
}),
99-
commonjs({
100-
extensions: ['.js'],
101-
// Optional peer deps of ws. Native deps that are mostly for performance.
102-
// Since ws is not that perf critical for us, just ignore these deps.
103-
ignore: ['bufferutil', 'utf-8-validate'],
104-
sourceMap: false,
105-
strictRequires: 'auto',
106-
}),
107-
json(),
108-
]
109-
}
110-
11169
const nodeConfig = defineConfig({
11270
...sharedNodeOptions,
11371
input: {
11472
index: path.resolve(__dirname, 'src/node/index.ts'),
11573
cli: path.resolve(__dirname, 'src/node/cli.ts'),
11674
constants: path.resolve(__dirname, 'src/node/constants.ts'),
11775
},
76+
resolve: {
77+
alias: {
78+
// we can always use node version (the default entry point has browser support)
79+
debug: 'debug/src/node.js',
80+
},
81+
},
82+
output: {
83+
...sharedNodeOptions.output,
84+
// When polyfillRequire is enabled, `require` gets renamed by rolldown.
85+
// But the current usage of require() inside inlined workers expects `require`
86+
// to not be renamed. To workaround, polyfillRequire is disabled and
87+
// the banner is used instead.
88+
// Ideally we should move workers to ESM
89+
polyfillRequire: false,
90+
banner:
91+
"import { createRequire as ___createRequire } from 'module'; const require = ___createRequire(import.meta.url);",
92+
},
11893
external: [
11994
/^vite\//,
12095
'fsevents',
12196
'rollup/parseAst',
12297
/^tsx\//,
12398
/^#/,
99+
'sugarss', // postcss-import -> sugarss
100+
'supports-color',
101+
'utf-8-validate', // ws
102+
'bufferutil', // ws
124103
...Object.keys(pkg.dependencies),
125104
...Object.keys(pkg.peerDependencies),
126105
],
127106
plugins: [
128-
// Some deps have try...catch require of optional deps, but rollup will
129-
// generate code that force require them upfront for side effects.
130-
// Shim them with eval() so rollup can skip these calls.
131107
shimDepsPlugin({
132-
// chokidar -> fsevents
133-
'fsevents-handler.js': [
134-
{
135-
src: `require('fsevents')`,
136-
replacement: `__require('fsevents')`,
137-
},
138-
],
139-
// postcss-import -> sugarss
140-
'process-content.js': [
141-
{
142-
src: 'require("sugarss")',
143-
replacement: `__require('sugarss')`,
144-
},
145-
],
146-
'lilconfig/src/index.js': [
147-
{
148-
pattern: /: require;/g,
149-
replacement: ': __require;',
150-
},
151-
],
152108
'postcss-load-config/src/req.js': [
153109
{
154110
src: "const { pathToFileURL } = require('node:url')",
@@ -180,14 +136,12 @@ const nodeConfig = defineConfig({
180136
},
181137
],
182138
}),
183-
...createSharedNodePlugins({}),
184139
buildTimeImportMetaUrlPlugin(),
185140
licensePlugin(
186141
path.resolve(__dirname, 'LICENSE.md'),
187142
'Vite core license',
188143
'Vite',
189-
),
190-
cjsPatchPlugin(),
144+
) as Plugin,
191145
],
192146
})
193147

@@ -202,10 +156,15 @@ const moduleRunnerConfig = defineConfig({
202156
'rollup/parseAst',
203157
...Object.keys(pkg.dependencies),
204158
],
205-
plugins: [
206-
...createSharedNodePlugins({ esbuildOptions: { minifySyntax: true } }),
207-
bundleSizeLimit(54),
208-
],
159+
plugins: [bundleSizeLimit(54)],
160+
output: {
161+
...sharedNodeOptions.output,
162+
minify: {
163+
compress: true,
164+
mangle: false,
165+
removeWhitespace: false,
166+
},
167+
},
209168
})
210169

211170
const cjsConfig = defineConfig({
@@ -218,13 +177,10 @@ const cjsConfig = defineConfig({
218177
entryFileNames: `node-cjs/[name].cjs`,
219178
chunkFileNames: 'node-cjs/chunks/dep-[hash].js',
220179
format: 'cjs',
180+
target: 'es2022', // TODO: use node18
221181
},
222-
external: ['fsevents', ...Object.keys(pkg.dependencies)],
223-
plugins: [
224-
...createSharedNodePlugins({}),
225-
bundleSizeLimit(175),
226-
exportCheck(),
227-
],
182+
external: ['fsevents', 'supports-color', ...Object.keys(pkg.dependencies)],
183+
plugins: [bundleSizeLimit(175), exportCheck()],
228184
})
229185

230186
export default defineConfig([
@@ -384,33 +340,6 @@ function buildTimeImportMetaUrlPlugin(): Plugin {
384340
}
385341
}
386342

387-
/**
388-
* Inject CJS Context for each deps chunk
389-
*/
390-
function cjsPatchPlugin(): Plugin {
391-
const cjsPatch = `
392-
import { createRequire as __cjs_createRequire } from 'node:module';
393-
394-
const __require = __cjs_createRequire(import.meta.url);
395-
`.trimStart()
396-
397-
return {
398-
name: 'cjs-chunk-patch',
399-
renderChunk(code, chunk) {
400-
if (!chunk.fileName.includes('chunks/dep-')) return
401-
if (!code.includes('__require')) return
402-
403-
const match = /^(?:import[\s\S]*?;\s*)+/.exec(code)
404-
const index = match ? match.index! + match[0].length : 0
405-
const s = new MagicString(code)
406-
// inject after the last `import`
407-
s.appendRight(index, cjsPatch)
408-
console.log('patched cjs context: ' + chunk.fileName)
409-
return s.toString()
410-
},
411-
}
412-
}
413-
414343
/**
415344
* Guard the bundle size
416345
*

0 commit comments

Comments
 (0)