vue3-core/scripts/build.js

155 lines
4.1 KiB
JavaScript
Raw Normal View History

// @ts-check
2018-09-20 00:21:00 +08:00
/*
Produces production builds and stitches together d.ts files.
2018-09-20 00:21:00 +08:00
To specify the package to build, simply pass its name and the desired build
2018-09-20 00:21:00 +08:00
formats to output (defaults to `buildOptions.formats` specified in that package,
or "esm,cjs"):
```
# name supports fuzzy match. will build all packages with name containing "dom":
2021-10-09 02:23:30 +08:00
nr build dom
2018-09-20 00:21:00 +08:00
# specify the format to output
2021-10-09 02:23:30 +08:00
nr build core --formats cjs
2018-09-20 00:21:00 +08:00
```
*/
2023-01-26 14:24:49 +08:00
import fs from 'node:fs/promises'
import { existsSync, readFileSync, rmSync } from 'node:fs'
2023-01-26 14:24:49 +08:00
import path from 'node:path'
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'
2023-02-03 18:12:56 +08:00
import { targets as allTargets, fuzzyMatchTarget } from './utils.js'
import { scanEnums } from './const-enum.js'
2023-01-26 14:24:49 +08:00
const require = createRequire(import.meta.url)
const args = minimist(process.argv.slice(2))
const targets = args._
2018-09-20 00:21:00 +08:00
const formats = args.formats || args.f
const devOnly = args.devOnly || args.d
const prodOnly = !devOnly && (args.prodOnly || args.p)
const sourceMap = args.sourcemap || args.s
2019-12-11 11:14:02 +08:00
const isRelease = args.release
2018-10-23 23:58:37 +08:00
const buildAllMatching = args.all || args.a
const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7)
run()
async function run() {
const removeCache = scanEnums()
try {
if (!targets.length) {
await buildAll(allTargets)
checkAllSizes(allTargets)
} else {
await buildAll(fuzzyMatchTarget(targets, buildAllMatching))
checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching))
}
} finally {
removeCache()
2018-09-19 23:35:38 +08:00
}
}
2018-09-19 23:35:38 +08:00
2018-09-20 00:21:00 +08:00
async function buildAll(targets) {
2023-01-26 14:24:49 +08:00
await runParallel(cpus().length, targets, build)
}
async function runParallel(maxConcurrency, source, iteratorFn) {
const ret = []
const executing = []
for (const item of source) {
const p = Promise.resolve().then(() => iteratorFn(item, source))
ret.push(p)
if (maxConcurrency <= source.length) {
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
executing.push(e)
if (executing.length >= maxConcurrency) {
await Promise.race(executing)
}
}
2018-09-19 23:35:38 +08:00
}
return Promise.all(ret)
2018-09-19 23:35:38 +08:00
}
2018-09-20 00:21:00 +08:00
async function build(target) {
2018-09-19 23:35:38 +08:00
const pkgDir = path.resolve(`packages/${target}`)
2018-10-17 05:41:59 +08:00
const pkg = require(`${pkgDir}/package.json`)
2018-09-19 23:35:38 +08:00
// if this is a full build (no specific targets), ignore private packages
if ((isRelease || !targets.length) && pkg.private) {
2019-12-11 11:14:02 +08:00
return
}
// if building a specific format, do not remove dist.
2023-01-26 16:11:24 +08:00
if (!formats && existsSync(`${pkgDir}/dist`)) {
2023-01-26 14:24:49 +08:00
await fs.rm(`${pkgDir}/dist`, { recursive: true })
}
2018-09-19 23:35:38 +08:00
2019-10-05 01:08:06 +08:00
const env =
(pkg.buildOptions && pkg.buildOptions.env) ||
(devOnly ? 'development' : 'production')
2018-09-20 00:21:00 +08:00
await execa(
'rollup',
[
'-c',
'--environment',
[
`COMMIT:${commit}`,
`NODE_ENV:${env}`,
`TARGET:${target}`,
formats ? `FORMATS:${formats}` : ``,
prodOnly ? `PROD_ONLY:true` : ``,
sourceMap ? `SOURCE_MAP:true` : ``
]
.filter(Boolean)
.join(',')
2018-09-20 00:21:00 +08:00
],
{ stdio: 'inherit' }
)
2018-09-19 23:35:38 +08:00
}
2018-09-20 00:21:00 +08:00
function checkAllSizes(targets) {
2021-09-24 02:46:16 +08:00
if (devOnly || (formats && !formats.includes('global'))) {
2019-12-03 07:18:02 +08:00
return
}
2018-09-19 23:35:38 +08:00
console.log()
for (const target of targets) {
checkSize(target)
}
console.log()
}
2018-09-20 00:21:00 +08:00
function checkSize(target) {
2018-09-19 23:35:38 +08:00
const pkgDir = path.resolve(`packages/${target}`)
checkFileSize(`${pkgDir}/dist/${target}.global.prod.js`)
2021-09-24 02:46:16 +08:00
if (!formats || formats.includes('global-runtime')) {
checkFileSize(`${pkgDir}/dist/${target}.runtime.global.prod.js`)
}
}
function checkFileSize(filePath) {
2023-01-26 14:24:49 +08:00
if (!existsSync(filePath)) {
return
2018-09-19 23:35:38 +08:00
}
2023-01-26 14:24:49 +08:00
const file = readFileSync(filePath)
const minSize = (file.length / 1024).toFixed(2) + 'kb'
const gzipped = gzipSync(file)
const gzippedSize = (gzipped.length / 1024).toFixed(2) + 'kb'
const compressed = compress(file)
2023-02-03 18:12:56 +08:00
// @ts-ignore
const compressedSize = (compressed.length / 1024).toFixed(2) + 'kb'
console.log(
`${chalk.gray(
chalk.bold(path.basename(filePath))
)} min:${minSize} / gzip:${gzippedSize} / brotli:${compressedSize}`
)
2018-09-19 23:35:38 +08:00
}