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
node_modules
.cache

View File

@ -17,9 +17,9 @@ TypeScript is a strict static-typed superset of JavaScript. In development, it's
### 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:
@ -33,7 +33,7 @@ Likewise, with Sass, every `.scss` file in `netbox/project-static/styles` is:
2. Minified
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/)
@ -65,14 +65,14 @@ To bundle only CSS files, run:
```bash
# netbox/project-static
yarn bundle --styles
yarn bundle:styles
```
To bundle only JS files, run:
```bash
# netbox/project-static
yarn bundle --scripts
yarn bundle:scripts
```
Or, to bundle both, run:

View File

@ -1,66 +1,84 @@
/**
* ParcelJS Bundle Configuration.
*
* @see https://parceljs.org/api.html
*/
const Bundler = require('parcel-bundler');
const esbuild = require('esbuild');
const { sassPlugin } = require('esbuild-sass-plugin');
// Bundler options common to all bundle jobs.
const options = {
logLevel: 2,
cache: true,
watch: false,
outdir: './dist',
bundle: true,
minify: true,
outDir: './dist',
publicUrl: '/static',
sourcemap: true,
logLevel: 'error',
publicPath: '/static',
};
// Get CLI arguments for optional overrides.
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();
}
}
const ARGS = process.argv.slice(2);
/**
* Run script bundle jobs.
*/
async function bundleScripts() {
for (const [input, outFile] of scripts) {
const instance = new Bundler(input, { outFile, ...options });
await instance.bundle();
const entryPoints = {
netbox: 'src/index.ts',
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.
*/
async function bundleAll() {
if (args.includes('--styles')) {
if (ARGS.includes('--styles')) {
// Only run style jobs.
return await bundleStyles();
} else if (args.includes('--scripts')) {
} else if (ARGS.includes('--scripts')) {
// Only run script jobs.
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",
"scripts": {
"bundle": "node bundle.js",
"bundle:styles": "node bundle.js --styles",
"bundle:scripts": "node bundle.js --scripts",
"typecheck": "tsc --noEmit"
},
"dependencies": {
@ -15,30 +17,23 @@
"color2k": "^1.2.4",
"cookie": "^0.4.1",
"dayjs": "^1.10.4",
"esbuild": "^0.12.15",
"esbuild-sass-plugin": "^1.4.8",
"flatpickr": "4.6.3",
"just-debounce-it": "^1.4.0",
"masonry-layout": "^4.2.2",
"parcel-bundler": "1.12.3",
"query-string": "^6.14.1",
"sass": "^1.32.8",
"simplebar": "^5.3.4",
"slim-select": "^1.27.0"
},
"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/clipboard": "^2.0.1",
"@types/cookie": "^0.4.0",
"@types/masonry-layout": "^4.2.2",
"@typescript-eslint/eslint-plugin": "^4.17.0",
"@typescript-eslint/parser": "^4.17.0",
"babel-polyfill": "^6.26.0",
"eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0",
"eslint-import-resolver-typescript": "^2.4.0",
@ -47,19 +42,5 @@
"prettier": "^2.2.1",
"prettier-eslint": "^12.0.0",
"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 'bootstrap';
import 'simplebar';

View File

@ -1,4 +1,4 @@
// 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 '@mdi/font/css/materialdesignicons.min.css';
@import 'flatpickr/dist/flatpickr.css';
@import '../node_modules/@mdi/font/css/materialdesignicons.min.css';
@import '../node_modules/flatpickr/dist/flatpickr.css';

View File

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

View File

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

File diff suppressed because it is too large Load Diff