Update esbuild to latest version (#3218)

This commit is contained in:
v 2025-02-12 18:09:14 +01:00 committed by Vendicated
parent 306890aa13
commit 5196c2adc0
No known key found for this signature in database
GPG key ID: D66986BAF75ECF18
9 changed files with 406 additions and 376 deletions

View file

@ -17,38 +17,41 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import esbuild from "esbuild";
// @ts-check
import { readdir } from "fs/promises";
import { join } from "path";
import { BUILD_TIMESTAMP, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, commonRendererPlugins, watch } from "./common.mjs";
import { BUILD_TIMESTAMP, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, commonRendererPlugins, watch, buildOrWatchAll, stringifyValues } from "./common.mjs";
const defines = {
const defines = stringifyValues({
IS_STANDALONE,
IS_DEV,
IS_REPORTER,
IS_UPDATER_DISABLED,
IS_WEB: false,
IS_EXTENSION: false,
VERSION: JSON.stringify(VERSION),
VERSION,
BUILD_TIMESTAMP
};
});
if (defines.IS_STANDALONE === false)
if (defines.IS_STANDALONE === "false") {
// If this is a local build (not standalone), optimize
// for the specific platform we're on
defines["process.platform"] = JSON.stringify(process.platform);
}
/**
* @type {esbuild.BuildOptions}
* @type {import("esbuild").BuildOptions}
*/
const nodeCommonOpts = {
...commonOpts,
define: defines,
format: "cjs",
platform: "node",
target: ["esnext"],
external: ["electron", "original-fs", "~pluginNatives", ...commonOpts.external],
define: defines
// @ts-ignore this is never undefined
external: ["electron", "original-fs", "~pluginNatives", ...commonOpts.external]
};
const sourceMapFooter = s => watch ? "" : `//# sourceMappingURL=vencord://${s}.js.map`;
@ -102,25 +105,27 @@ const globNativesPlugin = {
}
};
await Promise.all([
/** @type {import("esbuild").BuildOptions[]} */
const buildConfigs = ([
// Discord Desktop main & renderer & preload
esbuild.build({
{
...nodeCommonOpts,
entryPoints: ["src/main/index.ts"],
outfile: "dist/patcher.js",
footer: { js: "//# sourceURL=VencordPatcher\n" + sourceMapFooter("patcher") },
sourcemap,
define: {
...defines,
IS_DISCORD_DESKTOP: true,
IS_VESKTOP: false
},
plugins: [
// @ts-ignore this is never undefined
...nodeCommonOpts.plugins,
globNativesPlugin
]
}),
esbuild.build({
],
define: {
...defines,
IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: "false"
}
},
{
...commonOpts,
entryPoints: ["src/Vencord.ts"],
outfile: "dist/renderer.js",
@ -135,11 +140,11 @@ await Promise.all([
],
define: {
...defines,
IS_DISCORD_DESKTOP: true,
IS_VESKTOP: false
IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: "false"
}
}),
esbuild.build({
},
{
...nodeCommonOpts,
entryPoints: ["src/preload.ts"],
outfile: "dist/preload.js",
@ -147,29 +152,29 @@ await Promise.all([
sourcemap,
define: {
...defines,
IS_DISCORD_DESKTOP: true,
IS_VESKTOP: false
IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: "false"
}
}),
},
// Vencord Desktop main & renderer & preload
esbuild.build({
{
...nodeCommonOpts,
entryPoints: ["src/main/index.ts"],
outfile: "dist/vencordDesktopMain.js",
footer: { js: "//# sourceURL=VencordDesktopMain\n" + sourceMapFooter("vencordDesktopMain") },
sourcemap,
define: {
...defines,
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: true
},
plugins: [
...nodeCommonOpts.plugins,
globNativesPlugin
]
}),
esbuild.build({
],
define: {
...defines,
IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: "true"
}
},
{
...commonOpts,
entryPoints: ["src/Vencord.ts"],
outfile: "dist/vencordDesktopRenderer.js",
@ -184,11 +189,11 @@ await Promise.all([
],
define: {
...defines,
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: true
IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: "true"
}
}),
esbuild.build({
},
{
...nodeCommonOpts,
entryPoints: ["src/preload.ts"],
outfile: "dist/vencordDesktopPreload.js",
@ -196,14 +201,10 @@ await Promise.all([
sourcemap,
define: {
...defines,
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: true
IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: "true"
}
}),
]).catch(err => {
console.error("Build failed");
console.error(err.message);
// make ci fail
if (!commonOpts.watch)
process.exitCode = 1;
});
}
]);
await buildOrWatchAll(buildConfigs);

View file

@ -17,29 +17,30 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import esbuild from "esbuild";
// @ts-check
import { readFileSync } from "fs";
import { appendFile, mkdir, readdir, readFile, rm, writeFile } from "fs/promises";
import { join } from "path";
import Zip from "zip-local";
import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, VERSION, commonRendererPlugins } from "./common.mjs";
import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, VERSION, commonRendererPlugins, buildOrWatchAll, stringifyValues } from "./common.mjs";
/**
* @type {esbuild.BuildOptions}
* @type {import("esbuild").BuildOptions}
*/
const commonOptions = {
...commonOpts,
entryPoints: ["browser/Vencord.ts"],
globalName: "Vencord",
format: "iife",
globalName: "Vencord",
external: ["~plugins", "~git-hash", "/assets/*"],
target: ["esnext"],
plugins: [
globPlugins("web"),
...commonRendererPlugins
],
target: ["esnext"],
define: {
define: stringifyValues({
IS_WEB: true,
IS_EXTENSION: false,
IS_STANDALONE: true,
@ -48,9 +49,9 @@ const commonOptions = {
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: false,
IS_UPDATER_DISABLED: true,
VERSION: JSON.stringify(VERSION),
VERSION,
BUILD_TIMESTAMP
}
})
};
const MonacoWorkerEntryPoints = [
@ -58,70 +59,59 @@ const MonacoWorkerEntryPoints = [
"vs/editor/editor.worker.js"
];
const RnNoiseFiles = [
"dist/rnnoise.wasm",
"dist/rnnoise_simd.wasm",
"dist/rnnoise/workletProcessor.js",
"LICENSE"
/** @type {import("esbuild").BuildOptions[]} */
const buildConfigs = [
{
entryPoints: MonacoWorkerEntryPoints.map(entry => `node_modules/monaco-editor/esm/${entry}`),
bundle: true,
minify: true,
format: "iife",
outbase: "node_modules/monaco-editor/esm/",
outdir: "dist/vendor/monaco"
},
{
entryPoints: ["browser/monaco.ts"],
bundle: true,
minify: true,
format: "iife",
outfile: "dist/vendor/monaco/index.js",
loader: {
".ttf": "file"
}
},
{
...commonOptions,
outfile: "dist/browser.js",
footer: { js: "//# sourceURL=VencordWeb" }
},
{
...commonOptions,
outfile: "dist/extension.js",
define: {
...commonOptions.define,
IS_EXTENSION: "true"
},
footer: { js: "//# sourceURL=VencordWeb" }
},
{
...commonOptions,
inject: ["browser/GMPolyfill.js", ...(commonOptions?.inject || [])],
define: {
...commonOptions.define,
window: "unsafeWindow",
},
outfile: "dist/Vencord.user.js",
banner: {
js: readFileSync("browser/userscript.meta.js", "utf-8").replace("%version%", `${VERSION}.${new Date().getTime()}`)
},
footer: {
// UserScripts get wrapped in an iife, so define Vencord prop on window that returns our local
js: "Object.defineProperty(unsafeWindow,'Vencord',{get:()=>Vencord});"
}
}
];
await Promise.all(
[
esbuild.build({
entryPoints: MonacoWorkerEntryPoints.map(entry => `node_modules/monaco-editor/esm/${entry}`),
bundle: true,
minify: true,
format: "iife",
outbase: "node_modules/monaco-editor/esm/",
outdir: "dist/monaco"
}),
esbuild.build({
entryPoints: ["browser/monaco.ts"],
bundle: true,
minify: true,
format: "iife",
outfile: "dist/monaco/index.js",
loader: {
".ttf": "file"
}
}),
esbuild.build({
...commonOptions,
outfile: "dist/browser.js",
footer: { js: "//# sourceURL=VencordWeb" }
}),
esbuild.build({
...commonOptions,
outfile: "dist/extension.js",
define: {
...commonOptions?.define,
IS_EXTENSION: true,
},
footer: { js: "//# sourceURL=VencordWeb" }
}),
esbuild.build({
...commonOptions,
inject: ["browser/GMPolyfill.js", ...(commonOptions?.inject || [])],
define: {
...(commonOptions?.define),
window: "unsafeWindow",
},
outfile: "dist/Vencord.user.js",
banner: {
js: readFileSync("browser/userscript.meta.js", "utf-8").replace("%version%", `${VERSION}.${new Date().getTime()}`)
},
footer: {
// UserScripts get wrapped in an iife, so define Vencord prop on window that returns our local
js: "Object.defineProperty(unsafeWindow,'Vencord',{get:()=>Vencord});"
}
})
]
).catch(err => {
console.error("Build failed");
console.error(err.message);
if (!commonOpts.watch)
process.exit(1);
});;
await buildOrWatchAll(buildConfigs);
/**
* @type {(dir: string) => Promise<string[]>}
@ -155,16 +145,13 @@ async function buildExtension(target, files) {
const entries = {
"dist/Vencord.js": await readFile("dist/extension.js"),
"dist/Vencord.css": await readFile("dist/extension.css"),
...await loadDir("dist/monaco"),
...Object.fromEntries(await Promise.all(RnNoiseFiles.map(async file =>
[`third-party/rnnoise/${file.replace(/^dist\//, "")}`, await readFile(`node_modules/@sapphi-red/web-noise-suppressor/${file}`)]
))),
...await loadDir("dist/vendor/monaco", "dist/"),
...Object.fromEntries(await Promise.all(files.map(async f => {
let content = await readFile(join("browser", f));
if (f.startsWith("manifest")) {
const json = JSON.parse(content.toString("utf-8"));
json.version = VERSION;
content = new TextEncoder().encode(JSON.stringify(json));
content = Buffer.from(new TextEncoder().encode(JSON.stringify(json)));
}
return [
@ -210,7 +197,6 @@ if (!process.argv.includes("--skip-extension")) {
Zip.sync.zip("dist/firefox-unpacked").compress().save("dist/extension-firefox.zip");
console.info("Packed Firefox Extension written to dist/extension-firefox.zip");
} else {
await appendCssRuntime;
}

View file

@ -16,11 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// @ts-check
import "../suppressExperimentalWarnings.js";
import "../checkNodeVersion.js";
import { exec, execSync } from "child_process";
import esbuild from "esbuild";
import esbuild, { build, context } from "esbuild";
import { constants as FsConstants, readFileSync } from "fs";
import { access, readdir, readFile } from "fs/promises";
import { minify as minifyHtml } from "html-minifier-terser";
@ -31,7 +33,7 @@ import { getPluginTarget } from "../utils.mjs";
import { builtinModules } from "module";
/** @type {import("../../package.json")} */
const PackageJSON = JSON.parse(readFileSync("package.json"));
const PackageJSON = JSON.parse(readFileSync("package.json", "utf-8"));
export const VERSION = PackageJSON.version;
// https://reproducible-builds.org/docs/source-date-epoch/
@ -54,6 +56,34 @@ export const banner = {
`.trim()
};
/**
* JSON.stringify all values in an object
* @type {(obj: Record<string, any>) => Record<string, string>}
*/
export function stringifyValues(obj) {
for (const key in obj) {
obj[key] = JSON.stringify(obj[key]);
}
return obj;
}
/**
* @param {import("esbuild").BuildOptions[]} buildConfigs
*/
export async function buildOrWatchAll(buildConfigs) {
if (watch) {
await Promise.all(buildConfigs.map(cfg =>
context(cfg).then(ctx => ctx.watch())
));
} else {
await Promise.all(buildConfigs.map(cfg => build(cfg)))
.catch(error => {
console.error(error.message);
process.exit(1); // exit immediately to skip the rest of the builds
});
}
}
const PluginDefinitionNameMatcher = /definePlugin\(\{\s*(["'])?name\1:\s*(["'`])(.+?)\2/;
/**
* @param {string} base
@ -311,18 +341,16 @@ export const banImportPlugin = (filter, message) => ({
export const commonOpts = {
logLevel: "info",
bundle: true,
watch,
minify: !watch && !IS_REPORTER,
sourcemap: watch ? "inline" : "",
sourcemap: watch ? "inline" : "external",
legalComments: "linked",
banner,
plugins: [fileUrlPlugin, gitHashPlugin, gitRemotePlugin, stylePlugin],
external: ["~plugins", "~git-hash", "~git-remote", "/assets/*"],
inject: ["./scripts/build/inject/react.mjs"],
jsx: "transform",
jsxFactory: "VencordCreateElement",
jsxFragment: "VencordFragment",
// Work around https://github.com/evanw/esbuild/issues/2460
tsconfig: "./scripts/build/tsconfig.esbuild.json"
jsxFragment: "VencordFragment"
};
const escapedBuiltinModules = builtinModules
@ -335,5 +363,6 @@ export const commonRendererPlugins = [
banImportPlugin(/^react$/, "Cannot import from react. React and hooks should be imported from @webpack/common"),
banImportPlugin(/^electron(\/.*)?$/, "Cannot import electron in browser code. You need to use a native.ts file"),
banImportPlugin(/^ts-pattern$/, "Cannot import from ts-pattern. match and P should be imported from @webpack/common"),
// @ts-ignore this is never undefined
...commonOpts.plugins
];

View file

@ -1,7 +0,0 @@
// Work around https://github.com/evanw/esbuild/issues/2460
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"jsx": "react"
}
}