build.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. let fs = require('fs');
  2. let DotJson = require('dot-json');
  3. let brotliSize = require('brotli-size');
  4. ([
  5. // Packages:
  6. 'alpinejs',
  7. 'csp',
  8. 'history',
  9. 'intersect',
  10. 'persist',
  11. 'collapse',
  12. 'morph',
  13. 'focus',
  14. 'mask',
  15. ]).forEach(package => {
  16. if (! fs.existsSync(`./packages/${package}/dist`)) {
  17. fs.mkdirSync(`./packages/${package}/dist`, 0744);
  18. }
  19. // Go through each file in the package's "build" directory
  20. // and use the appropriate bundling strategy based on its name.
  21. fs.readdirSync(`./packages/${package}/builds`).forEach(file => {
  22. bundleFile(package, file)
  23. });
  24. })
  25. function bundleFile(package, file) {
  26. // Based on the filename, give esbuild a specific configuration to build.
  27. ({
  28. // This output file is meant to be loaded in a browser's <script> tag.
  29. 'cdn.js': () => {
  30. build({
  31. entryPoints: [`packages/${package}/builds/${file}`],
  32. outfile: `packages/${package}/dist/${file}`,
  33. bundle: true,
  34. platform: 'browser',
  35. define: { CDN: true },
  36. })
  37. // Build a minified version.
  38. build({
  39. entryPoints: [`packages/${package}/builds/${file}`],
  40. outfile: `packages/${package}/dist/${file.replace('.js', '.min.js')}`,
  41. bundle: true,
  42. minify: true,
  43. platform: 'browser',
  44. define: { CDN: true },
  45. }).then(() => {
  46. outputSize(package, `packages/${package}/dist/${file.replace('.js', '.min.js')}`)
  47. })
  48. },
  49. // This file outputs two files: an esm module and a cjs module.
  50. // The ESM one is meant for "import" statements (bundlers and new browsers)
  51. // and the cjs one is meant for "require" statements (node).
  52. 'module.js': () => {
  53. build({
  54. entryPoints: [`packages/${package}/builds/${file}`],
  55. outfile: `packages/${package}/dist/${file.replace('.js', '.esm.js')}`,
  56. bundle: true,
  57. platform: 'neutral',
  58. mainFields: ['module', 'main'],
  59. })
  60. build({
  61. entryPoints: [`packages/${package}/builds/${file}`],
  62. outfile: `packages/${package}/dist/${file.replace('.js', '.cjs.js')}`,
  63. bundle: true,
  64. target: ['node10.4'],
  65. platform: 'node',
  66. }).then(() => {
  67. writeToPackageDotJson(package, 'main', `dist/${file.replace('.js', '.cjs.js')}`)
  68. writeToPackageDotJson(package, 'module', `dist/${file.replace('.js', '.esm.js')}`)
  69. })
  70. },
  71. })[file]()
  72. }
  73. function build(options) {
  74. options.define || (options.define = {})
  75. options.define['ALPINE_VERSION'] = `'${getFromPackageDotJson('alpinejs', 'version')}'`
  76. options.define['process.env.NODE_ENV'] = process.argv.includes('--watch') ? `'production'` : `'development'`
  77. return require('esbuild').build({
  78. watch: process.argv.includes('--watch'),
  79. // external: ['alpinejs'],
  80. ...options,
  81. }).catch(() => process.exit(1))
  82. }
  83. function writeToPackageDotJson(package, key, value) {
  84. let dotJson = new DotJson(`./packages/${package}/package.json`)
  85. dotJson.set(key, value).save()
  86. }
  87. function getFromPackageDotJson(package, key) {
  88. let dotJson = new DotJson(`./packages/${package}/package.json`)
  89. return dotJson.get(key)
  90. }
  91. function outputSize(package, file) {
  92. let size = bytesToSize(brotliSize.sync(fs.readFileSync(file)))
  93. console.log("\x1b[32m", `${package}: ${size}`)
  94. }
  95. function bytesToSize(bytes) {
  96. const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
  97. if (bytes === 0) return 'n/a'
  98. const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10)
  99. if (i === 0) return `${bytes} ${sizes[i]}`
  100. return `${(bytes / (1024 ** i)).toFixed(1)} ${sizes[i]}`
  101. }