mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-09 16:21:51 +00:00
Build tools cleanup pass (#81)
* Fix tsconfig scopes affecting html.js Since it's quite hard to use a DOM library type there, remove the type entirely. * Remove environment variables check Nothing is using them anymore. It can be added back if needed later. * Refactor Texture Packer downloading Refactor local-config.js tasks file into a generic "environment" category consisting of checking if Java is installed, downloading the runnable Texture Packer if it's not yet downloaded and copying the local configuration template; update README accordingly. * Prepare environment only at postinstall Remove environment.prepare task from default build pipelines, add a postinstall script that calls the task, using environment.js as the gulpfile to speed it up. * Remove "docs" tasks and types generation script Remove tasks from docs.js as they are unlikely to do anything meaningful nowadays. Also remove the buildTypes script as it doesn't work anymore. A better solution will be provided in the future. * Simplify some globs Use additional gulp.src options instead of specifying more or complex globs. * Extract built-temp location to a variable Add the src/js/built-temp directory as a new variable in config.js, replace all existing references to built-temp with this variable.
This commit is contained in:
parent
ae739be484
commit
9906397170
@ -56,20 +56,17 @@ and does not intend to provide compatibility for older clients.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [ffmpeg](https://www.ffmpeg.org/download.html)
|
||||
- [Node.js](https://nodejs.org)
|
||||
- [ffmpeg](https://www.ffmpeg.org/download.html) for audio transcoding
|
||||
- [Java](https://www.oracle.com/java/technologies/downloads/) (or [OpenJDK](https://openjdk.org/)) to run the texture packer
|
||||
- [cURL](https://curl.se/download.html)[^1] to download the texture packer
|
||||
|
||||
[^1]: cURL is already installed on most Windows, Linux and macOS systems.
|
||||
|
||||
### Development
|
||||
|
||||
- Run `npm i` in the root folder and in `electron/`.
|
||||
- Run `npm run gulp` in the root folder to build and serve files.
|
||||
If a new browser tab opens, ignore it.
|
||||
- Open a new terminal and run `npm run start` in `electron/` to open an Electron window.
|
||||
- Use `npm run start -- --dev` to run in development mode.
|
||||
- Open a new terminal and run `npm start` in `electron/` to open an Electron window.
|
||||
- Use `npm start -- --dev` to run in development mode.
|
||||
- Tip: If you open the Electron window too early, you can reload it when focused on DevTools.
|
||||
|
||||
### Release
|
||||
|
||||
@ -3,20 +3,17 @@ import fs from "fs";
|
||||
|
||||
export function getRevision(useLast = false) {
|
||||
const commitHash = execSync("git rev-parse --short " + (useLast ? "HEAD^1" : "HEAD")).toString("ascii");
|
||||
return commitHash.replace(/^\s+|\s+$/g, "");
|
||||
return commitHash.trim();
|
||||
}
|
||||
|
||||
export function getAllResourceImages() {
|
||||
return fs
|
||||
.globSync("res/**/*.@(png|svg|jpg)", { cwd: ".." })
|
||||
.map(f => f.replace(/^res\//gi, ""))
|
||||
.filter(f => {
|
||||
if (f.indexOf("ui") >= 0) {
|
||||
// We drop all ui images except for the noinline ones
|
||||
return f.indexOf("noinline") >= 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return fs.globSync("./**/*.@(png|svg|jpg)", { cwd: "../res" }).filter(f => {
|
||||
if (f.indexOf("ui") >= 0) {
|
||||
// We drop all ui images except for the noinline ones
|
||||
return f.indexOf("noinline") >= 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function getVersion() {
|
||||
|
||||
@ -4,6 +4,7 @@ import path from "path/posix";
|
||||
export const baseDir = path.resolve("..");
|
||||
export const buildFolder = path.join(baseDir, "build");
|
||||
export const buildOutputFolder = path.join(baseDir, "build_output");
|
||||
export const generatedCodeFolder = path.join(baseDir, "src/js/built-temp");
|
||||
|
||||
// Globs for atlas resources
|
||||
export const rawImageResourcesGlobs = ["../res_raw/atlas.json", "../res_raw/**/*.png"];
|
||||
@ -20,19 +21,3 @@ export const imageResourcesGlobs = [
|
||||
];
|
||||
|
||||
export const browserSync = BrowserSync.create();
|
||||
|
||||
// Check environment variables
|
||||
|
||||
const envVars = [
|
||||
"SHAPEZ_CLI_SERVER_HOST",
|
||||
"SHAPEZ_CLI_APPLE_ID",
|
||||
"SHAPEZ_CLI_APPLE_CERT_NAME",
|
||||
"SHAPEZ_CLI_GITHUB_USER",
|
||||
"SHAPEZ_CLI_GITHUB_TOKEN",
|
||||
];
|
||||
|
||||
for (let i = 0; i < envVars.length; ++i) {
|
||||
if (!process.env[envVars[i]]) {
|
||||
console.warn("Unset environment variable, might cause issues:", envVars[i]);
|
||||
}
|
||||
}
|
||||
|
||||
36
gulp/docs.js
36
gulp/docs.js
@ -1,36 +0,0 @@
|
||||
import path from "path/posix";
|
||||
import fs from "fs/promises";
|
||||
import gulp from "gulp";
|
||||
|
||||
import gulpRename from "gulp-rename";
|
||||
import stripJsonComments from "strip-json-comments";
|
||||
|
||||
export function convertJsToTs() {
|
||||
return gulp
|
||||
.src(path.join("..", "src", "js", "**", "*.js"))
|
||||
.pipe(
|
||||
gulpRename(path => {
|
||||
path.extname = ".ts";
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(path.join("..", "tsc_temp")));
|
||||
}
|
||||
|
||||
export async function copyTsconfigForHints() {
|
||||
const src = (await fs.readFile(path.join("..", "src", "tsconfig.json"))).toString();
|
||||
const baseConfig = JSON.parse(stripJsonComments(src));
|
||||
|
||||
baseConfig.allowJs = false;
|
||||
baseConfig.checkJs = false;
|
||||
baseConfig.declaration = true;
|
||||
baseConfig.noEmit = false;
|
||||
baseConfig.strict = false;
|
||||
baseConfig.strictFunctionTypes = false;
|
||||
baseConfig.strictBindCallApply = false;
|
||||
baseConfig.alwaysStrict = false;
|
||||
baseConfig.composite = true;
|
||||
baseConfig.outFile = "bundled-ts.js";
|
||||
await fs.writeFile(path.join("..", "tsc_temp", "tsconfig.json"), JSON.stringify(baseConfig));
|
||||
}
|
||||
|
||||
export const prepareDocs = gulp.series(convertJsToTs, copyTsconfigForHints);
|
||||
49
gulp/environment.js
Normal file
49
gulp/environment.js
Normal file
@ -0,0 +1,49 @@
|
||||
import { exec } from "child_process";
|
||||
import fs from "fs/promises";
|
||||
import gulp from "gulp";
|
||||
import { promisify } from "util";
|
||||
|
||||
const texturePackerUrl =
|
||||
"https://libgdx-nightlies.s3.amazonaws.com/libgdx-runnables/runnable-texturepacker.jar";
|
||||
|
||||
const configTemplatePath = "../src/js/core/config.local.template.js";
|
||||
const configPath = "../src/js/core/config.local.js";
|
||||
|
||||
export async function checkJava() {
|
||||
try {
|
||||
const { stderr } = await promisify(exec)("java -version");
|
||||
console.log(`Found Java:`, stderr);
|
||||
} catch {
|
||||
throw new Error("Java is required to build the texture atlas, but was not found");
|
||||
}
|
||||
}
|
||||
|
||||
export async function downloadTexturePacker() {
|
||||
const destination = "./runnable-texturepacker.jar";
|
||||
|
||||
try {
|
||||
// If the file exists already, we're done
|
||||
await fs.access(destination);
|
||||
return;
|
||||
} catch {
|
||||
// File does not exist, need to download
|
||||
}
|
||||
|
||||
console.log(`Downloading ${destination}...`);
|
||||
const response = await fetch(texturePackerUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to download Texture Packer: ${response.statusText}`);
|
||||
}
|
||||
|
||||
await fs.writeFile(destination, response.body);
|
||||
}
|
||||
|
||||
export async function createLocalConfig() {
|
||||
try {
|
||||
await fs.copyFile(configTemplatePath, configPath, fs.constants.COPYFILE_EXCL);
|
||||
} catch {
|
||||
// The file is already there
|
||||
}
|
||||
}
|
||||
|
||||
export const prepare = gulp.parallel(gulp.series(checkJava, downloadTexturePacker), createLocalConfig);
|
||||
17
gulp/html.js
17
gulp/html.js
@ -17,17 +17,11 @@ async function buildHtml() {
|
||||
return gulp
|
||||
.src("../src/html/index.html")
|
||||
.pipe(
|
||||
gulpDom(
|
||||
/** @this {Document} **/ function () {
|
||||
const document = this;
|
||||
|
||||
let loadingCss = fs.readFileSync(path.join("preloader", "preloader.css")).toString();
|
||||
|
||||
const style = document.createElement("style");
|
||||
style.textContent = loadingCss;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
)
|
||||
gulpDom(function () {
|
||||
const style = this.createElement("style");
|
||||
style.textContent = fs.readFileSync(path.join("preloader", "preloader.css"), "utf-8");
|
||||
this.head.appendChild(style);
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
gulpHtmlmin({
|
||||
@ -39,7 +33,6 @@ async function buildHtml() {
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
quoteCharacter: '"',
|
||||
useShortDoctype: true,
|
||||
})
|
||||
)
|
||||
.pipe(gulpRename("index.html"))
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import fs from "fs/promises";
|
||||
import path from "path/posix";
|
||||
import gulp from "gulp";
|
||||
import { buildFolder } from "./config.js";
|
||||
import path from "path/posix";
|
||||
import atlas2Json from "./atlas2json.js";
|
||||
import { buildFolder } from "./config.js";
|
||||
|
||||
import childProcess from "child_process";
|
||||
import { promisify } from "util";
|
||||
@ -15,18 +14,14 @@ const execute = command => {
|
||||
return promise;
|
||||
};
|
||||
|
||||
import gulpImagemin from "gulp-imagemin";
|
||||
import imageminJpegtran from "imagemin-jpegtran";
|
||||
import imageminGifsicle from "imagemin-gifsicle";
|
||||
import imageminPngquant from "imagemin-pngquant";
|
||||
import gulpIf from "gulp-if";
|
||||
import gulpCached from "gulp-cached";
|
||||
import gulpClean from "gulp-clean";
|
||||
import { nonImageResourcesGlobs, imageResourcesGlobs } from "./config.js";
|
||||
|
||||
// Link to download LibGDX runnable-texturepacker.jar
|
||||
const runnableTPSource =
|
||||
"https://libgdx-nightlies.s3.eu-central-1.amazonaws.com/libgdx-runnables/runnable-texturepacker.jar";
|
||||
import gulpIf from "gulp-if";
|
||||
import gulpImagemin from "gulp-imagemin";
|
||||
import imageminGifsicle from "imagemin-gifsicle";
|
||||
import imageminJpegtran from "imagemin-jpegtran";
|
||||
import imageminPngquant from "imagemin-pngquant";
|
||||
import { imageResourcesGlobs, nonImageResourcesGlobs } from "./config.js";
|
||||
|
||||
// Lossless options
|
||||
const minifyImagesOptsLossless = () => [
|
||||
@ -85,21 +80,6 @@ export async function buildAtlas() {
|
||||
const dest = JSON.stringify("../res_built/atlas");
|
||||
|
||||
try {
|
||||
// First check whether Java is installed
|
||||
await execute("java -version");
|
||||
// Now check and try downloading runnable-texturepacker.jar (22MB)
|
||||
try {
|
||||
await fs.access("./runnable-texturepacker.jar");
|
||||
} catch {
|
||||
const escapedLink = JSON.stringify(runnableTPSource);
|
||||
|
||||
try {
|
||||
await execute(`curl -o runnable-texturepacker.jar ${escapedLink}`);
|
||||
} catch {
|
||||
throw new Error("Failed to download runnable-texturepacker.jar!");
|
||||
}
|
||||
}
|
||||
|
||||
await execute(`java -jar runnable-texturepacker.jar ${source} ${dest} atlas0 ${config}`);
|
||||
} catch {
|
||||
console.warn("Building atlas failed. Java not found / unsupported version?");
|
||||
@ -113,7 +93,7 @@ export async function atlasToJson() {
|
||||
|
||||
// Copies the atlas to the final destination
|
||||
export function atlas() {
|
||||
return gulp.src(["../res_built/atlas/*.png"]).pipe(gulp.dest(resourcesDestFolder));
|
||||
return gulp.src("../res_built/atlas/*.png").pipe(gulp.dest(resourcesDestFolder));
|
||||
}
|
||||
|
||||
// Copies the atlas to the final destination after optimizing it (lossy compression)
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
import fs from "fs/promises";
|
||||
|
||||
const configTemplatePath = "../src/js/core/config.local.template.js";
|
||||
const configPath = "../src/js/core/config.local.js";
|
||||
|
||||
export async function findOrCreate() {
|
||||
try {
|
||||
await fs.copyFile(configTemplatePath, configPath, fs.constants.COPYFILE_EXCL);
|
||||
} catch {}
|
||||
}
|
||||
@ -1,12 +1,12 @@
|
||||
import path from "path/posix";
|
||||
import gulp from "gulp";
|
||||
import { buildFolder } from "./config.js";
|
||||
import path from "path/posix";
|
||||
import { buildFolder, generatedCodeFolder } from "./config.js";
|
||||
|
||||
import gulpAudiosprite from "gulp-audiosprite";
|
||||
import gulpClean from "gulp-clean";
|
||||
import gulpCache from "gulp-cache";
|
||||
import gulpPlumber from "gulp-plumber";
|
||||
import gulpClean from "gulp-clean";
|
||||
import gulpFluentFfmpeg from "gulp-fluent-ffmpeg";
|
||||
import gulpPlumber from "gulp-plumber";
|
||||
|
||||
// Gather some basic infos
|
||||
const soundsDir = path.join("..", "res_raw", "sounds");
|
||||
@ -110,9 +110,7 @@ export function sfxOptimize() {
|
||||
.pipe(gulp.dest(path.join(builtSoundsDir)));
|
||||
}
|
||||
export function sfxCopyAtlas() {
|
||||
return gulp
|
||||
.src([path.join(builtSoundsDir, "sfx.json")])
|
||||
.pipe(gulp.dest(path.join("..", "src", "js", "built-temp")));
|
||||
return gulp.src([path.join(builtSoundsDir, "sfx.json")]).pipe(gulp.dest(generatedCodeFolder));
|
||||
}
|
||||
|
||||
export const sfx = gulp.series(sfxGenerateSprites, sfxOptimize, sfxCopyAtlas);
|
||||
|
||||
@ -27,13 +27,10 @@ export default Object.fromEntries(
|
||||
}
|
||||
|
||||
function copyPrefab() {
|
||||
const requiredFiles = [
|
||||
path.join(electronBaseDir, "preload.cjs"),
|
||||
path.join(electronBaseDir, "node_modules", "**", "*.*"),
|
||||
path.join(electronBaseDir, "node_modules", "**", ".*"),
|
||||
path.join(electronBaseDir, "favicon*"),
|
||||
];
|
||||
return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir));
|
||||
const requiredFiles = ["preload.cjs", "node_modules/**/*", "favicon*"];
|
||||
return gulp
|
||||
.src(requiredFiles, { cwd: electronBaseDir, cwdbase: true, dot: true })
|
||||
.pipe(gulp.dest(tempDestBuildDir));
|
||||
}
|
||||
|
||||
async function transpileTypeScript() {
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
browserSync,
|
||||
buildFolder,
|
||||
buildOutputFolder,
|
||||
generatedCodeFolder,
|
||||
imageResourcesGlobs,
|
||||
nonImageResourcesGlobs,
|
||||
rawImageResourcesGlobs,
|
||||
@ -20,16 +21,15 @@ import gulpClean from "gulp-clean";
|
||||
import gulpWebserver from "gulp-webserver";
|
||||
|
||||
import * as css from "./css.js";
|
||||
import * as docs from "./docs.js";
|
||||
import * as environment from "./environment.js";
|
||||
import html from "./html.js";
|
||||
import * as imgres from "./image-resources.js";
|
||||
import js from "./js.js";
|
||||
import * as localConfig from "./local-config.js";
|
||||
import * as sounds from "./sounds.js";
|
||||
import standalone from "./standalone.js";
|
||||
import * as translations from "./translations.js";
|
||||
|
||||
export { css, docs, html, imgres, js, localConfig, sounds, standalone, translations };
|
||||
export { css, environment, html, imgres, js, sounds, standalone, translations };
|
||||
|
||||
///////////////////// BUILD TASKS /////////////////////
|
||||
|
||||
@ -41,9 +41,7 @@ function cleanBuildOutputFolder() {
|
||||
return gulp.src(buildOutputFolder, { read: false, allowEmpty: true }).pipe(gulpClean({ force: true }));
|
||||
}
|
||||
function cleanBuildTempFolder() {
|
||||
return gulp
|
||||
.src(path.join("..", "src", "js", "built-temp"), { read: false, allowEmpty: true })
|
||||
.pipe(gulpClean({ force: true }));
|
||||
return gulp.src(generatedCodeFolder, { read: false, allowEmpty: true }).pipe(gulpClean({ force: true }));
|
||||
}
|
||||
function cleanImageBuildFolder() {
|
||||
return gulp
|
||||
@ -184,7 +182,6 @@ const prepare = {
|
||||
dev: variant =>
|
||||
gulp.series(
|
||||
utils.cleanup,
|
||||
localConfig.findOrCreate,
|
||||
gulp.parallel(
|
||||
utils.copyAdditionalBuildFiles,
|
||||
gulp.series(imgres.buildAtlas, gulp.parallel(imgres.atlasToJson, imgres.atlas)),
|
||||
@ -255,7 +252,6 @@ for (const variant in BUILD_VARIANTS) {
|
||||
pack[variant] = {};
|
||||
for (const task of packageTasks) {
|
||||
pack[variant][task] = gulp.series(
|
||||
localConfig.findOrCreate,
|
||||
full,
|
||||
utils.cleanBuildOutputFolder,
|
||||
standalone[variant].prepare.all,
|
||||
@ -269,7 +265,6 @@ for (const variant in BUILD_VARIANTS) {
|
||||
}
|
||||
|
||||
export const main = {
|
||||
prepareDocs: docs.prepareDocs,
|
||||
webserver,
|
||||
};
|
||||
|
||||
|
||||
@ -1,20 +1,18 @@
|
||||
import path from "path/posix";
|
||||
import fs from "fs/promises";
|
||||
import YAML from "yaml";
|
||||
import gulp from "gulp";
|
||||
import path from "path/posix";
|
||||
|
||||
import gulpPlumber from "gulp-plumber";
|
||||
import gulpYaml from "gulp-yaml";
|
||||
import { generatedCodeFolder } from "./config.js";
|
||||
|
||||
const translationsSourceDir = path.join("..", "translations");
|
||||
const translationsJsonDir = path.join("..", "src", "js", "built-temp");
|
||||
|
||||
export function convertToJson() {
|
||||
return gulp
|
||||
.src(path.join(translationsSourceDir, "*.yaml"))
|
||||
.pipe(gulpPlumber())
|
||||
.pipe(gulpYaml({ space: 2, safe: true }))
|
||||
.pipe(gulp.dest(translationsJsonDir));
|
||||
.pipe(gulp.dest(generatedCodeFolder));
|
||||
}
|
||||
|
||||
export const fullBuild = convertToJson;
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@ -7,6 +7,7 @@
|
||||
"": {
|
||||
"name": "shapez",
|
||||
"version": "1.6.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@msgpack/msgpack": "^3.1.2",
|
||||
@ -59,7 +60,6 @@
|
||||
"postcss-preset-env": "^6.5.0",
|
||||
"postcss-round-subpixels": "^1.2.0",
|
||||
"prettier": "^3.3.2",
|
||||
"strip-json-comments": "^3.0.1",
|
||||
"terser-webpack-plugin": "^5.3.6",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^5.8.2",
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"postinstall": "gulp -f gulp/environment.js prepare",
|
||||
"gulp": "gulp --cwd gulp",
|
||||
"lint": "eslint .",
|
||||
"prettier-all": "prettier --write .",
|
||||
"buildTypes": "tsc src/js/application.js --declaration --allowJs --emitDeclarationOnly --skipLibCheck --out types.js",
|
||||
"package-win32-x64": "gulp --cwd gulp package.standalone.win32-x64",
|
||||
"package-win32-arm64": "gulp --cwd gulp package.standalone.win32-arm64",
|
||||
"package-linux-x64": "gulp --cwd gulp package.standalone.linux-x64",
|
||||
@ -71,7 +71,6 @@
|
||||
"postcss-preset-env": "^6.5.0",
|
||||
"postcss-round-subpixels": "^1.2.0",
|
||||
"prettier": "^3.3.2",
|
||||
"strip-json-comments": "^3.0.1",
|
||||
"terser-webpack-plugin": "^5.3.6",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^5.8.2",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"extends": ["@tsconfig/node-lts/tsconfig"],
|
||||
"include": ["./*", "./electron/**/*", "./gulp/**/*"],
|
||||
"include": ["./*", "./gulp/**/*"],
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user