new build script

This commit is contained in:
MathMan05 2025-05-01 16:23:48 -05:00
parent 2bf44e3c50
commit 854da8ecec
4 changed files with 112 additions and 163 deletions

99
build.ts Normal file
View file

@ -0,0 +1,99 @@
import {promises as fs} from "fs";
import * as swc from "@swc/core";
import {fileURLToPath} from "node:url";
import path from "node:path";
import child_process from "child_process";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
async function moveFiles(path: string, newPath: string) {
async function processFile(file: string) {
const Prom: Promise<unknown>[] = [];
if ((await fs.stat(path + "/" + file)).isDirectory()) {
await fs.mkdir(newPath + "/" + file);
Prom.push(moveFiles(path + "/" + file, newPath + "/" + file));
} else {
if (!file.endsWith(".ts")) {
await fs.copyFile(path + "/" + file, newPath + "/" + file);
} else {
const plainname = file.split(".ts")[0];
const newfileDir = newPath + "/" + plainname;
const mod = await swc.transformFile(path + "/" + file, {
minify: true,
sourceMaps: true,
isModule: true,
});
await Promise.all([
fs.writeFile(
newfileDir + ".js",
mod.code + "\n" + `//# sourceMappingURL= ${plainname}.js.map`,
),
fs.writeFile(newfileDir + ".js.map", mod.map as string),
]);
}
}
await Promise.all(Prom);
}
await Promise.all((await fs.readdir(path)).map(processFile));
}
async function build() {
console.time("build");
console.time("Cleaning dir");
try {
await fs.rm(__dirname + "/dist", {recursive: true});
} catch {}
await fs.mkdir(__dirname + "/dist");
console.timeEnd("Cleaning dir");
console.time("Moving and compiling files");
await moveFiles(__dirname + "/src", __dirname + "/dist");
console.timeEnd("Moving and compiling files");
console.time("Moving translations");
let langs = await fs.readdir(__dirname + "/translations");
langs = langs.filter((e) => e !== "qqq.json");
const langobj = {};
for (const lang of langs) {
const str = await fs.readFile("translations/" + lang);
const json = JSON.parse(str.toString());
langobj[lang] = json.readableName;
fs.writeFile(__dirname + "/dist/webpage/translations/" + lang, str);
}
await fs.writeFile(
"dist/webpage/translations/langs.js",
`const langs=${JSON.stringify(langobj)};export{langs}`,
);
console.timeEnd("Moving translations");
console.time("Adding git commit hash");
const revision = child_process.execSync("git rev-parse HEAD").toString().trim();
await fs.writeFile("dist/webpage/getupdates", revision);
console.timeEnd("Adding git commit hash");
console.timeEnd("build");
console.log("");
}
await build();
if (process.argv.includes("watch")) {
let last = Date.now();
(async () => {
for await (const thing of fs.watch(__dirname + "/src")) {
if (Date.now() - last < 100) {
continue;
}
last = Date.now();
await build();
}
})();
(async () => {
for await (const thing of fs.watch(__dirname + "/translations")) {
if (Date.now() - last < 100) {
continue;
}
last = Date.now();
await build();
}
})();
}

View file

