130 lines
3.9 KiB
JavaScript
130 lines
3.9 KiB
JavaScript
const esbuild = require("esbuild");
|
|
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
|
|
const production = process.argv.includes("--production");
|
|
const watch = process.argv.includes("--watch");
|
|
|
|
/**
|
|
* Needed by `syncCommandsPlugin`, which evaluates the commands, because `vscode` is not
|
|
* a real package. `vscode` imports only make sense in the extension host context. We can't
|
|
* just do `external: ["vscode"]` because we aren't bundling the extension in its host context.
|
|
*
|
|
* @type {import("esbuild").Plugin}
|
|
*/
|
|
const vscodeStubPlugin = {
|
|
name: "stub-vscode",
|
|
|
|
setup(build) {
|
|
build.onResolve({ filter: /^vscode$/ }, (args) => ({ path: args.path, namespace: "vscode-stub" }));
|
|
build.onLoad({ filter: /.*/, namespace: "vscode-stub" }, () => ({
|
|
loader: "js",
|
|
contents: `
|
|
function stub() {
|
|
return new Proxy(function () {}, { get: stub, apply: stub, construct: stub });
|
|
}
|
|
module.exports = stub();
|
|
`,
|
|
}));
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Rewrites package.json's `contributes.commands` based on `src/commands/index.ts`, to
|
|
* have a single source of truth.
|
|
*
|
|
* @type {import("esbuild").Plugin}
|
|
*/
|
|
const syncCommandsPlugin = {
|
|
name: "sync-commands",
|
|
|
|
setup(build) {
|
|
build.onStart(async () => {
|
|
const packageJsonPath = path.join(__dirname, "package.json");
|
|
|
|
const result = await esbuild.build({
|
|
entryPoints: [path.join(__dirname, "src/commands/index.ts")],
|
|
bundle: true,
|
|
write: false,
|
|
format: "cjs",
|
|
platform: "node",
|
|
logLevel: "silent",
|
|
plugins: [vscodeStubPlugin],
|
|
});
|
|
|
|
// any command file has `export default defineCommand`
|
|
const mod = { exports: {} };
|
|
const runModule = new Function("module", "exports", result.outputFiles[0].text);
|
|
runModule(mod, mod.exports);
|
|
const { commands } = mod.exports;
|
|
|
|
const currentJSON = fs.readFileSync(packageJsonPath, "utf8");
|
|
const package = JSON.parse(currentJSON);
|
|
package.contributes ??= {};
|
|
package.contributes.commands = commands
|
|
.map(({ id, title }) => ({
|
|
command: `tatr-vsc.${id}`,
|
|
title,
|
|
}));
|
|
const newJSON = `${JSON.stringify(package, null, 2)}\n`;
|
|
|
|
if (newJSON !== currentJSON) {
|
|
fs.writeFileSync(packageJsonPath, newJSON);
|
|
console.log("Updated package.json contributes.commands.");
|
|
}
|
|
});
|
|
},
|
|
};
|
|
|
|
/**
|
|
* @type {import("esbuild").Plugin}
|
|
*/
|
|
const esbuildProblemMatcherPlugin = {
|
|
name: "esbuild-problem-matcher",
|
|
|
|
setup(build) {
|
|
build.onStart(() => {
|
|
console.log("[watch] build started");
|
|
});
|
|
build.onEnd((result) => {
|
|
result.errors.forEach(({ text, location }) => {
|
|
console.error(`✘ [ERROR] ${text}`);
|
|
console.error(` ${location.file}:${location.line}:${location.column}:`);
|
|
});
|
|
console.log("[watch] build finished");
|
|
});
|
|
},
|
|
};
|
|
|
|
async function main() {
|
|
const ctx = await esbuild.context({
|
|
entryPoints: [
|
|
"src/extension.ts"
|
|
],
|
|
bundle: true,
|
|
format: "cjs",
|
|
minify: production,
|
|
sourcemap: !production,
|
|
sourcesContent: false,
|
|
platform: "node",
|
|
outfile: "dist/extension.js",
|
|
external: ["vscode"],
|
|
logLevel: "silent",
|
|
plugins: [
|
|
syncCommandsPlugin,
|
|
esbuildProblemMatcherPlugin,
|
|
],
|
|
});
|
|
if (watch) {
|
|
await ctx.watch();
|
|
} else {
|
|
await ctx.rebuild();
|
|
await ctx.dispose();
|
|
}
|
|
}
|
|
|
|
main().catch(e => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
});
|