Skip to content

Commit d3cfb26

Browse files
committed
build: use rolldown for dev script
1 parent 79eddcc commit d3cfb26

File tree

5 files changed

+44
-153
lines changed

5 files changed

+44
-153
lines changed

scripts/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ nr build core --formats cjs
1616
```
1717
*/
1818

19+
import { rolldown } from 'rolldown'
1920
import fs from 'node:fs'
2021
import { parseArgs } from 'node:util'
2122
import { existsSync, readFileSync } from 'node:fs'
@@ -26,7 +27,6 @@ import { targets as allTargets, fuzzyMatchTarget } from './utils.js'
2627
import prettyBytes from 'pretty-bytes'
2728
import { spawnSync } from 'node:child_process'
2829
import { createConfigsForPackage } from './create-rolldown-config.js'
29-
import { rolldown } from 'rolldown'
3030
import { scanEnums } from './inline-enums.js'
3131
import { fileURLToPath } from 'node:url'
3232

scripts/create-rolldown-config.js

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ const packagesDir = path.resolve(__dirname, '../packages')
2828
* devOnly?: boolean
2929
* prodOnly?: boolean
3030
* sourceMap?: boolean
31+
* localDev?: boolean
32+
* inlineDeps?: boolean
3133
* }} options
3234
*/
3335
export function createConfigsForPackage({
@@ -37,8 +39,10 @@ export function createConfigsForPackage({
3739
devOnly = false,
3840
prodOnly = false,
3941
sourceMap = false,
42+
localDev = false,
43+
inlineDeps = false,
4044
}) {
41-
const [enumPlugin, enumDefines] = inlineEnums()
45+
const [enumPlugin, enumDefines] = localDev ? [] : inlineEnums()
4246

4347
const packageDir = path.resolve(packagesDir, target)
4448
const resolve = (/** @type {string} */ p) => path.resolve(packageDir, p)
@@ -49,32 +53,32 @@ export function createConfigsForPackage({
4953
/** @type {Record<PackageFormat, import('rolldown').OutputOptions>} */
5054
const outputConfigs = {
5155
'esm-bundler': {
52-
entryFileNames: `${name}.esm-bundler.js`,
56+
file: `${name}.esm-bundler.js`,
5357
format: 'es',
5458
},
5559
'esm-browser': {
56-
entryFileNames: `${name}.esm-browser.js`,
60+
file: `${name}.esm-browser.js`,
5761
format: 'es',
5862
},
5963
cjs: {
60-
entryFileNames: `${name}.cjs.js`,
64+
file: `${name}.cjs.js`,
6165
format: 'cjs',
6266
},
6367
global: {
64-
entryFileNames: `${name}.global.js`,
68+
file: `${name}.global.js`,
6569
format: 'iife',
6670
},
6771
// runtime-only builds, for main "vue" package only
6872
'esm-bundler-runtime': {
69-
entryFileNames: `${name}.runtime.esm-bundler.js`,
73+
file: `${name}.runtime.esm-bundler.js`,
7074
format: 'es',
7175
},
7276
'esm-browser-runtime': {
73-
entryFileNames: `${name}.runtime.esm-browser.js`,
77+
file: `${name}.runtime.esm-browser.js`,
7478
format: 'es',
7579
},
7680
'global-runtime': {
77-
entryFileNames: `${name}.runtime.global.js`,
81+
file: `${name}.runtime.global.js`,
7882
format: 'iife',
7983
},
8084
}
@@ -117,9 +121,7 @@ export function createConfigsForPackage({
117121

118122
output.dir = resolve('dist')
119123

120-
const isProductionBuild = /\.prod\.js$/.test(
121-
String(output.entryFileNames) || '',
122-
)
124+
const isProductionBuild = /\.prod\.js$/.test(String(output.file) || '')
123125
const isBundlerESMBuild = /esm-bundler/.test(format)
124126
const isBrowserESMBuild = /esm-browser/.test(format)
125127
const isServerRenderer = name === 'server-renderer'
@@ -216,7 +218,7 @@ export function createConfigsForPackage({
216218
return defines
217219
}
218220

219-
// esbuild define is a bit strict and only allows literal json or identifiers
221+
// define is a bit strict and only allows literal json or identifiers
220222
// so we still need replace plugin in some cases
221223
function resolveReplace() {
222224
/** @type {Record<string, string>} */
@@ -272,7 +274,7 @@ export function createConfigsForPackage({
272274
]
273275
}
274276

275-
if (isGlobalBuild || isBrowserESMBuild || isCompatPackage) {
277+
if (isGlobalBuild || isBrowserESMBuild || isCompatPackage || inlineDeps) {
276278
if (!packageOptions.enableNonBrowserBranches) {
277279
// normal browser builds - non-browser only imports are tree-shaken,
278280
// they are only listed here to suppress warnings.
@@ -314,9 +316,9 @@ export function createConfigsForPackage({
314316
resolve: {
315317
alias: entries,
316318
},
319+
// @ts-expect-error rollup's Plugin type incompatible w/ rolldown's vendored Plugin type
317320
plugins: [
318-
// @ts-expect-error rollup's Plugin type incompatible w/ rolldown's vendored Plugin type
319-
enumPlugin,
321+
...(localDev ? [] : [enumPlugin]),
320322
...resolveReplace(),
321323
...resolveNodePlugins(),
322324
...plugins,
@@ -336,7 +338,7 @@ export function createConfigsForPackage({
336338

337339
function createProductionConfig(/** @type {PackageFormat} */ format) {
338340
return createConfig(format, {
339-
entryFileNames: `${name}.${format}.prod.js`,
341+
file: `${name}.${format}.prod.js`,
340342
format: outputConfigs[format].format,
341343
})
342344
}
@@ -345,10 +347,7 @@ export function createConfigsForPackage({
345347
return createConfig(
346348
format,
347349
{
348-
entryFileNames: String(outputConfigs[format].entryFileNames).replace(
349-
/\.js$/,
350-
'.prod.js',
351-
),
350+
file: String(outputConfigs[format].file).replace(/\.js$/, '.prod.js'),
352351
format: outputConfigs[format].format,
353352
// minify: true,
354353
},

scripts/dev.js

Lines changed: 22 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
11
// @ts-check
22

3-
// Using esbuild for faster dev builds.
4-
// We are still using Rollup for production builds because it generates
5-
// smaller files and provides better tree-shaking.
6-
7-
import esbuild from 'esbuild'
8-
import fs from 'node:fs'
9-
import { dirname, relative, resolve } from 'node:path'
10-
import { fileURLToPath } from 'node:url'
11-
import { createRequire } from 'node:module'
3+
import { watch } from 'rolldown'
4+
import { createConfigsForPackage } from './create-rolldown-config.js'
125
import { parseArgs } from 'node:util'
13-
import { polyfillNode } from 'esbuild-plugin-polyfill-node'
14-
15-
const require = createRequire(import.meta.url)
16-
const __dirname = dirname(fileURLToPath(import.meta.url))
176

187
const {
198
values: { format: rawFormat, prod, inline: inlineDeps },
@@ -40,123 +29,26 @@ const {
4029
})
4130

4231
const format = rawFormat || 'global'
43-
const targets = positionals.length ? positionals : ['vue']
44-
45-
// resolve output
46-
const outputFormat = format.startsWith('global')
47-
? 'iife'
48-
: format === 'cjs'
49-
? 'cjs'
50-
: 'esm'
51-
52-
const postfix = format.endsWith('-runtime')
53-
? `runtime.${format.replace(/-runtime$/, '')}`
54-
: format
55-
56-
const privatePackages = fs.readdirSync('packages-private')
57-
58-
for (const target of targets) {
59-
const pkgBase = privatePackages.includes(target)
60-
? `packages-private`
61-
: `packages`
62-
const pkgBasePath = `../${pkgBase}/${target}`
63-
const pkg = require(`${pkgBasePath}/package.json`)
64-
const outfile = resolve(
65-
__dirname,
66-
`${pkgBasePath}/dist/${
67-
target === 'vue-compat' ? `vue` : target
68-
}.${postfix}.${prod ? `prod.` : ``}js`,
69-
)
70-
const relativeOutfile = relative(process.cwd(), outfile)
32+
const target = positionals.length ? positionals[0] : 'vue'
33+
34+
const [config, prodConfig] = createConfigsForPackage({
35+
target,
36+
commit: 'dev',
37+
// @ts-expect-error
38+
formats: [format],
39+
devOnly: !prod,
40+
sourceMap: true,
41+
localDev: true,
42+
inlineDeps,
43+
})
7144

72-
// resolve externals
73-
// TODO this logic is largely duplicated from rollup.config.js
74-
/** @type {string[]} */
75-
let external = []
76-
if (!inlineDeps) {
77-
// cjs & esm-bundler: external all deps
78-
if (format === 'cjs' || format.includes('esm-bundler')) {
79-
external = [
80-
...external,
81-
...Object.keys(pkg.dependencies || {}),
82-
...Object.keys(pkg.peerDependencies || {}),
83-
// for @vue/compiler-sfc / server-renderer
84-
'path',
85-
'url',
86-
'stream',
87-
]
88-
}
45+
const configToUse = prod ? prodConfig : config
8946

90-
if (target === 'compiler-sfc') {
91-
const consolidatePkgPath = require.resolve(
92-
'@vue/consolidate/package.json',
93-
{
94-
paths: [resolve(__dirname, `../packages/${target}/`)],
95-
},
96-
)
97-
const consolidateDeps = Object.keys(
98-
require(consolidatePkgPath).devDependencies,
99-
)
100-
external = [
101-
...external,
102-
...consolidateDeps,
103-
'fs',
104-
'vm',
105-
'crypto',
106-
'react-dom/server',
107-
'teacup/lib/express',
108-
'arc-templates/dist/es5',
109-
'then-pug',
110-
'then-jade',
111-
]
47+
watch(configToUse).then(watcher => {
48+
console.log(`watching: ${configToUse.output.file}`)
49+
watcher.on('event', event => {
50+
if (event.code === 'BUNDLE_END') {
51+
console.log(`rebuilt ${config.output.file} in ${event.duration}ms`)
11252
}
113-
}
114-
/** @type {Array<import('esbuild').Plugin>} */
115-
const plugins = [
116-
{
117-
name: 'log-rebuild',
118-
setup(build) {
119-
build.onEnd(() => {
120-
console.log(`built: ${relativeOutfile}`)
121-
})
122-
},
123-
},
124-
]
125-
126-
if (format !== 'cjs' && pkg.buildOptions?.enableNonBrowserBranches) {
127-
plugins.push(polyfillNode())
128-
}
129-
130-
esbuild
131-
.context({
132-
entryPoints: [resolve(__dirname, `${pkgBasePath}/src/index.ts`)],
133-
outfile,
134-
bundle: true,
135-
external,
136-
sourcemap: true,
137-
format: outputFormat,
138-
globalName: pkg.buildOptions?.name,
139-
platform: format === 'cjs' ? 'node' : 'browser',
140-
plugins,
141-
define: {
142-
__COMMIT__: `"dev"`,
143-
__VERSION__: `"${pkg.version}"`,
144-
__DEV__: prod ? `false` : `true`,
145-
__TEST__: `false`,
146-
__BROWSER__: String(
147-
format !== 'cjs' && !pkg.buildOptions?.enableNonBrowserBranches,
148-
),
149-
__GLOBAL__: String(format === 'global'),
150-
__ESM_BUNDLER__: String(format.includes('esm-bundler')),
151-
__ESM_BROWSER__: String(format.includes('esm-browser')),
152-
__CJS__: String(format === 'cjs'),
153-
__SSR__: String(format !== 'global'),
154-
__COMPAT__: String(target === 'vue-compat'),
155-
__FEATURE_SUSPENSE__: `true`,
156-
__FEATURE_OPTIONS_API__: `true`,
157-
__FEATURE_PROD_DEVTOOLS__: `false`,
158-
__FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__: `true`,
159-
},
160-
})
161-
.then(ctx => ctx.watch())
162-
}
53+
})
54+
})

scripts/inline-enums.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export function inlineEnums() {
233233

234234
// 3. during transform:
235235
// 3.1 files w/ enum declaration: rewrite declaration as object literal
236-
// 3.2 files using enum: inject into esbuild define
236+
// 3.2 files using enum: inject into rolldown define
237237
/**
238238
* @type {import('rollup').Plugin}
239239
*/

scripts/verify-treeshaking.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ exec('pnpm', ['build', 'vue', '-f', 'global-runtime']).then(() => {
1212

1313
if (devBuild.includes('__spreadValues')) {
1414
errors.push(
15-
'dev build contains unexpected esbuild object spread helper.\n' +
15+
'dev build contains unexpected object spread helper.\n' +
1616
'This means { ...obj } syntax is used in runtime code. This should be ' +
1717
'refactored to use the `extend` helper to avoid the extra code.',
1818
)

0 commit comments

Comments
 (0)