rollup.config.js 5.2 KB

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