build: update build scripts to esm

This commit is contained in:
Evan You 2023-01-26 14:24:49 +08:00
parent ec4531a6b3
commit ab45f6f8a2
13 changed files with 225 additions and 198 deletions

View File

@ -3,36 +3,36 @@
"version": "3.2.45",
"packageManager": "pnpm@7.1.0",
"scripts": {
"dev": "node scripts/dev.js",
"build": "node scripts/build.js",
"dev": "node scripts/dev.mjs",
"build": "node scripts/build.mjs",
"size": "run-s size-global size-baseline",
"size-global": "node scripts/build.js vue runtime-dom -f global -p",
"size-baseline": "node scripts/build.js runtime-dom runtime-core reactivity shared -f esm-bundler && cd packages/size-check && vite build && node brotli",
"size-global": "node scripts/build.mjs vue runtime-dom -f global -p",
"size-baseline": "node scripts/build.mjs runtime-dom runtime-core reactivity shared -f esm-bundler && cd packages/size-check && vite build && node brotli",
"lint": "eslint --cache --ext .ts packages/*/{src,__tests__}/**.ts",
"format": "prettier --write --cache --parser typescript \"**/*.[tj]s?(x)\"",
"format-check": "prettier --check --cache --parser typescript \"**/*.[tj]s?(x)\"",
"test": "run-s \"test-unit {@}\" \"test-e2e {@}\"",
"test-unit": "jest --filter ./scripts/filter-unit.js",
"test-e2e": "node scripts/build.js vue -f global -d && jest --filter ./scripts/filter-e2e.js --runInBand",
"test-dts": "node scripts/build.js shared reactivity runtime-core runtime-dom -dt -f esm-bundler && npm run test-dts-only",
"test-dts-only": "tsc -p ./test-dts/tsconfig.json && tsc -p ./test-dts/tsconfig.build.json",
"test-coverage": "node scripts/build.js vue -f global -d && jest --runInBand --coverage --bail",
"release": "node scripts/release.js",
"test-unit": "jest --filter ./scripts/filter-unit.mjs",
"test-e2e": "node scripts/build.mjs vue -f global -d && jest --filter ./scripts/filter-e2e.js --runInBand",
"test-dts": "node scripts/build.mjs shared reactivity runtime-core runtime-dom -dt -f esm-bundler && npm run test-dts-only",
"test-dts-only": "tsc -p ./test-dts/tsconfig.json && tsc -p ./test-dts/tsconfig.build.mjson",
"test-coverage": "node scripts/build.mjs vue -f global -d && jest --runInBand --coverage --bail",
"release": "node scripts/release.mjs",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"dev-esm": "node scripts/dev.js -if esm-bundler-runtime",
"dev-esm": "node scripts/dev.mjs -if esm-bundler-runtime",
"dev-compiler": "run-p \"dev template-explorer\" serve",
"dev-sfc": "run-s dev-sfc-prepare dev-sfc-run",
"dev-sfc-prepare": "node scripts/pre-dev-sfc.js || npm run build-compiler-cjs",
"dev-sfc-prepare": "node scripts/pre-dev-sfc.mjs || npm run build-compiler-cjs",
"dev-sfc-serve": "vite packages/sfc-playground --host",
"dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if esm-bundler-runtime\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve",
"serve": "serve",
"open": "open http://localhost:5000/packages/template-explorer/local.html",
"build-sfc-playground": "run-s build-compiler-cjs build-runtime-esm build-ssr-esm build-sfc-playground-self",
"build-compiler-cjs": "node scripts/build.js compiler reactivity-transform shared -af cjs",
"build-runtime-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler-runtime && node scripts/build.js vue -f esm-browser-runtime",
"build-ssr-esm": "node scripts/build.js compiler-sfc server-renderer -f esm-browser",
"build-compiler-cjs": "node scripts/build.mjs compiler reactivity-transform shared -af cjs",
"build-runtime-esm": "node scripts/build.mjs runtime reactivity shared -af esm-bundler && node scripts/build.mjs vue -f esm-bundler-runtime && node scripts/build.mjs vue -f esm-browser-runtime",
"build-ssr-esm": "node scripts/build.mjs compiler-sfc server-renderer -f esm-browser",
"build-sfc-playground-self": "cd packages/sfc-playground && npm run build",
"preinstall": "node ./scripts/preinstall.js",
"preinstall": "node ./scripts/preinstall.mjs",
"postinstall": "simple-git-hooks"
},
"types": "test-dts/index.d.ts",
@ -78,7 +78,6 @@
"eslint": "^7.7.0",
"eslint-plugin-jest": "26.1.5",
"execa": "^4.0.2",
"fs-extra": "^9.0.1",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"lint-staged": "^10.2.10",

