diff options
Diffstat (limited to 'build')
| -rw-r--r-- | build/build-plugins.js | 29 | ||||
| -rw-r--r-- | build/change-version.js | 125 | ||||
| -rw-r--r-- | build/generate-sri.js | 6 | ||||
| -rw-r--r-- | build/rollup.config.js | 15 | ||||
| -rw-r--r-- | build/ship.sh | 55 | ||||
| -rw-r--r-- | build/vnu-jar.js | 8 | ||||
| -rw-r--r-- | build/zip-examples.js | 73 |
7 files changed, 136 insertions, 175 deletions
diff --git a/build/build-plugins.js b/build/build-plugins.js index 7deda49b1..53093dc41 100644 --- a/build/build-plugins.js +++ b/build/build-plugins.js @@ -2,8 +2,8 @@ /*! * Script to build our plugins to use them separately. - * Copyright 2020 The Bootstrap Authors - * Copyright 2020 Twitter, Inc. + * Copyright 2020-2021 The Bootstrap Authors + * Copyright 2020-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -14,12 +14,13 @@ const rollup = require('rollup') const { babel } = require('@rollup/plugin-babel') const banner = require('./banner.js') +const rootPath = path.resolve(__dirname, '../js/dist/') const plugins = [ babel({ // Only transpile our source code exclude: 'node_modules/**', - // Inline the required helpers in each file - babelHelpers: 'inline' + // Include the helpers in each file, at most one copy of each + babelHelpers: 'bundled' }) ] const bsPlugins = { @@ -28,27 +29,30 @@ const bsPlugins = { Manipulator: path.resolve(__dirname, '../js/src/dom/manipulator.js'), SelectorEngine: path.resolve(__dirname, '../js/src/dom/selector-engine.js'), Alert: path.resolve(__dirname, '../js/src/alert.js'), + Base: path.resolve(__dirname, '../js/src/base-component.js'), Button: path.resolve(__dirname, '../js/src/button.js'), Carousel: path.resolve(__dirname, '../js/src/carousel.js'), Collapse: path.resolve(__dirname, '../js/src/collapse.js'), Dropdown: path.resolve(__dirname, '../js/src/dropdown.js'), Modal: path.resolve(__dirname, '../js/src/modal.js'), + Offcanvas: path.resolve(__dirname, '../js/src/offcanvas.js'), Popover: path.resolve(__dirname, '../js/src/popover.js'), ScrollSpy: path.resolve(__dirname, '../js/src/scrollspy.js'), Tab: path.resolve(__dirname, '../js/src/tab.js'), Toast: path.resolve(__dirname, '../js/src/toast.js'), Tooltip: path.resolve(__dirname, '../js/src/tooltip.js') } -const rootPath = path.resolve(__dirname, '../js/dist/') const defaultPluginConfig = { external: [ bsPlugins.Data, + bsPlugins.Base, bsPlugins.EventHandler, bsPlugins.SelectorEngine ], globals: { [bsPlugins.Data]: 'Data', + [bsPlugins.Base]: 'Base', [bsPlugins.EventHandler]: 'EventHandler', [bsPlugins.SelectorEngine]: 'SelectorEngine' } @@ -61,18 +65,20 @@ const getConfigByPluginKey = pluginKey => { pluginKey === 'EventHandler' || pluginKey === 'SelectorEngine' || pluginKey === 'Util' || - pluginKey === 'Sanitizer' + pluginKey === 'Sanitizer' || + pluginKey === 'Backdrop' ) { return { external: [] } } - if (pluginKey === 'Alert' || pluginKey === 'Tab') { + if (pluginKey === 'Alert' || pluginKey === 'Tab' || pluginKey === 'Offcanvas') { return defaultPluginConfig } if ( + pluginKey === 'Base' || pluginKey === 'Button' || pluginKey === 'Carousel' || pluginKey === 'Collapse' || @@ -87,9 +93,9 @@ const getConfigByPluginKey = pluginKey => { if (pluginKey === 'Dropdown' || pluginKey === 'Tooltip') { const config = Object.assign(defaultPluginConfig) - config.external.push(bsPlugins.Manipulator, 'popper.js') + config.external.push(bsPlugins.Manipulator, '@popperjs/core') config.globals[bsPlugins.Manipulator] = 'Manipulator' - config.globals['popper.js'] = 'Popper' + config.globals['@popperjs/core'] = 'Popper' return config } @@ -112,11 +118,13 @@ const getConfigByPluginKey = pluginKey => { return { external: [ bsPlugins.Data, + bsPlugins.Base, bsPlugins.EventHandler, bsPlugins.Manipulator ], globals: { [bsPlugins.Data]: 'Data', + [bsPlugins.Base]: 'Base', [bsPlugins.EventHandler]: 'EventHandler', [bsPlugins.Manipulator]: 'Manipulator' } @@ -126,7 +134,8 @@ const getConfigByPluginKey = pluginKey => { const utilObjects = new Set([ 'Util', - 'Sanitizer' + 'Sanitizer', + 'Backdrop' ]) const domObjects = new Set([ diff --git a/build/change-version.js b/build/change-version.js index b8a640fa8..63f231ea2 100644 --- a/build/change-version.js +++ b/build/change-version.js @@ -2,18 +2,28 @@ /*! * Script to update version number references in the project. - * Copyright 2017-2020 The Bootstrap Authors - * Copyright 2017-2020 Twitter, Inc. + * 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') +const fs = require('fs').promises const path = require('path') -const sh = require('shelljs') - -sh.config.fatal = true +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) { @@ -24,89 +34,48 @@ function regExpQuoteReplacement(string) { return string.replace(/\$/g, '$$') } -const DRY_RUN = false +async function replaceRecursively(file, oldVersion, newVersion) { + const originalString = await fs.readFile(file, 'utf8') + const newString = originalString.replace( + new RegExp(regExpQuote(oldVersion), 'g'), regExpQuoteReplacement(newVersion) + ) -function walkAsync(directory, excludedDirectories, fileCallback, errback) { - if (excludedDirectories.has(path.parse(directory).base)) { + // No need to move any further if the strings are identical + if (originalString === newString) { return } - fs.readdir(directory, (err, names) => { - if (err) { - errback(err) - return - } - - names.forEach(name => { - const filepath = path.join(directory, name) - fs.lstat(filepath, (err, stats) => { - if (err) { - process.nextTick(errback, err) - return - } - - if (stats.isDirectory()) { - process.nextTick(walkAsync, filepath, excludedDirectories, fileCallback, errback) - } else if (stats.isFile()) { - process.nextTick(fileCallback, filepath) - } - }) - }) - }) -} + if (VERBOSE) { + console.log(`FILE: ${file}`) + } -function replaceRecursively(directory, excludedDirectories, allowedExtensions, original, replacement) { - original = new RegExp(regExpQuote(original), 'g') - replacement = regExpQuoteReplacement(replacement) - const updateFile = DRY_RUN ? - filepath => { - if (allowedExtensions.has(path.parse(filepath).ext)) { - console.log(`FILE: ${filepath}`) - } else { - console.log(`EXCLUDED:${filepath}`) - } - } : - filepath => { - if (allowedExtensions.has(path.parse(filepath).ext)) { - sh.sed('-i', original, replacement, filepath) - } - } - - walkAsync(directory, excludedDirectories, updateFile, err => { - console.error('ERROR while traversing directory!:') - console.error(err) - process.exit(1) - }) + if (DRY_RUN) { + return + } + + await fs.writeFile(file, newString, 'utf8') } -function main(args) { - if (args.length !== 2) { - console.error('USAGE: change-version old_version new_version') +async function main(args) { + const [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) } - const oldVersion = args[0] - const newVersion = args[1] - const EXCLUDED_DIRS = new Set([ - '.git', - '_gh_pages', - 'node_modules', - 'vendor' - ]) - const INCLUDED_EXTENSIONS = new Set([ - // This extension allowlist is how we avoid modifying binary files - '', - '.css', - '.html', - '.js', - '.json', - '.md', - '.scss', - '.txt', - '.yml' - ]) - replaceRecursively('.', EXCLUDED_DIRS, INCLUDED_EXTENSIONS, oldVersion, newVersion) + // Strip any leading `v` from arguments because otherwise we will end up with duplicate `v`s + [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/generate-sri.js b/build/generate-sri.js index 0c272cead..221873b8f 100644 --- a/build/generate-sri.js +++ b/build/generate-sri.js @@ -5,8 +5,8 @@ * Remember to use the same vendor files as the CDN ones, * otherwise the hashes won't match! * - * Copyright 2017-2020 The Bootstrap Authors - * Copyright 2017-2020 Twitter, Inc. + * Copyright 2017-2021 The Bootstrap Authors + * Copyright 2017-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -42,7 +42,7 @@ const files = [ configPropertyName: 'js_bundle_hash' }, { - file: 'node_modules/popper.js/dist/umd/popper.min.js', + file: 'node_modules/@popperjs/core/dist/umd/popper.min.js', configPropertyName: 'popper_hash' } ] diff --git a/build/rollup.config.js b/build/rollup.config.js index 05579d165..8cecec9aa 100644 --- a/build/rollup.config.js +++ b/build/rollup.config.js @@ -3,13 +3,14 @@ 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 BUNDLE = process.env.BUNDLE === 'true' const ESM = process.env.ESM === 'true' let fileDest = `bootstrap${ESM ? '.esm' : ''}` -const external = ['popper.js'] +const external = ['@popperjs/core'] const plugins = [ babel({ // Only transpile our source code @@ -19,15 +20,21 @@ const plugins = [ }) ] const globals = { - 'popper.js': 'Popper' + '@popperjs/core': 'Popper' } if (BUNDLE) { fileDest += '.bundle' // Remove last entry in external array to bundle Popper external.pop() - delete globals['popper.js'] - plugins.push(nodeResolve()) + delete globals['@popperjs/core'] + plugins.push( + replace({ + 'process.env.NODE_ENV': '"production"', + preventAssignment: true + }), + nodeResolve() + ) } const rollupConfig = { diff --git a/build/ship.sh b/build/ship.sh deleted file mode 100644 index da5a03bcd..000000000 --- a/build/ship.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash - -set -e - -# -# Usage -# --------------- -# 1. Clone second version of Bootstrap in sibling directory named `bs-docs`. -# 2. Within `bs-docs` copy, switch to `gh-pages` branch. -# 3. Pull latest, re-bundle, re-npm. -# 4. Run script. - -red=$'\e[1;31m' -green=$'\e[1;32m' -#blue=$'\e[1;34m' -magenta=$'\e[1;35m' -#cyan=$'\e[1;36m' -end=$'\e[0m' - -# Get current version from package.json -current_version=$(node -p "require('./package.json').version") - -if [[ $# -lt 1 ]]; then - printf "\n%s⚠️ Shipping aborted. You must specify a version.\n%s" "$red" "$end" - exit 1 -fi - -# Pulling latest changes, just to be sure -printf "\n%s=======================================================%s" "$magenta" "$end" -printf "\n%sPulling latest changes...%s" "$magenta" "$end" -printf "\n%s=======================================================\n\n%s" "$magenta" "$end" -git pull origin main - -# Update version number -printf "\n%s=======================================================%s" "$magenta" "$end" -printf "\n%sUpdating version number...%s" "$magenta" "$end" -printf "\n%s=======================================================\n%s" "$magenta" "$end" -npm run release-version "$current_version" "$1" - -# Build release -printf "\n%s=======================================================%s" "$magenta" "$end" -printf "\n%sBuilding release...%s" "$magenta" "$end" -printf "\n%s=======================================================\n%s" "$magenta" "$end" -npm run release - -# Copy the contents of the built docs site over to `bs-docs` repo -printf "\n%s=======================================================%s" "$magenta" "$end" -printf "\n%sCopy it over...%s" "$magenta" "$end" -printf "\n%s=======================================================\n%s" "$magenta" "$end" -cp -rf _gh_pages/. ../bs-docs/ -printf "\nDone!\n" - -printf "\n%s=======================================================%s" "$green" "$end" -printf "\n%sSuccess, $1 is ready to review and publish.%s" "$green" "$end" -printf "\n%s=======================================================\n\n%s" "$green" "$end" diff --git a/build/vnu-jar.js b/build/vnu-jar.js index 90c1a12ab..7a912675e 100644 --- a/build/vnu-jar.js +++ b/build/vnu-jar.js @@ -2,8 +2,8 @@ /*! * Script to run vnu-jar if Java is available. - * Copyright 2017-2020 The Bootstrap Authors - * Copyright 2017-2020 Twitter, Inc. + * Copyright 2017-2021 The Bootstrap Authors + * Copyright 2017-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -42,14 +42,14 @@ childProcess.exec('java -version', (error, stdout, stderr) => { const args = [ '-jar', - vnu, + `"${vnu}"`, '--asciiquotes', '--skip-non-html', // Ignore the language code warnings '--no-langdetect', '--Werror', `--filterpattern "${ignores}"`, - '_gh_pages/', + '_site/', 'js/tests/' ] diff --git a/build/zip-examples.js b/build/zip-examples.js index bf50a0af6..312548e8a 100644 --- a/build/zip-examples.js +++ b/build/zip-examples.js @@ -3,7 +3,7 @@ /*! * Script to create the built examples zip archive; * requires the `zip` command to be present! - * Copyright 2020 The Bootstrap Authors + * Copyright 2020-2021 The Bootstrap Authors * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -12,36 +12,67 @@ const path = require('path') const sh = require('shelljs') -const { version, version_short: versionShort } = require('../package.json') +const pkg = require('../package.json') -const folderName = `bootstrap-${version}-examples` +const versionShort = pkg.config.version_short +const distFolder = `bootstrap-${pkg.version}-examples` +const rootDocsDir = '_site' +const docsDir = `${rootDocsDir}/docs/${versionShort}/` + +// these are the files we need in the examples +const cssFiles = [ + 'bootstrap.min.css', + 'bootstrap.min.css.map', + 'bootstrap.rtl.min.css', + 'bootstrap.rtl.min.css.map' +] +const jsFiles = [ + 'bootstrap.bundle.min.js', + 'bootstrap.bundle.min.js.map' +] +const imgFiles = [ + 'bootstrap-logo.svg', + 'bootstrap-logo-white.svg' +] sh.config.fatal = true -if (!sh.test('-d', '_gh_pages')) { - throw new Error('The "_gh_pages" folder does not exist, did you forget building the docs?') +if (!sh.test('-d', rootDocsDir)) { + throw new Error(`The "${rootDocsDir}" folder does not exist, did you forget building the docs?`) } // switch to the root dir sh.cd(path.join(__dirname, '..')) -// remove any previously created folder with the same name -sh.rm('-rf', folderName) +// remove any previously created folder/zip with the same name +sh.rm('-rf', [distFolder, `${distFolder}.zip`]) + // create any folders so that `cp` works -sh.mkdir('-p', folderName) -sh.mkdir('-p', `${folderName}/assets/brand/`) - -sh.cp('-Rf', `_gh_pages/docs/${versionShort}/examples/*`, folderName) -sh.cp('-Rf', `_gh_pages/docs/${versionShort}/dist/`, `${folderName}/assets/`) -// also copy the two brand images we use in the examples -sh.cp('-f', [ - `_gh_pages/docs/${versionShort}/assets/brand/bootstrap-logo.svg`, - `_gh_pages/docs/${versionShort}/assets/brand/bootstrap-logo-white.svg` -], `${folderName}/assets/brand/`) -sh.rm(`${folderName}/index.html`) +sh.mkdir('-p', [ + distFolder, + `${distFolder}/assets/brand/`, + `${distFolder}/assets/dist/css/`, + `${distFolder}/assets/dist/js/` +]) + +sh.cp('-Rf', `${docsDir}/examples/*`, distFolder) + +cssFiles.forEach(file => { + sh.cp('-f', `${docsDir}/dist/css/${file}`, `${distFolder}/assets/dist/css/`) +}) + +jsFiles.forEach(file => { + sh.cp('-f', `${docsDir}/dist/js/${file}`, `${distFolder}/assets/dist/js/`) +}) + +imgFiles.forEach(file => { + sh.cp('-f', `${docsDir}/assets/brand/${file}`, `${distFolder}/assets/brand/`) +}) + +sh.rm(`${distFolder}/index.html`) // get all examples' HTML files -sh.find(`${folderName}/**/*.html`).forEach(file => { +sh.find(`${distFolder}/**/*.html`).forEach(file => { const fileContents = sh.cat(file) .toString() .replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../') @@ -53,7 +84,7 @@ sh.find(`${folderName}/**/*.html`).forEach(file => { }) // create the zip file -sh.exec(`zip -r9 "${folderName}.zip" "${folderName}"`, { fatal: true }) +sh.exec(`zip -r9 "${distFolder}.zip" "${distFolder}"`) // remove the folder we created -sh.rm('-rf', folderName) +sh.rm('-rf', distFolder) |
