rollup.config.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. const fs = require('fs')
  2. const path = require('path')
  3. const ts = require('rollup-plugin-typescript2')
  4. const replace = require('rollup-plugin-replace')
  5. const alias = require('rollup-plugin-alias')
  6. const json = require('rollup-plugin-json')
  7. if (!process.env.TARGET) {
  8. throw new Error('TARGET package must be specified via --environment flag.')
  9. }
  10. const packagesDir = path.resolve(__dirname, 'packages')
  11. const packageDir = path.resolve(packagesDir, process.env.TARGET)
  12. const name = path.basename(packageDir)
  13. const resolve = p => path.resolve(packageDir, p)
  14. const pkg = require(resolve(`package.json`))
  15. const packageOptions = pkg.buildOptions || {}
  16. // build aliases dynamically
  17. const aliasOptions = { resolve: ['.ts'] }
  18. fs.readdirSync(packagesDir).forEach(dir => {
  19. if (fs.statSync(path.resolve(packagesDir, dir)).isDirectory()) {
  20. const name = dir === `vue` ? dir : `@vue/${dir}`
  21. aliasOptions[name] = path.resolve(packagesDir, `${dir}/src/index`)
  22. }
  23. })
  24. const aliasPlugin = alias(aliasOptions)
  25. // ensure TS checks only once for each build
  26. let hasTSChecked = false
  27. const configs = {
  28. esm: {
  29. file: resolve(`dist/${name}.esm-bundler.js`),
  30. format: `es`
  31. },
  32. cjs: {
  33. file: resolve(`dist/${name}.cjs.js`),
  34. format: `cjs`
  35. },
  36. global: {
  37. file: resolve(`dist/${name}.global.js`),
  38. format: `iife`
  39. },
  40. 'esm-browser': {
  41. file: resolve(`dist/${name}.esm-browser.js`),
  42. format: `es`
  43. }
  44. }
  45. const defaultFormats = ['esm', 'cjs']
  46. const inlineFromats = process.env.FORMATS && process.env.FORMATS.split(',')
  47. const packageFormats = inlineFromats || packageOptions.formats || defaultFormats
  48. const packageConfigs = process.env.PROD_ONLY
  49. ? []
  50. : packageFormats.map(format => createConfig(configs[format]))
  51. if (process.env.NODE_ENV === 'production') {
  52. packageFormats.forEach(format => {
  53. if (format === 'cjs') {
  54. packageConfigs.push(createProductionConfig(format))
  55. }
  56. if (format === 'global' || format === 'esm-browser') {
  57. packageConfigs.push(createMinifiedConfig(format))
  58. }
  59. })
  60. }
  61. module.exports = packageConfigs
  62. function createConfig(output, plugins = []) {
  63. const isProductionBuild =
  64. process.env.__DEV__ === 'false' || /\.prod\.js$/.test(output.file)
  65. const isGlobalBuild = /\.global(\.prod)?\.js$/.test(output.file)
  66. const isBunlderESMBuild = /\.esm\.js$/.test(output.file)
  67. const isBrowserESMBuild = /esm-browser(\.prod)?\.js$/.test(output.file)
  68. if (isGlobalBuild) {
  69. output.name = packageOptions.name
  70. }
  71. const shouldEmitDeclarations =
  72. process.env.TYPES != null &&
  73. process.env.NODE_ENV === 'production' &&
  74. !hasTSChecked
  75. const tsPlugin = ts({
  76. check: process.env.NODE_ENV === 'production' && !hasTSChecked,
  77. tsconfig: path.resolve(__dirname, 'tsconfig.json'),
  78. cacheRoot: path.resolve(__dirname, 'node_modules/.rts2_cache'),
  79. tsconfigOverride: {
  80. compilerOptions: {
  81. declaration: shouldEmitDeclarations,
  82. declarationMap: shouldEmitDeclarations
  83. },
  84. exclude: ['**/__tests__']
  85. }
  86. })
  87. // we only need to check TS and generate declarations once for each build.
  88. // it also seems to run into weird issues when checking multiple times
  89. // during a single build.
  90. hasTSChecked = true
  91. const externals = Object.keys(aliasOptions).filter(p => p !== '@vue/shared')
  92. return {
  93. input: resolve(`src/index.ts`),
  94. // Global and Browser ESM builds inlines everything so that they can be
  95. // used alone.
  96. external: isGlobalBuild || isBrowserESMBuild ? [] : externals,
  97. plugins: [
  98. json({
  99. namedExports: false
  100. }),
  101. tsPlugin,
  102. aliasPlugin,
  103. createReplacePlugin(
  104. isProductionBuild,
  105. isBunlderESMBuild,
  106. (isGlobalBuild || isBrowserESMBuild) &&
  107. !packageOptions.enableNonBrowserBranches
  108. ),
  109. ...plugins
  110. ],
  111. output,
  112. onwarn: (msg, warn) => {
  113. if (!/Circular/.test(msg)) {
  114. warn(msg)
  115. }
  116. }
  117. }
  118. }
  119. function createReplacePlugin(isProduction, isBunlderESMBuild, isBrowserBuild) {
  120. return replace({
  121. __COMMIT__: `"${process.env.COMMIT}"`,
  122. __DEV__: isBunlderESMBuild
  123. ? // preserve to be handled by bundlers
  124. `process.env.NODE_ENV !== 'production'`
  125. : // hard coded dev/prod builds
  126. !isProduction,
  127. // If the build is expected to run directly in the browser (global / esm-browser builds)
  128. __BROWSER__: isBrowserBuild,
  129. // support options?
  130. // the lean build drops options related code with buildOptions.lean: true
  131. __FEATURE_OPTIONS__: !packageOptions.lean,
  132. __FEATURE_SUSPENSE__: true,
  133. // this is only used during tests
  134. __JSDOM__: false
  135. })
  136. }
  137. function createProductionConfig(format) {
  138. return createConfig({
  139. file: resolve(`dist/${name}.${format}.prod.js`),
  140. format: configs[format].format
  141. })
  142. }
  143. function createMinifiedConfig(format) {
  144. const { terser } = require('rollup-plugin-terser')
  145. return createConfig(
  146. {
  147. file: resolve(`dist/${name}.${format}.prod.js`),
  148. format: configs[format].format
  149. },
  150. [
  151. terser({
  152. module: /^esm/.test(format)
  153. })
  154. ]
  155. )
  156. }