View File

@ -0,0 +1,7 @@
{
"extends": "../../api-extractor.json",
"mainEntryPointFilePath": "./dist/packages/<unscopedPackageName>/src/index.d.ts",
"dtsRollup": {
"publicTrimmedFilePath": "./dist/<unscopedPackageName>.d.ts"
}
}

View File

@ -29,7 +29,6 @@ importers:
eslint: ^7.7.0
eslint-plugin-jest: 26.1.5
execa: ^4.0.2
fs-extra: ^9.0.1
jest: ^29.3.1
jest-environment-jsdom: ^29.3.1
lint-staged: ^10.2.10
@ -81,7 +80,6 @@ importers:
eslint: 7.32.0
eslint-plugin-jest: 26.1.5_h6y6ce27mgasm6fmt6a3uqj6ne
execa: 4.1.0
fs-extra: 9.1.0
jest: 29.3.1_@types+node@16.11.12
jest-environment-jsdom: 29.3.1
lint-staged: 10.5.4
@ -2128,11 +2126,6 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: true
/at-least-node/1.0.0:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
engines: {node: '>= 4.0.0'}
dev: true
/babel-jest/29.3.1_@babel+core@7.16.0:
resolution: {integrity: sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@ -3730,16 +3723,6 @@ packages:
universalify: 0.1.2
dev: true
/fs-extra/9.1.0:
resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
engines: {node: '>=10'}
dependencies:
at-least-node: 1.0.0
graceful-fs: 4.2.8
jsonfile: 6.1.0
universalify: 2.0.0
dev: true
/fs.realpath/1.0.0:
resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
dev: true
@ -3934,10 +3917,6 @@ packages:
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
dev: true
/graceful-fs/4.2.8:
resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==}
dev: true
/handlebars/4.7.7:
resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==}
engines: {node: '>=0.4.7'}

View File

