| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // @ts-check
- import { mkdir, writeFile } from 'node:fs/promises'
- import path from 'node:path'
- import { rolldown } from 'rolldown'
- import { minify } from 'oxc-minify'
- import { replacePlugin } from 'rolldown/plugins'
- import { brotliCompressSync, gzipSync } from 'node:zlib'
- import { parseArgs } from 'node:util'
- import pico from 'picocolors'
- import prettyBytes from 'pretty-bytes'
- const {
- values: { write },
- } = parseArgs({
- options: {
- write: {
- type: 'boolean',
- default: false,
- },
- },
- })
- const sizeDir = path.resolve('temp/size')
- const vuePath = 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]
- */
- /** @type {Preset[]} */
- const presets = [
- {
- name: 'createApp (CAPI only)',
- imports: ['createApp'],
- replace: { __VUE_OPTIONS_API__: 'false' },
- },
- { name: 'createApp', imports: ['createApp'] },
- {
- name: 'createApp + vaporInteropPlugin',
- imports: ['createApp', 'vaporInteropPlugin'],
- },
- { name: 'createVaporApp', imports: ['createVaporApp'] },
- { name: 'createSSRApp', imports: ['createSSRApp'] },
- { name: 'createVaporSSRApp', imports: ['createVaporSSRApp'] },
- { name: 'defineCustomElement', imports: ['defineCustomElement'] },
- { name: 'defineVaporCustomElement', imports: ['defineVaporCustomElement'] },
- {
- name: 'overall',
- imports: [
- 'createApp',
- 'ref',
- 'watch',
- 'Transition',
- 'KeepAlive',
- 'Suspense',
- ],
- },
- ]
- main()
- /**
- * Main function that initiates the bundling process for the presets
- */
- async function main() {
- console.log()
- /** @type {Promise<{name: string, size: number, gzip: number, brotli: number}>[]} */
- const tasks = []
- for (const preset of presets) {
- tasks.push(generateBundle(preset))
- }
- const results = await Promise.all(tasks)
- 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 })}`,
- )
- }
- await mkdir(sizeDir, { recursive: true })
- await writeFile(
- path.resolve(sizeDir, '_usages.json'),
- JSON.stringify(Object.fromEntries(results.map(r => [r.name, r])), null, 2),
- '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) {
- const id = 'virtual:entry'
- const exportSpecifiers =
- preset.imports === '*'
- ? `* as ${preset.name}`
- : `{ ${preset.imports.join(', ')} }`
- const content = `export ${exportSpecifiers} from '${vuePath}'`
- const result = await rolldown({
- input: id,
- plugins: [
- {
- name: 'usage-size-plugin',
- resolveId(_id) {
- if (_id === id) return id
- return null
- },
- load(_id) {
- if (_id === id) return content
- },
- },
- replacePlugin(
- {
- 'process.env.NODE_ENV': '"production"',
- __VUE_PROD_DEVTOOLS__: 'false',
- __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
- __VUE_OPTIONS_API__: 'true',
- ...preset.replace,
- },
- { preventAssignment: true },
- ),
- ],
- tsconfig: false,
- treeshake: {
- moduleSideEffects: false,
- },
- })
- const generated = await result.generate({
- minify: 'dce-only',
- })
- const bundled = generated.output[0].code
- const file = preset.name + '.js'
- const minified = (
- await minify(file, bundled, {
- module: true,
- mangle: {
- toplevel: true,
- },
- })
- ).code
- const size = minified.length
- const gzip = gzipSync(minified).length
- const brotli = brotliCompressSync(minified).length
- if (write) {
- await writeFile(path.resolve(sizeDir, file), bundled)
- }
- return {
- name: preset.name,
- size,
- gzip,
- brotli,
- }
- }
|