usage-size.ts 2.5 KB

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