rollup.config.js 5.4 KB

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