@ -1,127 +0,0 @@
const gulp = require("gulp");
const ts = require("gulp-typescript");
const tsProject = ts.createProject("tsconfig.json");
const argv = require("yargs").argv;
const rimraf = require("rimraf");
const plumber = require("gulp-plumber");
const sourcemaps = require("gulp-sourcemaps");
const fs = require("fs");
const {swcDir} = require("@swc/cli");
gulp.task(
"watch",
function () {
gulp.watch("./src", gulp.series("default"));
gulp.watch("./translations", gulp.series("default"));
},
{debounceDelay: 10},
);
// Clean task to delete the dist directory
gulp.task("clean", (cb) => {
return rimraf.rimraf("dist").then(cb());
});
// Task to compile TypeScript files using SWC
gulp.task("scripts", async () => {
if (argv.swc || argv.bunswc) {
return await new Promise((ret) => {
swcDir({
cliOptions: {
outDir: "./dist",
watch: false,
filenames: ["./src"],
extensions: [".ts"],
stripLeadingPaths: true,
},
callbacks: {
onSuccess: (e) => {
ret();
console.log(e);
},
onFail: (e) => {
for ([, reason] of e.reasons) {
console.log(reason);
}
ret();
},
onWatchReady: () => {},
},
});
});
} else {
console.warn("[WARN] Using TSC compiler, will be slower than SWC");
return gulp
.src("src/**/*.ts")
.pipe(sourcemaps.init())
.pipe(plumber()) // Prevent pipe breaking caused by errors
.pipe(tsProject())
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("dist"));
}
});
gulp.task("commit", () => {
revision = require("child_process").execSync("git rev-parse HEAD").toString().trim();
fs.writeFileSync("dist/webpage/getupdates", revision);
return new Promise((_) => _());
});
// Task to copy HTML files
gulp.task("copy-html", () => {
return gulp
.src("src/**/*.html")
.pipe(plumber()) // Prevent pipe breaking caused by errors
.pipe(gulp.dest("dist"));
});
gulp.task("copy-translations", () => {
let langs = fs.readdirSync("translations");
langs = langs.filter((e) => e !== "qqq.json");
const langobj = {};
for (const lang of langs) {
const json = JSON.parse(fs.readFileSync("translations/" + lang).toString());
langobj[lang] = json.readableName;
}
if (!fs.existsSync("dist/webpage/translations")) fs.mkdirSync("dist/webpage/translations");
fs.writeFileSync(
"dist/webpage/translations/langs.js",
`const langs=${JSON.stringify(langobj)};export{langs}`,
);
return gulp
.src("translations/*.json")
.pipe(plumber()) // Prevent pipe breaking caused by errors
.pipe(gulp.dest("dist/webpage/translations"));
});
// Task to copy other static assets (e.g., CSS, images)
gulp.task("copy-assets", () => {
return gulp
.src(
[
"src/**/*.css",
"src/**/*.bin",
"src/**/*.ico",
"src/**/*.json",
"src/**/*.js",
"src/**/*.png",
"src/**/*.jpg",
"src/**/*.jpeg",
"src/**/*.webp",
"src/**/*.gif",
"src/**/*.svg",
"src/**/*.jasf",
"src/**/*.txt",
"src/**/*.woff2",
],
{encoding: false},
)
.pipe(plumber()) // Prevent pipe breaking caused by errors
.pipe(gulp.dest("dist"));
});
// Default task to run all tasks
gulp.task(
"default",
gulp.series(
"clean",
gulp.parallel("scripts", "copy-html", "copy-assets"),
gulp.parallel("copy-translations", "commit"),
),
);

View file

@ -5,50 +5,28 @@
"main": ".dist/index.js",
"type": "module",
"scripts": {
"lint": "eslint .",
"build": "npx gulp",
"bunBuild": "bun build.ts",
"build": "node --experimental-strip-types build.ts",
"start": "node dist/index.js"
},
"author": "MathMan05",
"license": "GPL-3.0",
"dependencies": {
"compression": "^1.7.4",
"express": "^4.19.2",
"gulp-sourcemaps": "^2.6.5",
"prettier": "^3.4.2",
"rimraf": "^6.0.1"
"compression": "^1.8.0",
"@swc/core": "1.11.24",
"express": "^4.21.2"
},
"devDependencies": {
"prettier": "^3.5.3",
"@types/compression": "^1.7.5",
"@types/express": "^4.17.21",
"@types/node-fetch": "^2.6.12",
"typescript": "^5.8.3"
},
"prettier": {
"useTabs": true,
"printWidth": 100,
"semi": true,
"bracketSpacing": false
},
"devDependencies": {
"@eslint/js": "^9.10.0",
"@html-eslint/eslint-plugin": "^0.25.0",
"@html-eslint/parser": "^0.27.0",
"@rsbuild/core": "^1.1.4",
"@rsbuild/plugin-node-polyfill": "^1.2.0",
"@stylistic/eslint-plugin": "^2.3.0",
"@stylistic/eslint-plugin-js": "^2.8.0",
"@swc/cli": "^0.5.2",
"@swc/core": "^1.10.1",
"@types/compression": "^1.7.5",
"@types/eslint__js": "^8.42.3",
"@types/express": "^4.17.21",
"@types/node-fetch": "^2.6.11",
"@typescript-eslint/eslint-plugin": "^8.14.0",
"@typescript-eslint/parser": "^8.14.0",
"eslint": "^8.57.1",
"eslint-plugin-html": "^8.1.1",
"eslint-plugin-sonarjs": "^1.0.4",
"eslint-plugin-unicorn": "^55.0.0",
"gulp": "^5.0.0",
"gulp-copy": "^5.0.0",
"gulp-plumber": "^1.2.1",
"gulp-typescript": "^6.0.0-alpha.1",
"typescript": "^5.6.2",
"typescript-eslint": "^8.14.0"
}
}

View file

@ -1,5 +1,3 @@
#!/usr/bin/env node
import compression from "compression";
import express, {Request, Response} from "express";
import fs from "node:fs/promises";
@ -27,6 +25,7 @@ async function getDirectories(path: string): Promise<dirtype> {
),
);
}
let dirs: dirtype | undefined = undefined;
async function combinePath(path: string, tryAgain = true): Promise<string> {
if (!dirs) {