From: Evan You Date: Fri, 8 Nov 2024 11:55:14 +0000 (+0800) Subject: build: use rolldown for dev script X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d3cfb2684e8a139d37afd8d06dd81af215c9ff72;p=thirdparty%2Fvuejs%2Fcore.git build: use rolldown for dev script --- diff --git a/scripts/build.js b/scripts/build.js index a1b23ed6a9..f3d9127798 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -16,6 +16,7 @@ nr build core --formats cjs ``` */ +import { rolldown } from 'rolldown' import fs from 'node:fs' import { parseArgs } from 'node:util' import { existsSync, readFileSync } from 'node:fs' @@ -26,7 +27,6 @@ import { targets as allTargets, fuzzyMatchTarget } from './utils.js' import prettyBytes from 'pretty-bytes' import { spawnSync } from 'node:child_process' import { createConfigsForPackage } from './create-rolldown-config.js' -import { rolldown } from 'rolldown' import { scanEnums } from './inline-enums.js' import { fileURLToPath } from 'node:url' diff --git a/scripts/create-rolldown-config.js b/scripts/create-rolldown-config.js index b5a5d80872..cdc2320a35 100644 --- a/scripts/create-rolldown-config.js +++ b/scripts/create-rolldown-config.js @@ -28,6 +28,8 @@ const packagesDir = path.resolve(__dirname, '../packages') * devOnly?: boolean * prodOnly?: boolean * sourceMap?: boolean + * localDev?: boolean + * inlineDeps?: boolean * }} options */ export function createConfigsForPackage({ @@ -37,8 +39,10 @@ export function createConfigsForPackage({ devOnly = false, prodOnly = false, sourceMap = false, + localDev = false, + inlineDeps = false, }) { - const [enumPlugin, enumDefines] = inlineEnums() + const [enumPlugin, enumDefines] = localDev ? [] : inlineEnums() const packageDir = path.resolve(packagesDir, target) const resolve = (/** @type {string} */ p) => path.resolve(packageDir, p) @@ -49,32 +53,32 @@ export function createConfigsForPackage({ /** @type {Record} */ const outputConfigs = { 'esm-bundler': { - entryFileNames: `${name}.esm-bundler.js`, + file: `${name}.esm-bundler.js`, format: 'es', }, 'esm-browser': { - entryFileNames: `${name}.esm-browser.js`, + file: `${name}.esm-browser.js`, format: 'es', }, cjs: { - entryFileNames: `${name}.cjs.js`, + file: `${name}.cjs.js`, format: 'cjs', }, global: { - entryFileNames: `${name}.global.js`, + file: `${name}.global.js`, format: 'iife', }, // runtime-only builds, for main "vue" package only 'esm-bundler-runtime': { - entryFileNames: `${name}.runtime.esm-bundler.js`, + file: `${name}.runtime.esm-bundler.js`, format: 'es', }, 'esm-browser-runtime': { - entryFileNames: `${name}.runtime.esm-browser.js`, + file: `${name}.runtime.esm-browser.js`, format: 'es', }, 'global-runtime': { - entryFileNames: `${name}.runtime.global.js`, + file: `${name}.runtime.global.js`, format: 'iife', }, } @@ -117,9 +121,7 @@ export function createConfigsForPackage({ output.dir = resolve('dist') - const isProductionBuild = /\.prod\.js$/.test( - String(output.entryFileNames) || '', - ) + const isProductionBuild = /\.prod\.js$/.test(String(output.file) || '') const isBundlerESMBuild = /esm-bundler/.test(format) const isBrowserESMBuild = /esm-browser/.test(format) const isServerRenderer = name === 'server-renderer' @@ -216,7 +218,7 @@ export function createConfigsForPackage({ return defines } - // esbuild define is a bit strict and only allows literal json or identifiers + // define is a bit strict and only allows literal json or identifiers // so we still need replace plugin in some cases function resolveReplace() { /** @type {Record} */ @@ -272,7 +274,7 @@ export function createConfigsForPackage({ ] } - if (isGlobalBuild || isBrowserESMBuild || isCompatPackage) { + if (isGlobalBuild || isBrowserESMBuild || isCompatPackage || inlineDeps) { if (!packageOptions.enableNonBrowserBranches) { // normal browser builds - non-browser only imports are tree-shaken, // they are only listed here to suppress warnings. @@ -314,9 +316,9 @@ export function createConfigsForPackage({ resolve: { alias: entries, }, + // @ts-expect-error rollup's Plugin type incompatible w/ rolldown's vendored Plugin type plugins: [ - // @ts-expect-error rollup's Plugin type incompatible w/ rolldown's vendored Plugin type - enumPlugin, + ...(localDev ? [] : [enumPlugin]), ...resolveReplace(), ...resolveNodePlugins(), ...plugins, @@ -336,7 +338,7 @@ export function createConfigsForPackage({ function createProductionConfig(/** @type {PackageFormat} */ format) { return createConfig(format, { - entryFileNames: `${name}.${format}.prod.js`, + file: `${name}.${format}.prod.js`, format: outputConfigs[format].format, }) } @@ -345,10 +347,7 @@ export function createConfigsForPackage({ return createConfig( format, { - entryFileNames: String(outputConfigs[format].entryFileNames).replace( - /\.js$/, - '.prod.js', - ), + file: String(outputConfigs[format].file).replace(/\.js$/, '.prod.js'), format: outputConfigs[format].format, // minify: true, }, diff --git a/scripts/dev.js b/scripts/dev.js index fb4d3873e8..afdba8981d 100644 --- a/scripts/dev.js +++ b/scripts/dev.js @@ -1,19 +1,8 @@ // @ts-check -// Using esbuild for faster dev builds. -// We are still using Rollup for production builds because it generates -// smaller files and provides better tree-shaking. - -import esbuild from 'esbuild' -import fs from 'node:fs' -import { dirname, relative, resolve } from 'node:path' -import { fileURLToPath } from 'node:url' -import { createRequire } from 'node:module' +import { watch } from 'rolldown' +import { createConfigsForPackage } from './create-rolldown-config.js' import { parseArgs } from 'node:util' -import { polyfillNode } from 'esbuild-plugin-polyfill-node' - -const require = createRequire(import.meta.url) -const __dirname = dirname(fileURLToPath(import.meta.url)) const { values: { format: rawFormat, prod, inline: inlineDeps }, @@ -40,123 +29,26 @@ const { }) const format = rawFormat || 'global' -const targets = positionals.length ? positionals : ['vue'] - -// resolve output -const outputFormat = format.startsWith('global') - ? 'iife' - : format === 'cjs' - ? 'cjs' - : 'esm' - -const postfix = format.endsWith('-runtime') - ? `runtime.${format.replace(/-runtime$/, '')}` - : format - -const privatePackages = fs.readdirSync('packages-private') - -for (const target of targets) { - const pkgBase = privatePackages.includes(target) - ? `packages-private` - : `packages` - const pkgBasePath = `../${pkgBase}/${target}` - const pkg = require(`${pkgBasePath}/package.json`) - const outfile = resolve( - __dirname, - `${pkgBasePath}/dist/${ - target === 'vue-compat' ? `vue` : target - }.${postfix}.${prod ? `prod.` : ``}js`, - ) - const relativeOutfile = relative(process.cwd(), outfile) +const target = positionals.length ? positionals[0] : 'vue' + +const [config, prodConfig] = createConfigsForPackage({ + target, + commit: 'dev', + // @ts-expect-error + formats: [format], + devOnly: !prod, + sourceMap: true, + localDev: true, + inlineDeps, +}) - // resolve externals - // TODO this logic is largely duplicated from rollup.config.js - /** @type {string[]} */ - let external = [] - if (!inlineDeps) { - // cjs & esm-bundler: external all deps - if (format === 'cjs' || format.includes('esm-bundler')) { - external = [ - ...external, - ...Object.keys(pkg.dependencies || {}), - ...Object.keys(pkg.peerDependencies || {}), - // for @vue/compiler-sfc / server-renderer - 'path', - 'url', - 'stream', - ] - } +const configToUse = prod ? prodConfig : config - if (target === 'compiler-sfc') { - const consolidatePkgPath = require.resolve( - '@vue/consolidate/package.json', - { - paths: [resolve(__dirname, `../packages/${target}/`)], - }, - ) - const consolidateDeps = Object.keys( - require(consolidatePkgPath).devDependencies, - ) - external = [ - ...external, - ...consolidateDeps, - 'fs', - 'vm', - 'crypto', - 'react-dom/server', - 'teacup/lib/express', - 'arc-templates/dist/es5', - 'then-pug', - 'then-jade', - ] +watch(configToUse).then(watcher => { + console.log(`watching: ${configToUse.output.file}`) + watcher.on('event', event => { + if (event.code === 'BUNDLE_END') { + console.log(`rebuilt ${config.output.file} in ${event.duration}ms`) } - } - /** @type {Array} */ - const plugins = [ - { - name: 'log-rebuild', - setup(build) { - build.onEnd(() => { - console.log(`built: ${relativeOutfile}`) - }) - }, - }, - ] - - if (format !== 'cjs' && pkg.buildOptions?.enableNonBrowserBranches) { - plugins.push(polyfillNode()) - } - - esbuild - .context({ - entryPoints: [resolve(__dirname, `${pkgBasePath}/src/index.ts`)], - outfile, - bundle: true, - external, - sourcemap: true, - format: outputFormat, - globalName: pkg.buildOptions?.name, - platform: format === 'cjs' ? 'node' : 'browser', - plugins, - define: { - __COMMIT__: `"dev"`, - __VERSION__: `"${pkg.version}"`, - __DEV__: prod ? `false` : `true`, - __TEST__: `false`, - __BROWSER__: String( - format !== 'cjs' && !pkg.buildOptions?.enableNonBrowserBranches, - ), - __GLOBAL__: String(format === 'global'), - __ESM_BUNDLER__: String(format.includes('esm-bundler')), - __ESM_BROWSER__: String(format.includes('esm-browser')), - __CJS__: String(format === 'cjs'), - __SSR__: String(format !== 'global'), - __COMPAT__: String(target === 'vue-compat'), - __FEATURE_SUSPENSE__: `true`, - __FEATURE_OPTIONS_API__: `true`, - __FEATURE_PROD_DEVTOOLS__: `false`, - __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__: `true`, - }, - }) - .then(ctx => ctx.watch()) -} + }) +}) diff --git a/scripts/inline-enums.js b/scripts/inline-enums.js index 55583c10b4..88b2dca8c6 100644 --- a/scripts/inline-enums.js +++ b/scripts/inline-enums.js @@ -233,7 +233,7 @@ export function inlineEnums() { // 3. during transform: // 3.1 files w/ enum declaration: rewrite declaration as object literal - // 3.2 files using enum: inject into esbuild define + // 3.2 files using enum: inject into rolldown define /** * @type {import('rollup').Plugin} */ diff --git a/scripts/verify-treeshaking.js b/scripts/verify-treeshaking.js index 7cb76cdac8..783a4e9fc9 100644 --- a/scripts/verify-treeshaking.js +++ b/scripts/verify-treeshaking.js @@ -12,7 +12,7 @@ exec('pnpm', ['build', 'vue', '-f', 'global-runtime']).then(() => { if (devBuild.includes('__spreadValues')) { errors.push( - 'dev build contains unexpected esbuild object spread helper.\n' + + 'dev build contains unexpected object spread helper.\n' + 'This means { ...obj } syntax is used in runtime code. This should be ' + 'refactored to use the `extend` helper to avoid the extra code.', )