core/scripts/usage-size.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

147 lines
3.6 KiB
JavaScript
Raw Normal View History

// @ts-check
2023-08-21 03:33:51 +00:00
import { mkdir, writeFile } from 'node:fs/promises'
import path from 'node:path'
import { rollup } from 'rollup'
import nodeResolve from '@rollup/plugin-node-resolve'
2024-07-15 08:28:47 +00:00
import { minify } from '@swc/core'
2023-08-21 03:33:51 +00:00
import replace from '@rollup/plugin-replace'
import { brotliCompressSync, gzipSync } from 'node:zlib'
2024-08-11 13:48:08 +00:00
import { parseArgs } from 'node:util'
import pico from 'picocolors'
import prettyBytes from 'pretty-bytes'
const {
values: { write },
} = parseArgs({
options: {
write: {
type: 'boolean',
default: false,
},
},
})
2023-08-21 03:33:51 +00:00
const sizeDir = path.resolve('temp/size')
const entry = path.resolve('./packages/vue/dist/vue.runtime.esm-bundler.js')
/**
* @typedef {Object} Preset
* @property {string} name - The name of the preset
* @property {string[]} imports - The imports that are part of this preset
* @property {Record<string, string>} [replace]
*/
2023-08-21 03:33:51 +00:00
/** @type {Preset[]} */
const presets = [
{
name: 'createApp (CAPI only)',
imports: ['createApp'],
replace: { __VUE_OPTIONS_API__: 'false' },
},
2023-08-21 03:33:51 +00:00
{ name: 'createApp', imports: ['createApp'] },
{ name: 'createSSRApp', imports: ['createSSRApp'] },
{ name: 'defineCustomElement', imports: ['defineCustomElement'] },
{
name: 'overall',
imports: [
'createApp',
'ref',
'watch',
'Transition',
'KeepAlive',
'Suspense',
],
},
]
main()
/**
* Main function that initiates the bundling process for the presets
*/
2023-08-21 03:33:51 +00:00
async function main() {
2024-08-11 13:48:08 +00:00
console.log()
/** @type {Promise<{name: string, size: number, gzip: number, brotli: number}>[]} */
const tasks = []
2023-08-21 03:33:51 +00:00
for (const preset of presets) {
tasks.push(generateBundle(preset))
}
const results = await Promise.all(tasks)
2023-08-21 03:33:51 +00:00
for (const r of results) {
console.log(
`${pico.green(pico.bold(r.name))} - ` +
`min:${prettyBytes(r.size, { minimumFractionDigits: 3 })} / ` +
`gzip:${prettyBytes(r.gzip, { minimumFractionDigits: 3 })} / ` +
`brotli:${prettyBytes(r.brotli, { minimumFractionDigits: 3 })}`,
)
}
2023-08-21 03:33:51 +00:00
await mkdir(sizeDir, { recursive: true })
await writeFile(
path.resolve(sizeDir, '_usages.json'),
JSON.stringify(Object.fromEntries(results.map(r => [r.name, r])), null, 2),
2023-08-21 03:33:51 +00:00
'utf-8',
)
}
/**
* Generates a bundle for a given preset
*
* @param {Preset} preset - The preset to generate the bundle for
* @returns {Promise<{name: string, size: number, gzip: number, brotli: number}>} - The result of the bundling process
*/
async function generateBundle(preset) {
2023-08-21 03:33:51 +00:00
const id = 'virtual:entry'
const content = `export { ${preset.imports.join(', ')} } from '${entry}'`
2023-08-21 03:33:51 +00:00
const result = await rollup({
input: id,
plugins: [
{
name: 'usage-size-plugin',
resolveId(_id) {
if (_id === id) return id
return null
},
load(_id) {
if (_id === id) return content
},
},
nodeResolve(),
replace({
'process.env.NODE_ENV': '"production"',
__VUE_PROD_DEVTOOLS__: 'false',
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
2023-08-21 03:33:51 +00:00
__VUE_OPTIONS_API__: 'true',
preventAssignment: true,
...preset.replace,
2023-08-21 03:33:51 +00:00
}),
],
})
const generated = await result.generate({})
const bundled = generated.output[0].code
const minified = (
await minify(bundled, {
module: true,
toplevel: true,
})
).code
2023-08-21 03:33:51 +00:00
const size = minified.length
const gzip = gzipSync(minified).length
const brotli = brotliCompressSync(minified).length
2024-08-11 13:48:08 +00:00
if (write) {
await writeFile(path.resolve(sizeDir, preset.name + '.js'), bundled)
}
2023-08-21 03:33:51 +00:00
return {
name: preset.name,
size,
gzip,
brotli,
}
}