const esbuild = require('esbuild'); const { sassPlugin } = require('esbuild-sass-plugin'); const util = require('util'); const fs = require('fs'); const copyFilePromise = util.promisify(fs.copyFile); // Bundler options common to all bundle jobs. const options = { outdir: './dist', bundle: true, minify: true, sourcemap: 'external', sourcesContent: false, logLevel: 'error', }; // Get CLI arguments for optional overrides. const ARGS = process.argv.slice(2); function copyFiles(files) { return Promise.all(files.map(f => { return copyFilePromise(f.source, f.dest); })); } async function bundleGraphIQL() { let fileMap = [ { source: './node_modules/react/umd/react.production.min.js', dest: './dist/graphiql/react.production.min.js' }, { source: './node_modules/react-dom/umd/react-dom.production.min.js', dest: './dist/graphiql/react-dom.production.min.js' }, { source: './node_modules/js-cookie/dist/js.cookie.min.js', dest: './dist/graphiql/js.cookie.min.js' }, { source: './node_modules/graphiql/graphiql.min.js', dest: './dist/graphiql/graphiql.min.js' }, { source: './node_modules/@graphiql/plugin-explorer/dist/index.umd.js', dest: './dist/graphiql/index.umd.js' }, { source: './node_modules/graphiql/graphiql.min.css', dest: './dist/graphiql/graphiql.min.css' }, { source: './node_modules/@graphiql/plugin-explorer/dist/style.css', dest: './dist/graphiql/plugin-explorer-style.css' } ]; try { if (!fs.existsSync('./dist/graphiql/')) { fs.mkdirSync('./dist/graphiql/'); } } catch (err) { console.error(err); } copyFiles(fileMap).then(() => { console.log('✅ Copied graphiql files'); }).catch(err => { console.error(err); }); } /** * Bundle Core NetBox JavaScript. */ async function bundleNetBox() { const entryPoints = { netbox: 'src/index.ts', }; try { const 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 script bundle jobs. */ async function bundleScripts() { for (const bundle of [bundleNetBox, bundleGraphIQL]) { await bundle(); } } /** * Run style bundle jobs. */ async function bundleStyles() { try { const entryPoints = { 'netbox-external': 'styles/external.scss', 'netbox': 'styles/netbox.scss', rack_elevation: 'styles/svg/rack_elevation.scss', cable_trace: 'styles/svg/cable_trace.scss', }; const pluginOptions = { outputStyle: 'compressed' }; // Allow cache disabling. if (ARGS.includes('--no-cache')) { pluginOptions.cache = false; } let result = await esbuild.build({ ...options, // Disable sourcemaps for CSS/SCSS files, see #7068 sourcemap: false, 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)) { console.log(`✅ Bundled source file '${sourceName}' to '${targetName}.css'`); } } } catch (err) { console.error(err); } } /** * Run all bundle jobs. */ async function bundleAll() { if (ARGS.includes('--styles')) { // Only run style jobs. return await bundleStyles(); } else if (ARGS.includes('--scripts')) { // Only run script jobs. return await bundleScripts(); } await bundleStyles(); await bundleScripts(); } bundleAll();