Socialify

Folder ..

Viewing build-plugins.mjs
108 lines (89 loc) • 2.9 KB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env node

/*!
 * Script to build our plugins to use them separately.
 * Copyright 2020-2024 The Bootstrap Authors
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 */

import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { babel } from '@rollup/plugin-babel'
import { globby } from 'globby'
import { rollup } from 'rollup'
import banner from './banner.mjs'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(fileURLToPath(import.meta.url))

const sourcePath = path.resolve(__dirname, '../js/src/').replace(/\\/g, '/')
const jsFiles = await globby(`${sourcePath}/**/*.js`)

// Array which holds the resolved plugins
const resolvedPlugins = []

// Trims the "js" extension and uppercases => first letter, hyphens, backslashes & slashes
const filenameToEntity = filename => filename.replace('.js', '')
  .replace(/(?:^|-|\/|\\)[a-z]/g, str => str.slice(-1).toUpperCase())

for (const file of jsFiles) {
  resolvedPlugins.push({
    src: file,
    dist: file.replace('src', 'dist'),
    fileName: path.basename(file),
    className: filenameToEntity(path.basename(file))
    // safeClassName: filenameToEntity(path.relative(sourcePath, file))
  })
}

const build = async plugin => {
  /**
   * @type {import('rollup').GlobalsOption}
   */
  const globals = {}

  const bundle = await rollup({
    input: plugin.src,
    plugins: [
      babel({
        // Only transpile our source code
        exclude: 'node_modules/**',
        // Include the helpers in each file, at most one copy of each
        babelHelpers: 'bundled'
      })
    ],
    external(source) {
      // Pattern to identify local files
      const pattern = /^(\.{1,2})\//

      // It's not a local file, e.g a Node.js package
      if (!pattern.test(source)) {
        globals[source] = source
        return true
      }

      const usedPlugin = resolvedPlugins.find(plugin => {
        return plugin.src.includes(source.replace(pattern, ''))
      })

      if (!usedPlugin) {
        throw new Error(`Source ${source} is not mapped!`)
      }

      // We can change `Index` with `UtilIndex` etc if we use
      // `safeClassName` instead of `className` everywhere
      globals[path.normalize(usedPlugin.src)] = usedPlugin.className
      return true
    }
  })

  await bundle.write({
    banner: banner(plugin.fileName),
    format: 'umd',
    name: plugin.className,
    sourcemap: true,
    globals,
    generatedCode: 'es2015',
    file: plugin.dist
  })

  console.log(`Built ${plugin.className}`)
}

(async () => {
  try {
    const basename = path.basename(__filename)
    const timeLabel = `[${basename}] finished`

    console.log('Building individual plugins...')
    console.time(timeLabel)

    await Promise.all(Object.values(resolvedPlugins).map(plugin => build(plugin)))

    console.timeEnd(timeLabel)
  } catch (error) {
    console.error(error)
    process.exit(1)
  }
})()