dev.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // @ts-check
  2. // Using esbuild for faster dev builds.
  3. // We are still using Rollup for production builds because it generates
  4. // smaller files and provides better tree-shaking.
  5. import esbuild from 'esbuild'
  6. import { dirname, relative, resolve } from 'node:path'
  7. import { fileURLToPath } from 'node:url'
  8. import { createRequire } from 'node:module'
  9. import { parseArgs } from 'node:util'
  10. import { polyfillNode } from 'esbuild-plugin-polyfill-node'
  11. const require = createRequire(import.meta.url)
  12. const __dirname = dirname(fileURLToPath(import.meta.url))
  13. const {
  14. values: { format: rawFormat, prod, inline: inlineDeps },
  15. positionals,
  16. } = parseArgs({
  17. allowPositionals: true,
  18. options: {
  19. format: {
  20. type: 'string',
  21. short: 'f',
  22. default: 'global',
  23. },
  24. prod: {
  25. type: 'boolean',
  26. short: 'p',
  27. default: false,
  28. },
  29. inline: {
  30. type: 'boolean',
  31. short: 'i',
  32. default: false,
  33. },
  34. },
  35. })
  36. const format = rawFormat || 'global'
  37. const targets = positionals.length ? positionals : ['vue']
  38. // resolve output
  39. const outputFormat = format.startsWith('global')
  40. ? 'iife'
  41. : format === 'cjs'
  42. ? 'cjs'
  43. : 'esm'
  44. const postfix = format.endsWith('-runtime')
  45. ? `runtime.${format.replace(/-runtime$/, '')}`
  46. : format
  47. for (const target of targets) {
  48. const pkg = require(`../packages/${target}/package.json`)
  49. const outfile = resolve(
  50. __dirname,
  51. `../packages/${target}/dist/${
  52. target === 'vue-compat' ? `vue` : target
  53. }.${postfix}.${prod ? `prod.` : ``}js`,
  54. )
  55. const relativeOutfile = relative(process.cwd(), outfile)
  56. // resolve externals
  57. // TODO this logic is largely duplicated from rollup.config.js
  58. /** @type {string[]} */
  59. let external = []
  60. if (!inlineDeps) {
  61. // cjs & esm-bundler: external all deps
  62. if (format === 'cjs' || format.includes('esm-bundler')) {
  63. external = [
  64. ...external,
  65. ...Object.keys(pkg.dependencies || {}),
  66. ...Object.keys(pkg.peerDependencies || {}),
  67. // for @vue/compiler-sfc / server-renderer
  68. 'path',
  69. 'url',
  70. 'stream',
  71. ]
  72. }
  73. if (target === 'compiler-sfc') {
  74. const consolidatePkgPath = require.resolve(
  75. '@vue/consolidate/package.json',
  76. {
  77. paths: [resolve(__dirname, `../packages/${target}/`)],
  78. },
  79. )
  80. const consolidateDeps = Object.keys(
  81. require(consolidatePkgPath).devDependencies,
  82. )
  83. external = [
  84. ...external,
  85. ...consolidateDeps,
  86. 'fs',
  87. 'vm',
  88. 'crypto',
  89. 'react-dom/server',
  90. 'teacup/lib/express',
  91. 'arc-templates/dist/es5',
  92. 'then-pug',
  93. 'then-jade',
  94. ]
  95. }
  96. }
  97. /** @type {Array<import('esbuild').Plugin>} */
  98. const plugins = [
  99. {
  100. name: 'log-rebuild',
  101. setup(build) {
  102. build.onEnd(() => {
  103. console.log(`built: ${relativeOutfile}`)
  104. })
  105. },
  106. },
  107. ]
  108. if (format !== 'cjs' && pkg.buildOptions?.enableNonBrowserBranches) {
  109. plugins.push(polyfillNode())
  110. }
  111. esbuild
  112. .context({
  113. entryPoints: [resolve(__dirname, `../packages/${target}/src/index.ts`)],
  114. outfile,
  115. bundle: true,
  116. external,
  117. sourcemap: true,
  118. format: outputFormat,
  119. globalName: pkg.buildOptions?.name,
  120. platform: format === 'cjs' ? 'node' : 'browser',
  121. plugins,
  122. define: {
  123. __COMMIT__: `"dev"`,
  124. __VERSION__: `"${pkg.version}"`,
  125. __DEV__: prod ? `false` : `true`,
  126. __TEST__: `false`,
  127. __BROWSER__: String(
  128. format !== 'cjs' && !pkg.buildOptions?.enableNonBrowserBranches,
  129. ),
  130. __GLOBAL__: String(format === 'global'),
  131. __ESM_BUNDLER__: String(format.includes('esm-bundler')),
  132. __ESM_BROWSER__: String(format.includes('esm-browser')),
  133. __CJS__: String(format === 'cjs'),
  134. __SSR__: String(format !== 'global'),
  135. __COMPAT__: String(target === 'vue-compat'),
  136. __FEATURE_SUSPENSE__: `true`,
  137. __FEATURE_OPTIONS_API__: `true`,
  138. __FEATURE_PROD_DEVTOOLS__: `false`,
  139. __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__: `true`,
  140. },
  141. })
  142. .then(ctx => ctx.watch())
  143. }