yavsc/esbuild.config.mjs

113 lines
3.6 KiB
JavaScript
Raw Normal View History

// Yavsc front-end bundle config (esbuild).
//
// Produces a single minified bundle at
// src/Yavsc.Org/wwwroot/js/site.bundle.min.js
// that contains both our application code and the third-party libs we
// keep under npm. The bundle is committed to the repo so the .NET
// runtime does not need a node toolchain at publish time.
//
// Usage:
// npm install
// npm run build:js # one-shot
// npm run build:js:watch # rebuild on change
// npm run clean:js # remove the generated bundle
import { build, context } from 'esbuild';
import { existsSync, mkdirSync, statSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const isWatch = process.argv.includes('--watch');
const outFile = path.resolve(
__dirname,
'src/Yavsc.Org/wwwroot/js/site.bundle.min.js'
);
const outDir = path.dirname(outFile);
if (!existsSync(outDir)) {
mkdirSync(outDir, { recursive: true });
}
// --- Our code (entry points) --------------------------------------------
// `site.js` is the bootstrap loaded by _Layout.cshtml. We list every
// .js we own as an entry point so they all end up in the same bundle.
const ourEntries = [
'src/Yavsc.Org/wwwroot/js/site.js',
'src/Yavsc.Org/wwwroot/js/chat.js',
'src/Yavsc.Org/wwwroot/js/comment.js',
'src/Yavsc.Org/wwwroot/js/signout-redirect.js',
'src/Yavsc.Org/wwwroot/js/input-lib.js',
'src/Yavsc.Org/wwwroot/js/google-geoloc.js',
'src/Yavsc.Org/wwwroot/js/audiovideoinput.js',
'src/Yavsc.Org/wwwroot/js/yavsc-remote-fs.js',
];
// --- Third-party code we want bundled ----------------------------------
// Listed by npm package name; resolved via node_modules.
// jQuery, jQuery UI, jQuery plugins, Bootstrap JS bundle, SignalR
// (browser), Moment, Quill, Showdown, To-markdown, Dropzone.
const vendorEntries = [
'jquery/dist/jquery.min.js',
'jquery-ui/dist/jquery-ui.min.js',
'jquery-validation/dist/jquery.validate.min.js',
'jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js',
'jquery-timepicker/jquery.timepicker.min.js',
'jquery-datepair/dist/jquery.datepair.min.js',
'bootstrap/dist/js/bootstrap.bundle.min.js',
'@microsoft/signalr/dist/browser/signalr.min.js',
'moment/min/moment.min.js',
'showdown/dist/showdown.min.js',
'to-markdown/dist/to-markdown.min.js',
'dropzone/dist/min/dropzone.min.js',
'quill/dist/quill.min.js',
// eonasdan is registered as a CommonJS package; esbuild handles it.
'eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js',
];
// Our entry points may live alongside the output, so we exclude the
// outDir from the resolver to avoid bundling the previous run.
const entryPoints = [...ourEntries, ...vendorEntries];
const buildOptions = {
entryPoints,
outFile,
bundle: true,
minify: true,
sourcemap: false,
target: ['es2018'],
format: 'iife',
legalComments: 'none',
logLevel: 'info',
// jQuery plugins attach themselves to jQuery; we must not shim it.
alias: {},
nodePaths: ['node_modules'],
loader: {
'.js': 'js',
},
};
async function run() {
if (isWatch) {
const ctx = await context(buildOptions);
await ctx.watch();
console.log(`[esbuild] watching → ${path.relative(__dirname, outFile)}`);
} else {
const result = await build(buildOptions);
if (result.errors.length) {
process.exitCode = 1;
} else {
const size = statSync(outFile).size;
console.log(
`[esbuild] wrote ${path.relative(__dirname, outFile)} (${size} bytes)`
);
}
}
}
run().catch((err) => {
console.error(err);
process.exit(1);
});