diff options
Diffstat (limited to 'scripts/build')
-rwxr-xr-x | scripts/build/build.mjs | 53 | ||||
-rw-r--r-- | scripts/build/buildWeb.mjs | 61 | ||||
-rw-r--r-- | scripts/build/common.mjs | 80 |
3 files changed, 194 insertions, 0 deletions
diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs new file mode 100755 index 0000000..281246a --- /dev/null +++ b/scripts/build/build.mjs @@ -0,0 +1,53 @@ +#!/usr/bin/node +import esbuild from "esbuild"; +import { commonOpts, gitHashPlugin, globPlugins, makeAllPackagesExternalPlugin } from "./common.mjs"; + +/** + * @type {esbuild.BuildOptions} + */ +const nodeCommonOpts = { + ...commonOpts, + format: "cjs", + platform: "node", + target: ["esnext"], + sourcemap: "linked", + plugins: [makeAllPackagesExternalPlugin], +}; + +await Promise.all([ + esbuild.build({ + ...nodeCommonOpts, + entryPoints: ["src/preload.ts"], + outfile: "dist/preload.js", + }), + esbuild.build({ + ...nodeCommonOpts, + entryPoints: ["src/patcher.ts"], + outfile: "dist/patcher.js", + }), + esbuild.build({ + ...commonOpts, + entryPoints: ["src/Vencord.ts"], + outfile: "dist/renderer.js", + format: "iife", + target: ["esnext"], + footer: { js: "//# sourceURL=VencordRenderer" }, + globalName: "Vencord", + external: ["plugins", "git-hash"], + plugins: [ + globPlugins, + gitHashPlugin + ], + sourcemap: "inline", + minify: true, + define: { + IS_WEB: "false" + } + }), +]).catch(err => { + console.error("Build failed"); + console.error(err.message); + // make ci fail + if (!watch) + process.exitCode = 1; +}); diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs new file mode 100644 index 0000000..dd8cb5d --- /dev/null +++ b/scripts/build/buildWeb.mjs @@ -0,0 +1,61 @@ +// TODO: Modularise the plugins since both build scripts use them + +import { createWriteStream, readFileSync } from "fs"; +import yazl from "yazl"; +import esbuild from "esbuild"; +// wtf is this assert syntax +import PackageJSON from "../../package.json" assert { type: "json" }; +import { commonOpts, gitHashPlugin, globPlugins } from "./common.mjs"; + +/** + * @type {esbuild.BuildOptions} + */ +const commonOptions = { + ...commonOpts, + entryPoints: ["browser/Vencord.ts"], + globalName: "Vencord", + format: "iife", + minify: true, + sourcemap: false, + external: ["plugins", "git-hash"], + plugins: [ + globPlugins, + gitHashPlugin + ], + target: ["esnext"], + define: { + IS_WEB: "true" + } +}; + +await Promise.all( + [ + esbuild.build({ + ...commonOptions, + outfile: "dist/browser.js", + footer: { js: "//# sourceURL=VencordWeb" }, + }), + esbuild.build({ + ...commonOptions, + outfile: "dist/Vencord.user.js", + banner: { + js: readFileSync("browser/userscript.meta.js", "utf-8").replace("%version%", PackageJSON.version) + }, + footer: { + // UserScripts get wrapped in an iife, so define Vencord prop on window that returns our local + js: "Object.defineProperty(window,'Vencord',{get:()=>Vencord});" + }, + }) + ] +); + +const zip = new yazl.ZipFile(); +zip.outputStream.pipe(createWriteStream("dist/extension.zip")).on("close", () => { + console.info("Extension written to dist/extension.zip"); +}); + +zip.addFile("dist/browser.js", "dist/Vencord.js"); +["background.js", "content.js", "manifest.json"].forEach(f => { + zip.addFile(`browser/${f}`, `${f}`); +}); +zip.end(); diff --git a/scripts/build/common.mjs b/scripts/build/common.mjs new file mode 100644 index 0000000..d9b2878 --- /dev/null +++ b/scripts/build/common.mjs @@ -0,0 +1,80 @@ +import { execSync } from "child_process"; +import esbuild from "esbuild"; +import { readdir } from "fs/promises"; + +/** + * @type {esbuild.WatchMode|false} + */ +export const watch = process.argv.includes("--watch"); + +/** + * @type {esbuild.BuildOptions} + */ +export const commonOpts = { + logLevel: "info", + bundle: true, + watch +}; + +// https://github.com/evanw/esbuild/issues/619#issuecomment-751995294 +/** + * @type {esbuild.Plugin} + */ +export const makeAllPackagesExternalPlugin = { + name: "make-all-packages-external", + setup(build) { + let filter = /^[^.\/]|^\.[^.\/]|^\.\.[^\/]/; // Must not start with "/" or "./" or "../" + build.onResolve({ filter }, args => ({ path: args.path, external: true })); + }, +}; + +/** + * @type {esbuild.Plugin} + */ +export const globPlugins = { + name: "glob-plugins", + setup: build => { + build.onResolve({ filter: /^plugins$/ }, args => { + return { + namespace: "import-plugins", + path: args.path + }; + }); + + build.onLoad({ filter: /^plugins$/, namespace: "import-plugins" }, async () => { + const files = await readdir("./src/plugins"); + let code = ""; + let plugins = "\n"; + for (let i = 0; i < files.length; i++) { + if (files[i] === "index.ts") { + continue; + } + const mod = `p${i}`; + code += `import ${mod} from "./${files[i].replace(/.tsx?$/, "")}";\n`; + plugins += `[${mod}.name]:${mod},\n`; + } + code += `export default {${plugins}};`; + return { + contents: code, + resolveDir: "./src/plugins" + }; + }); + } +}; + +const gitHash = execSync("git rev-parse --short HEAD", { encoding: "utf-8" }).trim(); +/** + * @type {esbuild.Plugin} + */ +export const gitHashPlugin = { + name: "git-hash-plugin", + setup: build => { + const filter = /^git-hash$/; + build.onResolve({ filter }, args => ({ + namespace: "git-hash", path: args.path + })); + build.onLoad({ filter, namespace: "git-hash" }, () => ({ + contents: `export default "${gitHash}"` + })); + } +}; |