usage-size.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { mkdir, writeFile } from 'fs/promises'
  2. import path from 'node:path'
  3. import { rollup } from 'rollup'
  4. import nodeResolve from '@rollup/plugin-node-resolve'
  5. import { minify } from 'terser'
  6. import replace from '@rollup/plugin-replace'
  7. import { brotliCompressSync, gzipSync } from 'node:zlib'
  8. const sizeDir = path.resolve('temp/size')
  9. const entry = path.resolve('./packages/vue/dist/vue.runtime.esm-bundler.js')
  10. interface Preset {
  11. name: string
  12. imports: string[]
  13. }
  14. const presets: Preset[] = [
  15. { name: 'createApp', imports: ['createApp'] },
  16. { name: 'createSSRApp', imports: ['createSSRApp'] },
  17. { name: 'defineCustomElement', imports: ['defineCustomElement'] },
  18. {
  19. name: 'overall',
  20. imports: [
  21. 'createApp',
  22. 'ref',
  23. 'watch',
  24. 'Transition',
  25. 'KeepAlive',
  26. 'Suspense'
  27. ]
  28. }
  29. ]
  30. main()
  31. async function main() {
  32. const tasks: ReturnType<typeof generateBundle>[] = []
  33. for (const preset of presets) {
  34. tasks.push(generateBundle(preset))
  35. }
  36. const results = Object.fromEntries(
  37. (await Promise.all(tasks)).map(r => [r.name, r])
  38. )
  39. await mkdir(sizeDir, { recursive: true })
  40. await writeFile(
  41. path.resolve(sizeDir, '_usages.json'),
  42. JSON.stringify(results),
  43. 'utf-8'
  44. )
  45. }
  46. async function generateBundle(preset: Preset) {
  47. const id = 'virtual:entry'
  48. const content = `export { ${preset.imports.join(', ')} } from '${entry}'`
  49. const result = await rollup({
  50. input: id,
  51. plugins: [
  52. {
  53. name: 'usage-size-plugin',
  54. resolveId(_id) {
  55. if (_id === id) return id
  56. return null
  57. },
  58. load(_id) {
  59. if (_id === id) return content
  60. }
  61. },
  62. nodeResolve(),
  63. replace({
  64. 'process.env.NODE_ENV': '"production"',
  65. __VUE_PROD_DEVTOOLS__: 'false',
  66. __VUE_OPTIONS_API__: 'true',
  67. preventAssignment: true
  68. })
  69. ]
  70. })
  71. const generated = await result.generate({})
  72. const bundled = generated.output[0].code
  73. const minified = (
  74. await minify(bundled, {
  75. module: true,
  76. toplevel: true
  77. })
  78. ).code!
  79. const size = minified.length
  80. const gzip = gzipSync(minified).length
  81. const brotli = brotliCompressSync(minified).length
  82. return {
  83. name: preset.name,
  84. size,
  85. gzip,
  86. brotli
  87. }
  88. }