Migrate from ParcelJS to esbuild for UI bundling

This commit is contained in:
checktheroads 2021-07-24 00:00:38 -07:00
parent cb804eb3e1
commit 0572d03003
39 changed files with 230 additions and 4917 deletions

View File

@ -0,0 +1,3 @@
dist
node_modules
.cache

View File

@ -1 +1,3 @@
dist dist
node_modules
.cache

View File

@ -17,9 +17,9 @@ TypeScript is a strict static-typed superset of JavaScript. In development, it's
### Tools ### Tools
#### [ParcelJS](https://parceljs.org/) #### [esbuild](https://esbuild.github.io/)
Parcel is a bundling tool that takes given input files of most front-end languages (Sass and TypeScript, in our case), follows each of their dependencies (via import statements), and bundles them into a single minified file. esbuild is a bundling tool that takes given input files of most front-end languages (Sass and TypeScript, in our case), follows each of their dependencies (via import statements), and bundles them into a single minified file.
For JavaScript, every `.ts` file in `netbox/project-static/src` is: For JavaScript, every `.ts` file in `netbox/project-static/src` is:
@ -33,7 +33,7 @@ Likewise, with Sass, every `.scss` file in `netbox/project-static/styles` is:
2. Minified 2. Minified
3. Combined into a single output file at `netbox/project-static/dist/netbox.css` (this includes any dependant libraries imported in file) 3. Combined into a single output file at `netbox/project-static/dist/netbox.css` (this includes any dependant libraries imported in file)
For pre v3 releases, this process will be run in development, and the files in `netbox/project-static/dist` checked into change control. This is because running Parcel (and installing dependencies via NPM/Yarn, as described below) requires other system dependencies like NodeJS and Yarn, which aren't part of the current v2 dependency list. For pre v4 releases, this process will be run in development, and the files in `netbox/project-static/dist` checked into change control. This is because running Parcel (and installing dependencies via NPM/Yarn, as described below) requires other system dependencies like NodeJS and Yarn, which aren't part of the current v2 dependency list.
#### [Yarn](https://yarnpkg.com/) #### [Yarn](https://yarnpkg.com/)
@ -65,14 +65,14 @@ To bundle only CSS files, run:
```bash ```bash
# netbox/project-static # netbox/project-static
yarn bundle --styles yarn bundle:styles
``` ```
To bundle only JS files, run: To bundle only JS files, run:
```bash ```bash
# netbox/project-static # netbox/project-static
yarn bundle --scripts yarn bundle:scripts
``` ```
Or, to bundle both, run: Or, to bundle both, run:

View File

