aboutsummaryrefslogtreecommitdiff
path: root/build
diff options
context:
space:
mode:
authorBobby <[email protected]>2024-08-16 20:47:33 -0400
committerGitHub <[email protected]>2024-08-16 20:47:33 -0400
commit6b28433d9cfde435be8ec2bd6cf91e6324d08865 (patch)
tree8343c27b8b95ff5639233e81cf157f92e5688466 /build
parentd53094ec16ba385faae2973ddee648698b32ab24 (diff)
parent048f56f51460df75e92a2f7b472e1c56baeb68f7 (diff)
downloadbootstrap-main.tar.xz
bootstrap-main.zip
Merge branch 'twbs:main' into mainHEADmain
Diffstat (limited to 'build')
-rw-r--r--build/.eslintrc.json14
-rw-r--r--build/banner.mjs (renamed from build/banner.js)12
-rw-r--r--build/build-plugins.mjs (renamed from build/build-plugins.js)32
-rw-r--r--build/change-version.js81
-rw-r--r--build/change-version.mjs113
-rw-r--r--build/generate-sri.mjs (renamed from build/generate-sri.js)36
-rw-r--r--build/postcss.config.js19
-rw-r--r--build/postcss.config.mjs17
-rw-r--r--build/rollup.config.mjs (renamed from build/rollup.config.js)24
-rw-r--r--build/svgo.yml59
-rw-r--r--build/vnu-jar.mjs (renamed from build/vnu-jar.js)16
-rw-r--r--build/zip-examples.mjs (renamed from build/zip-examples.js)25
12 files changed, 215 insertions, 233 deletions
diff --git a/build/.eslintrc.json b/build/.eslintrc.json
deleted file mode 100644
index 679bd26f7..000000000
--- a/build/.eslintrc.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "env": {
- "browser": false,
- "node": true
- },
- "parserOptions": {
- "sourceType": "script"
- },
- "extends": "../.eslintrc.json",
- "rules": {
- "no-console": "off",
- "strict": "error"
- }
-}
diff --git a/build/banner.js b/build/banner.mjs
index df82ff32e..3fea93c8f 100644
--- a/build/banner.js
+++ b/build/banner.mjs
@@ -1,6 +1,12 @@
-'use strict'
+import fs from 'node:fs/promises'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
+
+const pkgJson = path.join(__dirname, '../package.json')
+const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8'))
-const pkg = require('../package.json')
const year = new Date().getFullYear()
function getBanner(pluginFilename) {
@@ -11,4 +17,4 @@ function getBanner(pluginFilename) {
*/`
}
-module.exports = getBanner
+export default getBanner
diff --git a/build/build-plugins.js b/build/build-plugins.mjs
index 044344743..532b0b4be 100644
--- a/build/build-plugins.js
+++ b/build/build-plugins.mjs
@@ -2,21 +2,22 @@
/*!
* Script to build our plugins to use them separately.
- * Copyright 2020-2021 The Bootstrap Authors
- * Copyright 2020-2021 Twitter, Inc.
+ * Copyright 2020-2024 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-'use strict'
+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 path = require('path')
-const rollup = require('rollup')
-const glob = require('glob')
-const { babel } = require('@rollup/plugin-babel')
-const banner = require('./banner.js')
+const __filename = fileURLToPath(import.meta.url)
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
-const srcPath = path.resolve(__dirname, '../js/src/')
-const jsFiles = glob.sync(srcPath + '/**/*.js')
+const sourcePath = path.resolve(__dirname, '../js/src/').replace(/\\/g, '/')
+const jsFiles = await globby(`${sourcePath}/**/*.js`)
// Array which holds the resolved plugins
const resolvedPlugins = []
@@ -27,18 +28,21 @@ const filenameToEntity = filename => filename.replace('.js', '')
for (const file of jsFiles) {
resolvedPlugins.push({
- src: file.replace('.js', ''),
+ src: file,
dist: file.replace('src', 'dist'),
fileName: path.basename(file),
className: filenameToEntity(path.basename(file))
- // safeClassName: filenameToEntity(path.relative(srcPath, file))
+ // safeClassName: filenameToEntity(path.relative(sourcePath, file))
})
}
const build = async plugin => {
+ /**
+ * @type {import('rollup').GlobalsOption}
+ */
const globals = {}
- const bundle = await rollup.rollup({
+ const bundle = await rollup({
input: plugin.src,
plugins: [
babel({
@@ -48,7 +52,7 @@ const build = async plugin => {
babelHelpers: 'bundled'
})
],
- external: source => {
+ external(source) {
// Pattern to identify local files
const pattern = /^(\.{1,2})\//
diff --git a/build/change-version.js b/build/change-version.js
deleted file mode 100644
index 22a169db9..000000000
--- a/build/change-version.js
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env node
-
-/*!
- * Script to update version number references in the project.
- * Copyright 2017-2021 The Bootstrap Authors
- * Copyright 2017-2021 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
- */
-
-'use strict'
-
-const fs = require('fs').promises
-const path = require('path')
-const globby = require('globby')
-
-const VERBOSE = process.argv.includes('--verbose')
-const DRY_RUN = process.argv.includes('--dry') || process.argv.includes('--dry-run')
-
-// These are the filetypes we only care about replacing the version
-const GLOB = [
- '**/*.{css,html,js,json,md,scss,txt,yml}'
-]
-const GLOBBY_OPTIONS = {
- cwd: path.join(__dirname, '..'),
- gitignore: true
-}
-
-// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
-function regExpQuote(string) {
- return string.replace(/[$()*+-.?[\\\]^{|}]/g, '\\$&')
-}
-
-function regExpQuoteReplacement(string) {
- return string.replace(/\$/g, '$$')
-}
-
-async function replaceRecursively(file, oldVersion, newVersion) {
- const originalString = await fs.readFile(file, 'utf8')
- const newString = originalString.replace(
- new RegExp(regExpQuote(oldVersion), 'g'), regExpQuoteReplacement(newVersion)
- )
-
- // No need to move any further if the strings are identical
- if (originalString === newString) {
- return
- }
-
- if (VERBOSE) {
- console.log(`FILE: ${file}`)
- }
-
- if (DRY_RUN) {
- return
- }
-
- await fs.writeFile(file, newString, 'utf8')
-}
-
-async function main(args) {
- let [oldVersion, newVersion] = args
-
- if (!oldVersion || !newVersion) {
- console.error('USAGE: change-version old_version new_version [--verbose] [--dry[-run]]')
- console.error('Got arguments:', args)
- process.exit(1)
- }
-
- // Strip any leading `v` from arguments because otherwise we will end up with duplicate `v`s
- [oldVersion, newVersion] = [oldVersion, newVersion].map(arg => arg.startsWith('v') ? arg.slice(1) : arg)
-
- try {
- const files = await globby(GLOB, GLOBBY_OPTIONS)
-
- await Promise.all(files.map(file => replaceRecursively(file, oldVersion, newVersion)))
- } catch (error) {
- console.error(error)
- process.exit(1)
- }
-}
-
-main(process.argv.slice(2))
diff --git a/build/change-version.mjs b/build/change-version.mjs
new file mode 100644
index 000000000..30cfcc456
--- /dev/null
+++ b/build/change-version.mjs
@@ -0,0 +1,113 @@
+#!/usr/bin/env node
+
+/*!
+ * Script to update version number references in the project.
+ * Copyright 2017-2024 The Bootstrap Authors
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */
+
+import { execFile } from 'node:child_process'
+import fs from 'node:fs/promises'
+import process from 'node:process'
+
+const VERBOSE = process.argv.includes('--verbose')
+const DRY_RUN = process.argv.includes('--dry') || process.argv.includes('--dry-run')
+
+// These are the files we only care about replacing the version
+const FILES = [
+ 'README.md',
+ 'hugo.yml',
+ 'js/src/base-component.js',
+ 'package.js',
+ 'scss/mixins/_banner.scss',
+ 'site/data/docs-versions.yml'
+]
+
+// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
+function regExpQuote(string) {
+ return string.replace(/[$()*+-.?[\\\]^{|}]/g, '\\$&')
+}
+
+function regExpQuoteReplacement(string) {
+ return string.replace(/\$/g, '$$')
+}
+
+async function replaceRecursively(file, oldVersion, newVersion) {
+ const originalString = await fs.readFile(file, 'utf8')
+ const newString = originalString
+ .replace(
+ new RegExp(regExpQuote(oldVersion), 'g'),
+ regExpQuoteReplacement(newVersion)
+ )
+ // Also replace the version used by the rubygem,
+ // which is using periods (`.`) instead of hyphens (`-`)
+ .replace(
+ new RegExp(regExpQuote(oldVersion.replace(/-/g, '.')), 'g'),
+ regExpQuoteReplacement(newVersion.replace(/-/g, '.'))
+ )
+
+ // No need to move any further if the strings are identical
+ if (originalString === newString) {
+ return
+ }
+
+ if (VERBOSE) {
+ console.log(`Found ${oldVersion} in ${file}`)
+ }
+
+ if (DRY_RUN) {
+ return
+ }
+
+ await fs.writeFile(file, newString, 'utf8')
+}
+
+function bumpNpmVersion(newVersion) {
+ if (DRY_RUN) {
+ return
+ }
+
+ execFile('npm', ['version', newVersion, '--no-git-tag'], { shell: true }, error => {
+ if (error) {
+ console.error(error)
+ process.exit(1)
+ }
+ })
+}
+
+function showUsage(args) {
+ console.error('USAGE: change-version old_version new_version [--verbose] [--dry[-run]]')
+ console.error('Got arguments:', args)
+ process.exit(1)
+}
+
+async function main(args) {
+ let [oldVersion, newVersion] = args
+
+ if (!oldVersion || !newVersion) {
+ showUsage(args)
+ }
+
+ // Strip any leading `v` from arguments because
+ // otherwise we will end up with duplicate `v`s
+ [oldVersion, newVersion] = [oldVersion, newVersion].map(arg => {
+ return arg.startsWith('v') ? arg.slice(1) : arg
+ })
+
+ if (oldVersion === newVersion) {
+ showUsage(args)
+ }
+
+ bumpNpmVersion(newVersion)
+
+ try {
+ await Promise.all(
+ FILES.map(file => replaceRecursively(file, oldVersion, newVersion))
+ )
+ } catch (error) {
+ console.error(error)
+ process.exit(1)
+ }
+}
+
+main(process.argv.slice(2))
diff --git a/build/generate-sri.js b/build/generate-sri.mjs
index 47d02c4c3..384e8f428 100644
--- a/build/generate-sri.js
+++ b/build/generate-sri.mjs
@@ -5,25 +5,25 @@
* Remember to use the same vendor files as the CDN ones,
* otherwise the hashes won't match!
*
- * Copyright 2017-2021 The Bootstrap Authors
- * Copyright 2017-2021 Twitter, Inc.
+ * Copyright 2017-2024 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-'use strict'
+import crypto from 'node:crypto'
+import fs from 'node:fs'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+import sh from 'shelljs'
-const crypto = require('crypto')
-const fs = require('fs')
-const path = require('path')
-const sh = require('shelljs')
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
sh.config.fatal = true
-const configFile = path.join(__dirname, '../config.yml')
+const configFile = path.join(__dirname, '../hugo.yml')
// Array of objects which holds the files to generate SRI hashes for.
// `file` is the path from the root folder
-// `configPropertyName` is the config.yml variable's name of the file
+// `configPropertyName` is the hugo.yml variable's name of the file
const files = [
{
file: 'dist/css/bootstrap.min.css',
@@ -47,18 +47,18 @@ const files = [
}
]
-for (const file of files) {
- fs.readFile(file.file, 'utf8', (err, data) => {
- if (err) {
- throw err
+for (const { file, configPropertyName } of files) {
+ fs.readFile(file, 'utf8', (error, data) => {
+ if (error) {
+ throw error
}
- const algo = 'sha384'
- const hash = crypto.createHash(algo).update(data, 'utf8').digest('base64')
- const integrity = `${algo}-${hash}`
+ const algorithm = 'sha384'
+ const hash = crypto.createHash(algorithm).update(data, 'utf8').digest('base64')
+ const integrity = `${algorithm}-${hash}`
- console.log(`${file.configPropertyName}: ${integrity}`)
+ console.log(`${configPropertyName}: ${integrity}`)
- sh.sed('-i', new RegExp(`^(\\s+${file.configPropertyName}:\\s+["'])\\S*(["'])`), `$1${integrity}$2`, configFile)
+ sh.sed('-i', new RegExp(`^(\\s+${configPropertyName}:\\s+["'])\\S*(["'])`), `$1${integrity}$2`, configFile)
})
}
diff --git a/build/postcss.config.js b/build/postcss.config.js
deleted file mode 100644
index b179a0e77..000000000
--- a/build/postcss.config.js
+++ /dev/null
@@ -1,19 +0,0 @@
-'use strict'
-
-module.exports = ctx => {
- return {
- map: ctx.file.dirname.includes('examples') ?
- false :
- {
- inline: false,
- annotation: true,
- sourcesContent: true
- },
- plugins: {
- autoprefixer: {
- cascade: false
- },
- rtlcss: ctx.env === 'RTL' ? {} : false
- }
- }
-}
diff --git a/build/postcss.config.mjs b/build/postcss.config.mjs
new file mode 100644
index 000000000..7717cfc3f
--- /dev/null
+++ b/build/postcss.config.mjs
@@ -0,0 +1,17 @@
+const mapConfig = {
+ inline: false,
+ annotation: true,
+ sourcesContent: true
+}
+
+export default context => {
+ return {
+ map: context.file.dirname.includes('examples') ? false : mapConfig,
+ plugins: {
+ autoprefixer: {
+ cascade: false
+ },
+ rtlcss: context.env === 'RTL'
+ }
+ }
+}
diff --git a/build/rollup.config.js b/build/rollup.config.mjs
index c00438de2..dd6c7d13e 100644
--- a/build/rollup.config.js
+++ b/build/rollup.config.mjs
@@ -1,15 +1,17 @@
-'use strict'
+import path from 'node:path'
+import process from 'node:process'
+import { fileURLToPath } from 'node:url'
+import { babel } from '@rollup/plugin-babel'
+import { nodeResolve } from '@rollup/plugin-node-resolve'
+import replace from '@rollup/plugin-replace'
+import banner from './banner.mjs'
-const path = require('path')
-const { babel } = require('@rollup/plugin-babel')
-const { nodeResolve } = require('@rollup/plugin-node-resolve')
-const replace = require('@rollup/plugin-replace')
-const banner = require('./banner.js')
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
const BUNDLE = process.env.BUNDLE === 'true'
const ESM = process.env.ESM === 'true'
-let fileDest = `bootstrap${ESM ? '.esm' : ''}`
+let destinationFile = `bootstrap${ESM ? '.esm' : ''}`
const external = ['@popperjs/core']
const plugins = [
babel({
@@ -24,7 +26,7 @@ const globals = {
}
if (BUNDLE) {
- fileDest += '.bundle'
+ destinationFile += '.bundle'
// Remove last entry in external array to bundle Popper
external.pop()
delete globals['@popperjs/core']
@@ -40,8 +42,8 @@ if (BUNDLE) {
const rollupConfig = {
input: path.resolve(__dirname, `../js/index.${ESM ? 'esm' : 'umd'}.js`),
output: {
- banner,
- file: path.resolve(__dirname, `../dist/js/${fileDest}.js`),
+ banner: banner(),
+ file: path.resolve(__dirname, `../dist/js/${destinationFile}.js`),
format: ESM ? 'esm' : 'umd',
globals,
generatedCode: 'es2015'
@@ -54,4 +56,4 @@ if (!ESM) {
rollupConfig.output.name = 'bootstrap'
}
-module.exports = rollupConfig
+export default rollupConfig
diff --git a/build/svgo.yml b/build/svgo.yml
deleted file mode 100644
index 67940d393..000000000
--- a/build/svgo.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-# Usage:
-# install svgo globally: `npm i -g svgo`
-# svgo --config=build/svgo.yml --input=foo.svg
-
-# https://github.com/svg/svgo/blob/master/docs/how-it-works/en.md
-# replace default config
-
-multipass: true
-#full: true
-
-# https://github.com/svg/svgo/blob/master/lib/svgo/js2svg.js#L6 for more config options
-
-js2svg:
- pretty: true
- indent: 2
-
-plugins:
-# - addAttributesToSVGElement:
-# attributes:
-# - focusable: false
- - cleanupAttrs: true
- - cleanupEnableBackground: true
- - cleanupIDs: true
- - cleanupListOfValues: true
- - cleanupNumericValues: true
- - collapseGroups: true
- - convertColors: true
- - convertPathData: true
- - convertShapeToPath: true
- - convertStyleToAttrs: true
- - convertTransform: true
- - inlineStyles: true
- - mergePaths: true
- - minifyStyles: true
- - moveElemsAttrsToGroup: true
- - moveGroupAttrsToElems: true
- - removeAttrs:
- attrs:
- - "data-name"
- - removeComments: true
- - removeDesc: true
- - removeDoctype: true
- - removeEditorsNSData: true
- - removeEmptyAttrs: true
- - removeEmptyContainers: true
- - removeEmptyText: true
- - removeHiddenElems: true
- - removeMetadata: true
- - removeNonInheritableGroupAttrs: true
- - removeTitle: false
- - removeUnknownsAndDefaults:
- keepRoleAttr: true
- - removeUnusedNS: true
- - removeUselessDefs: true
- - removeUselessStrokeAndFill: true
- - removeViewBox: false
- - removeXMLNS: false
- - removeXMLProcInst: true
- - sortAttrs: true
diff --git a/build/vnu-jar.js b/build/vnu-jar.mjs
index 2d5cc8b55..18a35bdff 100644
--- a/build/vnu-jar.js
+++ b/build/vnu-jar.mjs
@@ -2,22 +2,22 @@
/*!
* Script to run vnu-jar if Java is available.
- * Copyright 2017-2021 The Bootstrap Authors
- * Copyright 2017-2021 Twitter, Inc.
+ * Copyright 2017-2024 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-'use strict'
-
-const { execFile, spawn } = require('child_process')
-const vnu = require('vnu-jar')
+import { execFile, spawn } from 'node:child_process'
+import vnu from 'vnu-jar'
execFile('java', ['-version'], (error, stdout, stderr) => {
if (error) {
- console.error('Skipping vnu-jar test; Java is missing.')
+ console.error('Skipping vnu-jar test; Java is probably missing.')
+ console.error(error)
return
}
+ console.log('Running vnu-jar validation...')
+
const is32bitJava = !/64-Bit/.test(stderr)
// vnu-jar accepts multiple ignores joined with a `|`.
@@ -49,6 +49,8 @@ execFile('java', ['-version'], (error, stdout, stderr) => {
args.splice(0, 0, '-Xss512k')
}
+ console.log(`command used: java ${args.join(' ')}`)
+
return spawn('java', args, {
shell: true,
stdio: 'inherit'
diff --git a/build/zip-examples.js b/build/zip-examples.mjs
index 6c8ae527a..e5e39be3a 100644
--- a/build/zip-examples.js
+++ b/build/zip-examples.mjs
@@ -3,16 +3,19 @@
/*!
* Script to create the built examples zip archive;
* requires the `zip` command to be present!
- * Copyright 2020-2021 The Bootstrap Authors
+ * Copyright 2020-2024 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-'use strict'
+import fs from 'node:fs/promises'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+import sh from 'shelljs'
-const path = require('path')
-const sh = require('shelljs')
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
-const pkg = require('../package.json')
+const pkgJson = path.join(__dirname, '../package.json')
+const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8'))
const versionShort = pkg.config.version_short
const distFolder = `bootstrap-${pkg.version}-examples`
@@ -34,6 +37,9 @@ const imgFiles = [
'bootstrap-logo.svg',
'bootstrap-logo-white.svg'
]
+const staticJsFiles = [
+ 'color-modes.js'
+]
sh.config.fatal = true
@@ -52,7 +58,8 @@ sh.mkdir('-p', [
distFolder,
`${distFolder}/assets/brand/`,
`${distFolder}/assets/dist/css/`,
- `${distFolder}/assets/dist/js/`
+ `${distFolder}/assets/dist/js/`,
+ `${distFolder}/assets/js/`
])
sh.cp('-Rf', `${docsDir}/examples/*`, distFolder)
@@ -69,6 +76,10 @@ for (const file of imgFiles) {
sh.cp('-f', `${docsDir}/assets/brand/${file}`, `${distFolder}/assets/brand/`)
}
+for (const file of staticJsFiles) {
+ sh.cp('-f', `${docsDir}/assets/js/${file}`, `${distFolder}/assets/js/`)
+}
+
sh.rm(`${distFolder}/index.html`)
// get all examples' HTML files
@@ -84,7 +95,7 @@ for (const file of sh.find(`${distFolder}/**/*.html`)) {
}
// create the zip file
-sh.exec(`zip -r9 "${distFolder}.zip" "${distFolder}"`)
+sh.exec(`zip -qr9 "${distFolder}.zip" "${distFolder}"`)
// remove the folder we created
sh.rm('-rf', distFolder)