@ -1,11 +1,19 @@
// create package.json, README, etc. for packages that don't have them yet
// @ts-check
import minimist from 'minimist'
import fs from 'node:fs'
import path from 'node:path'
import { createRequire } from 'node:module'
import { fileURLToPath } from 'url'
const args = require('minimist')(process.argv.slice(2))
const fs = require('fs')
const path = require('path')
const args = minimist(process.argv.slice(2))
const require = createRequire(import.meta.url)
const version = require('../package.json').version
const packagesDir = path.resolve(__dirname, '../packages')
const packagesDir = path.resolve(
fileURLToPath(import.meta.url),
'../../packages'
)
const files = fs.readdirSync(packagesDir)
files.forEach(shortName => {

View File

@ -14,15 +14,23 @@ nr build core --formats cjs
```
*/
const fs = require('fs-extra')
const path = require('path')
const chalk = require('chalk')
const execa = require('execa')
const { gzipSync } = require('zlib')
const { compress } = require('brotli')
const { targets: allTargets, fuzzyMatchTarget } = require('./utils')
// @ts-check
import fs from 'node:fs/promises'
import { existsSync, readFileSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import minimist from 'minimist'
import { gzipSync } from 'node:zlib'
import { compress } from 'brotli'
import chalk from 'chalk'
import execa from 'execa'
import { cpus } from 'node:os'
import { createRequire } from 'node:module'
import { targets as allTargets, fuzzyMatchTarget } from './utils.mjs'
const args = require('minimist')(process.argv.slice(2))
const require = createRequire(import.meta.url)
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const args = minimist(process.argv.slice(2))
const targets = args._
const formats = args.formats || args.f
const devOnly = args.devOnly || args.d
@ -38,7 +46,9 @@ run()
async function run() {
if (isRelease) {
// remove build cache for release builds to avoid outdated enum values
await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache'))
await fs.rm(path.resolve(__dirname, '../node_modules/.rts2_cache'), {
recursive: true
})
}
if (!targets.length) {
await buildAll(allTargets)
@ -50,7 +60,7 @@ async function run() {
}
async function buildAll(targets) {
await runParallel(require('os').cpus().length, targets, build)
await runParallel(cpus().length, targets, build)
}
async function runParallel(maxConcurrency, source, iteratorFn) {
@ -82,7 +92,7 @@ async function build(target) {
// if building a specific format, do not remove dist.
if (!formats) {
await fs.remove(`${pkgDir}/dist`)
await fs.rm(`${pkgDir}/dist`, { recursive: true })
}
const env =
@ -128,7 +138,7 @@ async function build(target) {
if (extractorResult.succeeded) {
// concat additional d.ts to rolled-up dts
const typesDir = path.resolve(pkgDir, 'types')
if (await fs.exists(typesDir)) {
if (existsSync(typesDir)) {
const dtsPath = path.resolve(pkgDir, pkg.types)
const existing = await fs.readFile(dtsPath, 'utf-8')
const typeFiles = await fs.readdir(typesDir)
@ -150,7 +160,7 @@ async function build(target) {
process.exitCode = 1
}
await fs.remove(`${pkgDir}/dist/packages`)
await fs.rm(`${pkgDir}/dist/packages`, { recursive: true })
}
}
@ -174,10 +184,10 @@ function checkSize(target) {
}
function checkFileSize(filePath) {
if (!fs.existsSync(filePath)) {
if (!existsSync(filePath)) {
return
}
const file = fs.readFileSync(filePath)
const file = readFileSync(filePath)
const minSize = (file.length / 1024).toFixed(2) + 'kb'
const gzipped = gzipSync(file)
const gzippedSize = (gzipped.length / 1024).toFixed(2) + 'kb'

View File

@ -1,114 +0,0 @@
// Using esbuild for faster dev builds.
// We are still using Rollup for production builds because it generates
// smaller files w/ better tree-shaking.
// @ts-check
const { context } = require('esbuild')
const nodePolyfills = require('@esbuild-plugins/node-modules-polyfill')
const { resolve, relative } = require('path')
const args = require('minimist')(process.argv.slice(2))
const target = args._[0] || 'vue'
const format = args.f || 'global'
const inlineDeps = args.i || args.inline
const pkg = require(resolve(__dirname, `../packages/${target}/package.json`))
// resolve output
const outputFormat = format.startsWith('global')
? 'iife'
: format === 'cjs'
? 'cjs'
: 'esm'
const postfix = format.endsWith('-runtime')
? `runtime.${format.replace(/-runtime$/, '')}`
: format
const outfile = resolve(
__dirname,
`../packages/${target}/dist/${
target === 'vue-compat' ? `vue` : target
}.${postfix}.js`
)
const relativeOutfile = relative(process.cwd(), outfile)
// resolve externals
// TODO this logic is largely duplicated from rollup.config.js
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'
]
}
if (target === 'compiler-sfc') {
const consolidateDeps = require.resolve('@vue/consolidate/package.json', {
paths: [resolve(__dirname, `../packages/${target}/`)]
})
external = [
...external,
...Object.keys(require(consolidateDeps).devDependencies),
'fs',
'vm',
'crypto',
'react-dom/server',
'teacup/lib/express',
'arc-templates/dist/es5',
'then-pug',
'then-jade'
]
}
}
const plugins = [
{
name: 'log-rebuild',
setup(build) {
build.onEnd(() => {
console.log(`built: ${relativeOutfile}`)
})
}
}
]
if (format === 'cjs' || pkg.buildOptions?.enableNonBrowserBranches) {
plugins.push(nodePolyfills.default())
}
context({
entryPoints: [resolve(__dirname, `../packages/${target}/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__: `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')),
__NODE_JS__: String(format === 'cjs'),
__SSR__: String(format === 'cjs' || format.includes('esm-bundler')),
__COMPAT__: String(target === 'vue-compat'),
__FEATURE_SUSPENSE__: `true`,
__FEATURE_OPTIONS_API__: `true`,
__FEATURE_PROD_DEVTOOLS__: `false`
}
}).then(ctx => ctx.watch())

128
scripts/dev.mjs Normal file
View File

@ -0,0 +1,128 @@
// Using esbuild for faster dev builds.
// We are still using Rollup for production builds because it generates
// smaller files w/ better tree-shaking.
// @ts-check
import esbuild from 'esbuild'
import { resolve, relative, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import { createRequire } from 'node:module'
import minimist from 'minimist'
import { NodeModulesPolyfillPlugin as nodePolyfills } from '@esbuild-plugins/node-modules-polyfill'
const require = createRequire(import.meta.url)
const __dirname = dirname(fileURLToPath(import.meta.url))
const args = minimist(process.argv.slice(2))
const target = args._[0] || 'vue'
const format = args.f || 'global'
const inlineDeps = args.i || args.inline
const pkg = require(`../packages/${target}/package.json`)
// resolve output
const outputFormat = format.startsWith('global')
? 'iife'
: format === 'cjs'
? 'cjs'
: 'esm'
const postfix = format.endsWith('-runtime')
? `runtime.${format.replace(/-runtime$/, '')}`
: format
const outfile = resolve(
__dirname,
`../packages/${target}/dist/${
target === 'vue-compat' ? `vue` : target
}.${postfix}.js`
)
const relativeOutfile = relative(process.cwd(), outfile)
// resolve externals
// TODO this logic is largely duplicated from rollup.config.js
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'
]
}
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'
]
}
}
const plugins = [
{
name: 'log-rebuild',
setup(build) {
build.onEnd(() => {
console.log(`built: ${relativeOutfile}`)
})
}
}
]
if (format === 'cjs' || pkg.buildOptions?.enableNonBrowserBranches) {
console.log(nodePolyfills)
plugins.push(nodePolyfills())
}
esbuild
.context({
entryPoints: [resolve(__dirname, `../packages/${target}/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__: `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')),
__NODE_JS__: String(format === 'cjs'),
__SSR__: String(format === 'cjs' || format.includes('esm-bundler')),
__COMPAT__: String(target === 'vue-compat'),
__FEATURE_SUSPENSE__: `true`,
__FEATURE_OPTIONS_API__: `true`,
__FEATURE_PROD_DEVTOOLS__: `false`
}
})
.then(ctx => ctx.watch())

View File

@ -1,3 +1,4 @@
// jest only supports cjs filter files
const path = require('path')
const e2eTests = [

View File

@ -1,3 +1,4 @@
// jest only supports cjs filter files
const { e2eTests } = require('./filter-e2e')
module.exports = list => {

View File

@ -1,5 +1,4 @@
const fs = require('fs')
const path = require('path')
import fs from 'node:fs'
const packagesToCheck = [
'compiler-sfc',
@ -15,7 +14,7 @@ let allFilesPresent = true
for (const pkg of packagesToCheck) {
if (
!fs.existsSync(
path.resolve(__dirname, `../packages/${pkg}/dist/${pkg}.cjs.js`)
new URL(`../packages/${pkg}/dist/${pkg}.cjs.js`, import.meta.url)
)
) {
allFilesPresent = false

View File

@ -1,15 +1,19 @@
const args = require('minimist')(process.argv.slice(2))
const fs = require('fs')
const path = require('path')
const chalk = require('chalk')
const semver = require('semver')
const currentVersion = require('../package.json').version
const { prompt } = require('enquirer')
const execa = require('execa')
// @ts-check
import minimist from 'minimist'
import fs from 'node:fs'
import path from 'node:path'
import chalk from 'chalk'
import semver from 'semver'
import enquirer from 'enquirer'
import execa from 'execa'
import { createRequire } from 'node:module'
import { fileURLToPath } from 'node:url'
const preId =
args.preid ||
(semver.prerelease(currentVersion) && semver.prerelease(currentVersion)[0])
const { prompt } = enquirer
const currentVersion = createRequire(import.meta.url)('../package.json').version
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const args = minimist(process.argv.slice(2))
const preId = args.preid || semver.prerelease(currentVersion)?.[0]
const isDryRun = args.dry
const skipTests = args.skipTests
const skipBuild = args.skipBuild
@ -41,6 +45,7 @@ async function main() {
if (!targetVersion) {
// no explicit version, offer suggestions
// @ts-ignore
const { release } = await prompt({
type: 'select',
name: 'release',
@ -49,14 +54,14 @@ async function main() {
})
if (release === 'custom') {
targetVersion = (
await prompt({
type: 'input',
name: 'version',
message: 'Input custom version',
initial: currentVersion
})
).version
const result = await prompt({
type: 'input',
name: 'version',
message: 'Input custom version',
initial: currentVersion
})
// @ts-ignore
targetVersion = result.version
} else {
targetVersion = release.match(/\((.*)\)/)[1]
}
@ -66,6 +71,7 @@ async function main() {
throw new Error(`invalid target version: ${targetVersion}`)
}
// @ts-ignore
const { yes } = await prompt({
type: 'confirm',
name: 'yes',

View File

@ -1,7 +1,10 @@
const fs = require('fs')
const chalk = require('chalk')
import fs from 'node:fs'
import chalk from 'chalk'
import { createRequire } from 'node:module'
const targets = (exports.targets = fs.readdirSync('packages').filter(f => {
const require = createRequire(import.meta.url)
export const targets = fs.readdirSync('packages').filter(f => {
if (!fs.statSync(`packages/${f}`).isDirectory()) {
return false
}
@ -10,9 +13,9 @@ const targets = (exports.targets = fs.readdirSync('packages').filter(f => {
return false
}
return true
}))
})
exports.fuzzyMatchTarget = (partialTargets, includeAllMatching) => {
export function fuzzyMatchTarget(partialTargets, includeAllMatching) {
const matched = []
partialTargets.forEach(partialTarget => {
for (const target of targets) {