@ -1,66 +1,84 @@
/** const esbuild = require('esbuild');
* ParcelJS Bundle Configuration. const { sassPlugin } = require('esbuild-sass-plugin');
*
* @see https://parceljs.org/api.html
*/
const Bundler = require('parcel-bundler');
// Bundler options common to all bundle jobs. // Bundler options common to all bundle jobs.
const options = { const options = {
logLevel: 2, outdir: './dist',
cache: true, bundle: true,
watch: false,
minify: true, minify: true,
outDir: './dist', sourcemap: true,
publicUrl: '/static', logLevel: 'error',
publicPath: '/static',
}; };
// Get CLI arguments for optional overrides. // Get CLI arguments for optional overrides.
const args = process.argv.slice(2); const ARGS = process.argv.slice(2);
// Allow cache disabling.
if (args.includes('--no-cache')) {
options.cache = false;
}
// Style (SCSS) bundle jobs. Generally, everything should be bundled into netbox.css from main.scss
// unless there is a specific reason to do otherwise.
const styles = [
['styles/_external.scss', 'netbox-external.css'],
['styles/_light.scss', 'netbox-light.css'],
['styles/_dark.scss', 'netbox-dark.css'],
['styles/_rack_elevations.scss', 'rack_elevation.css'],
['styles/_cable_trace.scss', 'cable_trace.css'],
];
// Script (JavaScript) bundle jobs. Generally, everything should be bundled into netbox.js from
// index.ts unless there is a specific reason to do otherwise.
const scripts = [
['src/index.ts', 'netbox.js'],
['src/jobs.ts', 'jobs.js'],
['src/device/lldp.ts', 'lldp.js'],
['src/device/config.ts', 'config.js'],
['src/device/status.ts', 'status.js'],
];
/**
* Run style bundle jobs.
*/
async function bundleStyles() {
for (const [input, outFile] of styles) {
const instance = new Bundler(input, { outFile, ...options });
await instance.bundle();
}
}
/** /**
* Run script bundle jobs. * Run script bundle jobs.
*/ */
async function bundleScripts() { async function bundleScripts() {
for (const [input, outFile] of scripts) { const entryPoints = {
const instance = new Bundler(input, { outFile, ...options }); netbox: 'src/index.ts',
await instance.bundle(); jobs: 'src/jobs.ts',
lldp: 'src/device/lldp.ts',
config: 'src/device/config.ts',
status: 'src/device/status.ts',
};
try {
let result = await esbuild.build({
...options,
entryPoints,
target: 'es2016',
});
if (result.errors.length === 0) {
for (const [targetName, sourceName] of Object.entries(entryPoints)) {
const source = sourceName.split('/')[1];
console.log(`✅ Bundled source file '${source}' to '${targetName}.js'`);
}
}
} catch (err) {
console.error(err);
}
}
/**
* Run style bundle jobs.
*/
async function bundleStyles() {
try {
const entryPoints = {
'netbox-external': 'styles/_external.scss',
'netbox-light': 'styles/_light.scss',
'netbox-dark': 'styles/_dark.scss',
rack_elevations: 'styles/_rack_elevations.scss',
cable_trace: 'styles/_cable_trace.scss',
};
const pluginOptions = { outputStyle: 'compressed' };
// Allow cache disabling.
if (ARGS.includes('--no-cache')) {
pluginOptions.cache = false;
}
let result = await esbuild.build({
...options,
entryPoints,
plugins: [sassPlugin(pluginOptions)],
loader: {
'.eot': 'file',
'.woff': 'file',
'.woff2': 'file',
'.svg': 'file',
'.ttf': 'file',
},
});
if (result.errors.length === 0) {
for (const [targetName, sourceName] of Object.entries(entryPoints)) {
const source = sourceName.split('/')[1];
console.log(`✅ Bundled source file '${source}' to '${targetName}.css'`);
}
}
} catch (err) {
console.error(err);
} }
} }
@ -68,10 +86,10 @@ async function bundleScripts() {
* Run all bundle jobs. * Run all bundle jobs.
*/ */
async function bundleAll() { async function bundleAll() {
if (args.includes('--styles')) { if (ARGS.includes('--styles')) {
// Only run style jobs. // Only run style jobs.
return await bundleStyles(); return await bundleStyles();
} else if (args.includes('--scripts')) { } else if (ARGS.includes('--scripts')) {
// Only run script jobs. // Only run script jobs.
return await bundleScripts(); return await bundleScripts();
} }

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -5,6 +5,8 @@
"license": "Apache-2.0", "license": "Apache-2.0",
"scripts": { "scripts": {
"bundle": "node bundle.js", "bundle": "node bundle.js",
"bundle:styles": "node bundle.js --styles",
"bundle:scripts": "node bundle.js --scripts",
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
@ -15,30 +17,23 @@
"color2k": "^1.2.4", "color2k": "^1.2.4",
"cookie": "^0.4.1", "cookie": "^0.4.1",
"dayjs": "^1.10.4", "dayjs": "^1.10.4",
"esbuild": "^0.12.15",
"esbuild-sass-plugin": "^1.4.8",
"flatpickr": "4.6.3", "flatpickr": "4.6.3",
"just-debounce-it": "^1.4.0", "just-debounce-it": "^1.4.0",
"masonry-layout": "^4.2.2", "masonry-layout": "^4.2.2",
"parcel-bundler": "1.12.3",
"query-string": "^6.14.1", "query-string": "^6.14.1",
"sass": "^1.32.8", "sass": "^1.32.8",
"simplebar": "^5.3.4", "simplebar": "^5.3.4",
"slim-select": "^1.27.0" "slim-select": "^1.27.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.0.0-0",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8",
"@babel/plugin-proposal-object-rest-spread": "^7.13.8",
"@babel/plugin-proposal-optional-chaining": "^7.13.8",
"@babel/preset-env": "^7.13.9",
"@babel/preset-typescript": "^7.13.0",
"@types/bootstrap": "^5.0.12", "@types/bootstrap": "^5.0.12",
"@types/clipboard": "^2.0.1", "@types/clipboard": "^2.0.1",
"@types/cookie": "^0.4.0", "@types/cookie": "^0.4.0",
"@types/masonry-layout": "^4.2.2", "@types/masonry-layout": "^4.2.2",
"@typescript-eslint/eslint-plugin": "^4.17.0", "@typescript-eslint/eslint-plugin": "^4.17.0",
"@typescript-eslint/parser": "^4.17.0", "@typescript-eslint/parser": "^4.17.0",
"babel-polyfill": "^6.26.0",
"eslint": "^7.22.0", "eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0", "eslint-config-prettier": "^8.1.0",
"eslint-import-resolver-typescript": "^2.4.0", "eslint-import-resolver-typescript": "^2.4.0",
@ -47,19 +42,5 @@
"prettier": "^2.2.1", "prettier": "^2.2.1",
"prettier-eslint": "^12.0.0", "prettier-eslint": "^12.0.0",
"typescript": "^4.2.3" "typescript": "^4.2.3"
}, }
"babel": {
"presets": [
"@babel/env",
"@babel/typescript"
],
"plugins": [
"@babel/plugin-proposal-optional-chaining",
"@babel/proposal-class-properties",
"@babel/plugin-proposal-nullish-coalescing-operator"
]
},
"browserslist": [
"defaults"
]
} }

View File

@ -1,4 +1,3 @@
import 'babel-polyfill';
import '@popperjs/core'; import '@popperjs/core';
import 'bootstrap'; import 'bootstrap';
import 'simplebar'; import 'simplebar';

View File

@ -1,4 +1,4 @@
// Entry for all 3rd party library imports that do not rely on Bootstrap or NetBox styles. // Entry for all 3rd party library imports that do not rely on Bootstrap or NetBox styles.
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
@import '@mdi/font/css/materialdesignicons.min.css'; @import '../node_modules/@mdi/font/css/materialdesignicons.min.css';
@import 'flatpickr/dist/flatpickr.css'; @import '../node_modules/flatpickr/dist/flatpickr.css';

View File

@ -1,34 +1,34 @@
// Import the rest of bootstrap. // Import the rest of bootstrap.
@import 'bootstrap/scss/utilities'; @import '../node_modules/bootstrap/scss/utilities';
@import 'bootstrap/scss/mixins'; @import '../node_modules/bootstrap/scss/mixins';
@import 'bootstrap/scss/root'; @import '../node_modules/bootstrap/scss/root';
@import 'bootstrap/scss/reboot'; @import '../node_modules/bootstrap/scss/reboot';
@import 'bootstrap/scss/type'; @import '../node_modules/bootstrap/scss/type';
@import 'bootstrap/scss/images'; @import '../node_modules/bootstrap/scss/images';
@import 'bootstrap/scss/containers'; @import '../node_modules/bootstrap/scss/containers';
@import 'bootstrap/scss/grid'; @import '../node_modules/bootstrap/scss/grid';
@import 'bootstrap/scss/tables'; @import '../node_modules/bootstrap/scss/tables';
@import 'bootstrap/scss/forms'; @import '../node_modules/bootstrap/scss/forms';
@import 'bootstrap/scss/buttons'; @import '../node_modules/bootstrap/scss/buttons';
@import 'bootstrap/scss/transitions'; @import '../node_modules/bootstrap/scss/transitions';
@import 'bootstrap/scss/dropdown'; @import '../node_modules/bootstrap/scss/dropdown';
@import 'bootstrap/scss/button-group'; @import '../node_modules/bootstrap/scss/button-group';
@import 'bootstrap/scss/nav'; @import '../node_modules/bootstrap/scss/nav';
@import 'bootstrap/scss/navbar'; @import '../node_modules/bootstrap/scss/navbar';
@import 'bootstrap/scss/card'; @import '../node_modules/bootstrap/scss/card';
@import 'bootstrap/scss/accordion'; @import '../node_modules/bootstrap/scss/accordion';
@import 'bootstrap/scss/breadcrumb'; @import '../node_modules/bootstrap/scss/breadcrumb';
@import 'bootstrap/scss/pagination'; @import '../node_modules/bootstrap/scss/pagination';
@import 'bootstrap/scss/badge'; @import '../node_modules/bootstrap/scss/badge';
@import 'bootstrap/scss/alert'; @import '../node_modules/bootstrap/scss/alert';
@import 'bootstrap/scss/progress'; @import '../node_modules/bootstrap/scss/progress';
@import 'bootstrap/scss/list-group'; @import '../node_modules/bootstrap/scss/list-group';
@import 'bootstrap/scss/close'; @import '../node_modules/bootstrap/scss/close';
@import 'bootstrap/scss/toasts'; @import '../node_modules/bootstrap/scss/toasts';
@import 'bootstrap/scss/modal'; @import '../node_modules/bootstrap/scss/modal';
@import 'bootstrap/scss/tooltip'; @import '../node_modules/bootstrap/scss/tooltip';
@import 'bootstrap/scss/popover'; @import '../node_modules/bootstrap/scss/popover';
@import 'bootstrap/scss/carousel'; @import '../node_modules/bootstrap/scss/carousel';
@import 'bootstrap/scss/spinners'; @import '../node_modules/bootstrap/scss/spinners';
@import 'bootstrap/scss/helpers'; @import '../node_modules/bootstrap/scss/helpers';
@import 'bootstrap/scss/utilities/api'; @import '../node_modules/bootstrap/scss/utilities/api';

View File

@ -1,6 +1,6 @@
// Base NetBox Theme Overrides and Settings - color mode agnostic. // Base NetBox Theme Overrides and Settings - color mode agnostic.
@import 'bootstrap/scss/functions'; @import '../node_modules/bootstrap/scss/functions';
$card-cap-bg: 'unset'; $card-cap-bg: 'unset';
@ -31,7 +31,7 @@ $line-height-lg: 1.75;
$darker: #1b1f22; $darker: #1b1f22;
$darkest: #171b1d; $darkest: #171b1d;
@import 'bootstrap/scss/variables'; @import '../node_modules/bootstrap/scss/variables';
// Make color palette colors available as theme colors. // Make color palette colors available as theme colors.
// For example, you could use `.bg-red-100`, if needed. // For example, you could use `.bg-red-100`, if needed.

File diff suppressed because it is too large Load Diff