rollup-bundles.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. const path = require('path')
  2. const glob = require('glob')
  3. const nodeResolve = require('rollup-plugin-node-resolve')
  4. const postCss = require('rollup-plugin-postcss')
  5. const { renderBanner, isRelPath, SOURCEMAP_PLUGINS, WATCH_OPTIONS, EXTERNAL_BROWSER_GLOBALS, TEMPLATE_PLUGIN, onwarn, isScssPath } = require('./rollup-util')
  6. const { pkgStructs, pkgStructHash, getCorePkgStruct, getNonPremiumBundle } = require('./pkg-struct')
  7. const alias = require('rollup-plugin-alias')
  8. module.exports = function(isDev) {
  9. let configs = []
  10. for (let pkgStruct of pkgStructs) {
  11. if (pkgStruct.isBundle) {
  12. let bundleConfig = buildBundleConfig(pkgStruct, isDev)
  13. let nonBundleNames = require(path.join(process.cwd(), pkgStruct.dir, 'non-bundled-plugins.json'))
  14. let nonBundleConfigs = nonBundleNames.map((name) => (
  15. buildNonBundleConfig(pkgStructHash[name], pkgStruct.distDir, isDev)
  16. ))
  17. configs.push(
  18. bundleConfig,
  19. ...nonBundleConfigs
  20. )
  21. }
  22. }
  23. configs.push(
  24. ...buildLocaleConfigs(),
  25. buildLocalesAllConfig()
  26. )
  27. return configs
  28. }
  29. function buildBundleConfig(pkgStruct, isDev) {
  30. let banner = renderBanner(pkgStruct.jsonObj)
  31. return {
  32. input: path.join('tmp/tsc-output', pkgStruct.srcDir, 'main.js'), // TODO: use tscMain
  33. output: {
  34. format: 'umd',
  35. file: path.join(pkgStruct.distDir, 'main.js'),
  36. name: EXTERNAL_BROWSER_GLOBALS['fullcalendar'], // TODO: make it a separarate const???
  37. banner,
  38. sourcemap: isDev
  39. },
  40. plugins: [
  41. alias(buildAliasMap()),
  42. nodeResolve(), // for requiring tslib. TODO: whitelist?
  43. postCss({
  44. extract: true // to separate file
  45. }),
  46. ...(isDev ? SOURCEMAP_PLUGINS : []),
  47. {
  48. resolveId(id, importer) { // TODO: not really DRY // TODO: use alias instead?
  49. if (isScssPath(id) && isRelPath(id) && importer.match('/tmp/tsc-output/')) {
  50. let resourcePath = importer.replace('/tmp/tsc-output/', '/')
  51. resourcePath = path.dirname(resourcePath) // the directory of the file
  52. resourcePath = resourcePath.replace(/\/src(\/|$)/, '/dist$1')
  53. resourcePath = path.join(resourcePath, id.replace('.scss', '.css'))
  54. return { id: resourcePath, external: false }
  55. }
  56. return null
  57. }
  58. },
  59. ],
  60. watch: WATCH_OPTIONS,
  61. onwarn
  62. }
  63. }
  64. /*
  65. if the exports object has the globalPlugins property, that means the exports object
  66. is the same as the root fullcalendar namespace, which means we're executing as browser globals.
  67. in this case, register the plugin globally. also, undo attaching a useless `default` export.
  68. */
  69. const OUTRO = `
  70. if (exports.globalPlugins) {
  71. exports.globalPlugins.push(exports.default)
  72. delete exports.default
  73. }
  74. `
  75. /*
  76. modules we don't want in the main bundle file but want as separate files in the same dir.
  77. can't have CSS.
  78. */
  79. function buildNonBundleConfig(pkgStruct, bundleDistDir, isDev) {
  80. let banner = renderBanner(pkgStruct.jsonObj)
  81. let inputFile = path.join('tmp/tsc-output', pkgStruct.srcDir, 'main.js')
  82. return {
  83. input: inputFile,
  84. output: {
  85. format: 'umd',
  86. file: path.join(bundleDistDir, pkgStruct.shortName + '.js'),
  87. name: EXTERNAL_BROWSER_GLOBALS['fullcalendar'], // tack on to existing global
  88. extend: true, // don't overwrite whats already on the UMD global
  89. exports: 'named', // allows export of default AND named
  90. globals: EXTERNAL_BROWSER_GLOBALS, // because these pkgStructs are connectors to third party plugins, and we dont want to include 3rd party files!
  91. banner,
  92. outro: OUTRO,
  93. sourcemap: isDev
  94. },
  95. plugins: [
  96. // if we don't provide this whitelist, all external packages get resolved and included :(
  97. nodeResolve({ only: [ 'tslib' ] }),
  98. TEMPLATE_PLUGIN,
  99. ...(isDev ? SOURCEMAP_PLUGINS : []),
  100. {
  101. // use the resolvedId hook to rename the import of @fullcalendar/core -> fullcalendar.
  102. // otherwise, we could have used the exernals config option all the way.
  103. // nodeResolve seems to take precedence (thus the tslib hack). PUT THIS FIRST?s
  104. resolveId(id) {
  105. if (id === inputFile) { return inputFile }
  106. if (id === 'tslib') { return { id, external: false } }
  107. if (id === '@fullcalendar/core') { return { id: 'fullcalendar', external: true } } // TODO: shouldn't this be 'fullcalendar-scheduler' in some cases?
  108. if (!isRelPath(id)) { return { id, external: true } }
  109. return null
  110. }
  111. }
  112. ],
  113. watch: WATCH_OPTIONS,
  114. onwarn
  115. }
  116. }
  117. function buildLocaleConfigs() { // for EACH
  118. let corePkg = getCorePkgStruct()
  119. let bundleStruct = getNonPremiumBundle()
  120. let localePaths = glob.sync('locales/*.js', { cwd: corePkg.tscDir })
  121. return localePaths.map((localePath) => {
  122. let localeCode = path.basename(localePath).replace(/\.[^.]*$/, '')
  123. return {
  124. input: path.join(corePkg.tscDir, localePath),
  125. output: {
  126. format: 'umd',
  127. name: 'FullCalendarLocales.' + localeCode, // code isn't used, but needs to be unique
  128. file: path.join(bundleStruct.distDir, localePath)
  129. }
  130. }
  131. })
  132. }
  133. function buildLocalesAllConfig() {
  134. let corePkgStruct = getCorePkgStruct()
  135. let bundleStruct = getNonPremiumBundle()
  136. return {
  137. input: path.join(corePkgStruct.distDir, 'locales-all.js'),
  138. output: {
  139. format: 'umd',
  140. name: 'FullCalendarLocales',
  141. file: path.join(bundleStruct.distDir, 'locales-all.js'),
  142. },
  143. watch: WATCH_OPTIONS,
  144. onwarn
  145. }
  146. }
  147. // TODO: use elsewhere
  148. // NOTE: can't use `entries` because rollup-plugin-alias is an old version
  149. function buildAliasMap() {
  150. let map = {}
  151. for (let pkgStruct of pkgStructs) {
  152. if (!pkgStruct.isBundle) {
  153. map[pkgStruct.name] = path.join(process.cwd(), pkgStruct.tscMain) // needs to be absolute
  154. }
  155. }
  156. return map
  157. }