diff options
Diffstat (limited to 'scripts/build')
-rw-r--r--[-rwxr-xr-x] | scripts/build/buildWeb.mjs | 74 | ||||
-rw-r--r-- | scripts/build/common.mjs | 41 | ||||
-rw-r--r-- | scripts/build/module/style.js | 26 |
3 files changed, 106 insertions, 35 deletions
diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs index c85d8aa..3ad43b2 100755..100644 --- a/scripts/build/buildWeb.mjs +++ b/scripts/build/buildWeb.mjs @@ -20,13 +20,13 @@ import esbuild from "esbuild"; import { zip } from "fflate"; -import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs"; -import { readFile } from "fs/promises"; -import { join, resolve } from "path"; +import { readFileSync } from "fs"; +import { appendFile, mkdir, readFile, rm, writeFile } from "fs/promises"; +import { join } from "path"; // wtf is this assert syntax import PackageJSON from "../../package.json" assert { type: "json" }; -import { commonOpts, fileIncludePlugin, gitHashPlugin, gitRemotePlugin, globPlugins, watch } from "./common.mjs"; +import { commonOpts, globPlugins, watch } from "./common.mjs"; /** * @type {esbuild.BuildOptions} @@ -39,9 +39,7 @@ const commonOptions = { external: ["plugins", "git-hash"], plugins: [ globPlugins, - gitHashPlugin, - gitRemotePlugin, - fileIncludePlugin + ...commonOpts.plugins, ], target: ["esnext"], define: { @@ -77,9 +75,13 @@ await Promise.all( ] ); +/** + * @type {(target: string, files: string[], shouldZip: boolean) => Promise<void>} + */ async function buildPluginZip(target, files, shouldZip) { const entries = { - "dist/Vencord.js": readFileSync("dist/browser.js"), + "dist/Vencord.js": await readFile("dist/browser.js"), + "dist/Vencord.css": await readFile("dist/browser.css"), ...Object.fromEntries(await Promise.all(files.map(async f => [ (f.startsWith("manifest") ? "manifest.json" : f), await readFile(join("browser", f)) @@ -87,29 +89,47 @@ async function buildPluginZip(target, files, shouldZip) { }; if (shouldZip) { - zip(entries, {}, (err, data) => { - if (err) { - console.error(err); - process.exitCode = 1; - } else { - writeFileSync("dist/" + target, data); - console.info("Extension written to dist/" + target); - } + return new Promise((resolve, reject) => { + zip(entries, {}, (err, data) => { + if (err) { + reject(err); + } else { + const out = join("dist", target); + writeFile(out, data).then(() => { + console.info("Extension written to " + out); + resolve(); + }).catch(reject); + } + }); }); } else { - if (existsSync(target)) - rmSync(target, { recursive: true }); - for (const entry in entries) { - const destination = "dist/" + target + "/" + entry; - const parentDirectory = resolve(destination, ".."); - mkdirSync(parentDirectory, { recursive: true }); - writeFileSync(destination, entries[entry]); - } + await rm(target, { recursive: true, force: true }); + await Promise.all(Object.entries(entries).map(async ([file, content]) => { + const dest = join("dist", target, file); + const parentDirectory = join(dest, ".."); + await mkdir(parentDirectory, { recursive: true }); + await writeFile(dest, content); + })); + console.info("Unpacked Extension written to dist/" + target); } } -await buildPluginZip("extension-v3.zip", ["modifyResponseHeaders.json", "content.js", "manifestv3.json"], true); -await buildPluginZip("extension-v2.zip", ["background.js", "content.js", "manifestv2.json"], true); -await buildPluginZip("extension-v2-unpacked", ["background.js", "content.js", "manifestv2.json"], false); +const cssText = "`" + readFileSync("dist/Vencord.user.css", "utf-8").replaceAll("`", "\\`") + "`"; +const cssRuntime = ` +;document.addEventListener("DOMContentLoaded", () => document.documentElement.appendChild( + Object.assign(document.createElement("style"), { + textContent: ${cssText}, + id: "vencord-css-core" + }), + { once: true } +)); +`; + +await Promise.all([ + appendFile("dist/Vencord.user.js", cssRuntime), + buildPluginZip("extension-v3.zip", ["modifyResponseHeaders.json", "content.js", "manifestv3.json"], true), + buildPluginZip("extension-v2.zip", ["background.js", "content.js", "manifestv2.json"], true), + buildPluginZip("extension-v2-unpacked", ["background.js", "content.js", "manifestv2.json"], false), +]); diff --git a/scripts/build/common.mjs b/scripts/build/common.mjs index 11aaa81..2743c70 100644 --- a/scripts/build/common.mjs +++ b/scripts/build/common.mjs @@ -17,9 +17,9 @@ */ import { exec, execSync } from "child_process"; -import { existsSync } from "fs"; +import { existsSync, readFileSync } from "fs"; import { readdir, readFile } from "fs/promises"; -import { join } from "path"; +import { join, relative } from "path"; import { promisify } from "util"; export const watch = process.argv.includes("--watch"); @@ -35,7 +35,7 @@ export const banner = { // https://github.com/evanw/esbuild/issues/619#issuecomment-751995294 /** - * @type {esbuild.Plugin} + * @type {import("esbuild").Plugin} */ export const makeAllPackagesExternalPlugin = { name: "make-all-packages-external", @@ -46,7 +46,7 @@ export const makeAllPackagesExternalPlugin = { }; /** - * @type {esbuild.Plugin} + * @type {import("esbuild").Plugin} */ export const globPlugins = { name: "glob-plugins", @@ -87,7 +87,7 @@ export const globPlugins = { }; /** - * @type {esbuild.Plugin} + * @type {import("esbuild").Plugin} */ export const gitHashPlugin = { name: "git-hash-plugin", @@ -103,7 +103,7 @@ export const gitHashPlugin = { }; /** - * @type {esbuild.Plugin} + * @type {import("esbuild").Plugin} */ export const gitRemotePlugin = { name: "git-remote-plugin", @@ -125,7 +125,7 @@ export const gitRemotePlugin = { }; /** - * @type {esbuild.Plugin} + * @type {import("esbuild").Plugin} */ export const fileIncludePlugin = { name: "file-include-plugin", @@ -147,6 +147,31 @@ export const fileIncludePlugin = { } }; +const styleModule = readFileSync("./scripts/build/module/style.js", "utf-8"); +/** + * @type {import("esbuild").Plugin} + */ +export const stylePlugin = { + name: "style-plugin", + setup: ({ onResolve, onLoad }) => { + onResolve({ filter: /\.css\?managed$/, namespace: "file" }, ({ path, resolveDir }) => ({ + path: relative(process.cwd(), join(resolveDir, path.replace("?managed", ""))), + namespace: "managed-style", + })); + onLoad({ filter: /\.css$/, namespace: "managed-style" }, async ({ path }) => { + const css = await readFile(path, "utf-8"); + const name = relative(process.cwd(), path).replaceAll("\\", "/"); + + return { + loader: "js", + contents: styleModule + .replaceAll("STYLE_SOURCE", JSON.stringify(css)) + .replaceAll("STYLE_NAME", JSON.stringify(name)) + }; + }); + } +}; + /** * @type {import("esbuild").BuildOptions} */ @@ -158,7 +183,7 @@ export const commonOpts = { sourcemap: watch ? "inline" : "", legalComments: "linked", banner, - plugins: [fileIncludePlugin, gitHashPlugin, gitRemotePlugin], + plugins: [fileIncludePlugin, gitHashPlugin, gitRemotePlugin, stylePlugin], external: ["~plugins", "~git-hash", "~git-remote"], inject: ["./scripts/build/inject/react.mjs"], jsxFactory: "VencordCreateElement", diff --git a/scripts/build/module/style.js b/scripts/build/module/style.js new file mode 100644 index 0000000..5981a3d --- /dev/null +++ b/scripts/build/module/style.js @@ -0,0 +1,26 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2022 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +(window.VencordStyles ??= new Map()).set(STYLE_NAME, { + name: STYLE_NAME, + source: STYLE_SOURCE, + classNames: {}, + dom: null, +}); + +export default STYLE_NAME; |