mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-11 09:11:50 +00:00
Apply formatting to gulp
This commit is contained in:
parent
f49def0c19
commit
5ff15f3029
@ -31,4 +31,4 @@ export function getTag() {
|
||||
export function getVersion() {
|
||||
// Use the version number specified in package.json
|
||||
return JSON.parse(fs.readFileSync("../package.json", "utf-8")).version;
|
||||
}
|
||||
}
|
||||
|
||||
236
gulp/css.js
236
gulp/css.js
@ -1,118 +1,118 @@
|
||||
import path from "path/posix";
|
||||
import gulp from "gulp";
|
||||
import { getRevision } from "./buildutils.js";
|
||||
import { buildFolder } from "./config.js";
|
||||
|
||||
import gulpPostcss from "gulp-postcss";
|
||||
import postcssAssets from "postcss-assets";
|
||||
import postcssPresetEnv from "postcss-preset-env";
|
||||
import postcssRoundSubpixels from "postcss-round-subpixels";
|
||||
import postcssCriticalSplit from "postcss-critical-split";
|
||||
import cssMqpacker from "css-mqpacker";
|
||||
import cssnano from "cssnano";
|
||||
import gulpSassLint from "gulp-sass-lint";
|
||||
import gulpDartSass from "gulp-dart-sass";
|
||||
import gulpPlumber from "gulp-plumber";
|
||||
import gulpRename from "gulp-rename";
|
||||
|
||||
// The assets plugin copies the files
|
||||
const commitHash = getRevision();
|
||||
const postcssAssetsPlugin = postcssAssets({
|
||||
loadPaths: [path.join(buildFolder, "res", "ui")],
|
||||
basePath: buildFolder,
|
||||
baseUrl: ".",
|
||||
});
|
||||
|
||||
// Postcss configuration
|
||||
const postcssPlugins = prod => {
|
||||
const plugins = [postcssAssetsPlugin];
|
||||
if (prod) {
|
||||
plugins.unshift(
|
||||
postcssPresetEnv({
|
||||
browsers: ["> 0.1%"],
|
||||
})
|
||||
);
|
||||
|
||||
plugins.push(
|
||||
cssMqpacker({
|
||||
sort: true,
|
||||
}),
|
||||
cssnano({
|
||||
preset: [
|
||||
"advanced",
|
||||
{
|
||||
cssDeclarationSorter: false,
|
||||
discardUnused: true,
|
||||
mergeIdents: false,
|
||||
reduceIdents: true,
|
||||
zindex: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
postcssRoundSubpixels()
|
||||
);
|
||||
}
|
||||
return plugins;
|
||||
};
|
||||
|
||||
// Performs linting on css
|
||||
export function lint() {
|
||||
return gulp
|
||||
.src(["../src/css/**/*.scss"])
|
||||
.pipe(gulpSassLint({ configFile: ".sasslint.yml" }))
|
||||
.pipe(gulpSassLint.format())
|
||||
.pipe(gulpSassLint.failOnError());
|
||||
}
|
||||
|
||||
function resourcesTask({ isProd }) {
|
||||
return gulp
|
||||
.src("../src/css/main.scss")
|
||||
.pipe(gulpPlumber())
|
||||
.pipe(gulpDartSass.sync().on("error", gulpDartSass.logError))
|
||||
.pipe(
|
||||
gulpPostcss([
|
||||
postcssCriticalSplit({
|
||||
blockTag: "@load-async",
|
||||
}),
|
||||
])
|
||||
)
|
||||
.pipe(gulpRename("async-resources.css"))
|
||||
.pipe(gulpPostcss(postcssPlugins(isProd)))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
}
|
||||
|
||||
export const resources = {
|
||||
// Builds the css resources
|
||||
dev: () => resourcesTask({ isProd: false }),
|
||||
|
||||
// Builds the css resources in prod (=minified)
|
||||
prod: () => resourcesTask({ isProd: true }),
|
||||
};
|
||||
|
||||
function mainTask({ isProd }) {
|
||||
return gulp
|
||||
.src("../src/css/main.scss")
|
||||
.pipe(gulpPlumber())
|
||||
.pipe(gulpDartSass.sync().on("error", gulpDartSass.logError))
|
||||
.pipe(
|
||||
gulpPostcss([
|
||||
postcssCriticalSplit({
|
||||
blockTag: "@load-async",
|
||||
output: "rest",
|
||||
}),
|
||||
])
|
||||
)
|
||||
.pipe(gulpPostcss(postcssPlugins(isProd)))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
}
|
||||
|
||||
export const main = {
|
||||
// Builds the css main
|
||||
dev: () => mainTask({ isProd: false }),
|
||||
|
||||
// Builds the css main in prod (=minified)
|
||||
prod: () => mainTask({ isProd: true }),
|
||||
};
|
||||
|
||||
export const dev = gulp.parallel(main.dev, resources.dev);
|
||||
export const prod = gulp.parallel(main.prod, resources.prod);
|
||||
import path from "path/posix";
|
||||
import gulp from "gulp";
|
||||
import { getRevision } from "./buildutils.js";
|
||||
import { buildFolder } from "./config.js";
|
||||
|
||||
import gulpPostcss from "gulp-postcss";
|
||||
import postcssAssets from "postcss-assets";
|
||||
import postcssPresetEnv from "postcss-preset-env";
|
||||
import postcssRoundSubpixels from "postcss-round-subpixels";
|
||||
import postcssCriticalSplit from "postcss-critical-split";
|
||||
import cssMqpacker from "css-mqpacker";
|
||||
import cssnano from "cssnano";
|
||||
import gulpSassLint from "gulp-sass-lint";
|
||||
import gulpDartSass from "gulp-dart-sass";
|
||||
import gulpPlumber from "gulp-plumber";
|
||||
import gulpRename from "gulp-rename";
|
||||
|
||||
// The assets plugin copies the files
|
||||
const commitHash = getRevision();
|
||||
const postcssAssetsPlugin = postcssAssets({
|
||||
loadPaths: [path.join(buildFolder, "res", "ui")],
|
||||
basePath: buildFolder,
|
||||
baseUrl: ".",
|
||||
});
|
||||
|
||||
// Postcss configuration
|
||||
const postcssPlugins = prod => {
|
||||
const plugins = [postcssAssetsPlugin];
|
||||
if (prod) {
|
||||
plugins.unshift(
|
||||
postcssPresetEnv({
|
||||
browsers: ["> 0.1%"],
|
||||
})
|
||||
);
|
||||
|
||||
plugins.push(
|
||||
cssMqpacker({
|
||||
sort: true,
|
||||
}),
|
||||
cssnano({
|
||||
preset: [
|
||||
"advanced",
|
||||
{
|
||||
cssDeclarationSorter: false,
|
||||
discardUnused: true,
|
||||
mergeIdents: false,
|
||||
reduceIdents: true,
|
||||
zindex: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
postcssRoundSubpixels()
|
||||
);
|
||||
}
|
||||
return plugins;
|
||||
};
|
||||
|
||||
// Performs linting on css
|
||||
export function lint() {
|
||||
return gulp
|
||||
.src(["../src/css/**/*.scss"])
|
||||
.pipe(gulpSassLint({ configFile: ".sasslint.yml" }))
|
||||
.pipe(gulpSassLint.format())
|
||||
.pipe(gulpSassLint.failOnError());
|
||||
}
|
||||
|
||||
function resourcesTask({ isProd }) {
|
||||
return gulp
|
||||
.src("../src/css/main.scss")
|
||||
.pipe(gulpPlumber())
|
||||
.pipe(gulpDartSass.sync().on("error", gulpDartSass.logError))
|
||||
.pipe(
|
||||
gulpPostcss([
|
||||
postcssCriticalSplit({
|
||||
blockTag: "@load-async",
|
||||
}),
|
||||
])
|
||||
)
|
||||
.pipe(gulpRename("async-resources.css"))
|
||||
.pipe(gulpPostcss(postcssPlugins(isProd)))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
}
|
||||
|
||||
export const resources = {
|
||||
// Builds the css resources
|
||||
dev: () => resourcesTask({ isProd: false }),
|
||||
|
||||
// Builds the css resources in prod (=minified)
|
||||
prod: () => resourcesTask({ isProd: true }),
|
||||
};
|
||||
|
||||
function mainTask({ isProd }) {
|
||||
return gulp
|
||||
.src("../src/css/main.scss")
|
||||
.pipe(gulpPlumber())
|
||||
.pipe(gulpDartSass.sync().on("error", gulpDartSass.logError))
|
||||
.pipe(
|
||||
gulpPostcss([
|
||||
postcssCriticalSplit({
|
||||
blockTag: "@load-async",
|
||||
output: "rest",
|
||||
}),
|
||||
])
|
||||
)
|
||||
.pipe(gulpPostcss(postcssPlugins(isProd)))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
}
|
||||
|
||||
export const main = {
|
||||
// Builds the css main
|
||||
dev: () => mainTask({ isProd: false }),
|
||||
|
||||
// Builds the css main in prod (=minified)
|
||||
prod: () => mainTask({ isProd: true }),
|
||||
};
|
||||
|
||||
export const dev = gulp.parallel(main.dev, resources.dev);
|
||||
export const prod = gulp.parallel(main.prod, resources.prod);
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
import gulp from "gulp";
|
||||
import * as tasks from "./tasks.js";
|
||||
|
||||
/**
|
||||
* @typedef {import("gulp").TaskFunction} TaskFunction
|
||||
* @typedef {TaskFunction | { [k: string]: Tasks }} Tasks
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Tasks} tasks
|
||||
* @param {string=} prefix
|
||||
*/
|
||||
function register(tasks, prefix) {
|
||||
if (tasks instanceof Function) {
|
||||
gulp.task(prefix, tasks);
|
||||
return;
|
||||
}
|
||||
for (const [k, v] of Object.entries(tasks)) {
|
||||
register(v, prefix == null ? k : `${prefix}.${k}`);
|
||||
}
|
||||
}
|
||||
|
||||
register(tasks);
|
||||
import gulp from "gulp";
|
||||
import * as tasks from "./tasks.js";
|
||||
|
||||
/**
|
||||
* @typedef {import("gulp").TaskFunction} TaskFunction
|
||||
* @typedef {TaskFunction | { [k: string]: Tasks }} Tasks
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Tasks} tasks
|
||||
* @param {string=} prefix
|
||||
*/
|
||||
function register(tasks, prefix) {
|
||||
if (tasks instanceof Function) {
|
||||
gulp.task(prefix, tasks);
|
||||
return;
|
||||
}
|
||||
for (const [k, v] of Object.entries(tasks)) {
|
||||
register(v, prefix == null ? k : `${prefix}.${k}`);
|
||||
}
|
||||
}
|
||||
|
||||
register(tasks);
|
||||
|
||||
216
gulp/html.js
216
gulp/html.js
@ -1,108 +1,108 @@
|
||||
import { getRevision } from "./buildutils.js";
|
||||
import fs from "fs";
|
||||
import path from "path/posix";
|
||||
import crypto from "crypto";
|
||||
import gulp from "gulp";
|
||||
import { buildFolder } from "./config.js";
|
||||
|
||||
import gulpDom from "gulp-dom";
|
||||
import gulpHtmlmin from "gulp-htmlmin";
|
||||
import gulpHtmlBeautify from "gulp-html-beautify";
|
||||
import gulpRename from "gulp-rename";
|
||||
|
||||
function computeIntegrityHash(fullPath, algorithm = "sha256") {
|
||||
const file = fs.readFileSync(fullPath);
|
||||
const hash = crypto.createHash(algorithm).update(file).digest("base64");
|
||||
return algorithm + "-" + hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* PROVIDES
|
||||
*
|
||||
* html.dev
|
||||
* html.prod
|
||||
*/
|
||||
const commitHash = getRevision();
|
||||
async function buildHtml({ integrity = true }) {
|
||||
return gulp
|
||||
.src("../src/html/index.html")
|
||||
.pipe(
|
||||
gulpDom(
|
||||
/** @this {Document} **/ function () {
|
||||
const document = this;
|
||||
|
||||
// Append css
|
||||
const css = document.createElement("link");
|
||||
css.rel = "stylesheet";
|
||||
css.type = "text/css";
|
||||
css.media = "none";
|
||||
css.setAttribute("onload", "this.media='all'");
|
||||
css.href = "main.css";
|
||||
if (integrity) {
|
||||
css.setAttribute(
|
||||
"integrity",
|
||||
computeIntegrityHash(path.join(buildFolder, "main.css"))
|
||||
);
|
||||
}
|
||||
document.head.appendChild(css);
|
||||
|
||||
let fontCss = `
|
||||
@font-face {
|
||||
font-family: "GameFont";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-display: swap;
|
||||
src: url('res/fonts/GameFont.woff2') format("woff2");
|
||||
}
|
||||
`;
|
||||
let loadingCss =
|
||||
fontCss + fs.readFileSync(path.join("preloader", "preloader.css")).toString();
|
||||
|
||||
const style = document.createElement("style");
|
||||
style.setAttribute("type", "text/css");
|
||||
style.textContent = loadingCss;
|
||||
document.head.appendChild(style);
|
||||
|
||||
let bodyContent = fs.readFileSync(path.join("preloader", "preloader.html")).toString();
|
||||
|
||||
const bundleScript = document.createElement("script");
|
||||
bundleScript.type = "text/javascript";
|
||||
bundleScript.src = "bundle.js";
|
||||
if (integrity) {
|
||||
bundleScript.setAttribute(
|
||||
"integrity",
|
||||
computeIntegrityHash(path.join(buildFolder, "bundle.js"))
|
||||
);
|
||||
}
|
||||
document.head.appendChild(bundleScript);
|
||||
|
||||
document.body.innerHTML = bodyContent;
|
||||
}
|
||||
)
|
||||
)
|
||||
.pipe(
|
||||
gulpHtmlmin({
|
||||
caseSensitive: true,
|
||||
collapseBooleanAttributes: true,
|
||||
collapseInlineTagWhitespace: true,
|
||||
collapseWhitespace: true,
|
||||
preserveLineBreaks: true,
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
quoteCharacter: '"',
|
||||
useShortDoctype: true,
|
||||
})
|
||||
)
|
||||
.pipe(gulpHtmlBeautify())
|
||||
.pipe(gulpRename("index.html"))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
}
|
||||
|
||||
export const dev = () =>
|
||||
buildHtml({
|
||||
integrity: false,
|
||||
});
|
||||
export const prod = () =>
|
||||
buildHtml({
|
||||
integrity: true,
|
||||
});
|
||||
import { getRevision } from "./buildutils.js";
|
||||
import fs from "fs";
|
||||
import path from "path/posix";
|
||||
import crypto from "crypto";
|
||||
import gulp from "gulp";
|
||||
import { buildFolder } from "./config.js";
|
||||
|
||||
import gulpDom from "gulp-dom";
|
||||
import gulpHtmlmin from "gulp-htmlmin";
|
||||
import gulpHtmlBeautify from "gulp-html-beautify";
|
||||
import gulpRename from "gulp-rename";
|
||||
|
||||
function computeIntegrityHash(fullPath, algorithm = "sha256") {
|
||||
const file = fs.readFileSync(fullPath);
|
||||
const hash = crypto.createHash(algorithm).update(file).digest("base64");
|
||||
return algorithm + "-" + hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* PROVIDES
|
||||
*
|
||||
* html.dev
|
||||
* html.prod
|
||||
*/
|
||||
const commitHash = getRevision();
|
||||
async function buildHtml({ integrity = true }) {
|
||||
return gulp
|
||||
.src("../src/html/index.html")
|
||||
.pipe(
|
||||
gulpDom(
|
||||
/** @this {Document} **/ function () {
|
||||
const document = this;
|
||||
|
||||
// Append css
|
||||
const css = document.createElement("link");
|
||||
css.rel = "stylesheet";
|
||||
css.type = "text/css";
|
||||
css.media = "none";
|
||||
css.setAttribute("onload", "this.media='all'");
|
||||
css.href = "main.css";
|
||||
if (integrity) {
|
||||
css.setAttribute(
|
||||
"integrity",
|
||||
computeIntegrityHash(path.join(buildFolder, "main.css"))
|
||||
);
|
||||
}
|
||||
document.head.appendChild(css);
|
||||
|
||||
let fontCss = `
|
||||
@font-face {
|
||||
font-family: "GameFont";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-display: swap;
|
||||
src: url('res/fonts/GameFont.woff2') format("woff2");
|
||||
}
|
||||
`;
|
||||
let loadingCss =
|
||||
fontCss + fs.readFileSync(path.join("preloader", "preloader.css")).toString();
|
||||
|
||||
const style = document.createElement("style");
|
||||
style.setAttribute("type", "text/css");
|
||||
style.textContent = loadingCss;
|
||||
document.head.appendChild(style);
|
||||
|
||||
let bodyContent = fs.readFileSync(path.join("preloader", "preloader.html")).toString();
|
||||
|
||||
const bundleScript = document.createElement("script");
|
||||
bundleScript.type = "text/javascript";
|
||||
bundleScript.src = "bundle.js";
|
||||
if (integrity) {
|
||||
bundleScript.setAttribute(
|
||||
"integrity",
|
||||
computeIntegrityHash(path.join(buildFolder, "bundle.js"))
|
||||
);
|
||||
}
|
||||
document.head.appendChild(bundleScript);
|
||||
|
||||
document.body.innerHTML = bodyContent;
|
||||
}
|
||||
)
|
||||
)
|
||||
.pipe(
|
||||
gulpHtmlmin({
|
||||
caseSensitive: true,
|
||||
collapseBooleanAttributes: true,
|
||||
collapseInlineTagWhitespace: true,
|
||||
collapseWhitespace: true,
|
||||
preserveLineBreaks: true,
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
quoteCharacter: '"',
|
||||
useShortDoctype: true,
|
||||
})
|
||||
)
|
||||
.pipe(gulpHtmlBeautify())
|
||||
.pipe(gulpRename("index.html"))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
}
|
||||
|
||||
export const dev = () =>
|
||||
buildHtml({
|
||||
integrity: false,
|
||||
});
|
||||
export const prod = () =>
|
||||
buildHtml({
|
||||
integrity: true,
|
||||
});
|
||||
|
||||
@ -1,182 +1,182 @@
|
||||
import fs from "fs/promises";
|
||||
import path from "path/posix";
|
||||
import gulp from "gulp";
|
||||
import { buildFolder } from "./config.js";
|
||||
import atlas2Json from "./atlas2json.js";
|
||||
|
||||
import childProcess from "child_process";
|
||||
import { promisify } from "util";
|
||||
const exec = promisify(childProcess.exec);
|
||||
const execute = command => {
|
||||
const promise = exec(command, {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
promise.child.stderr.pipe(process.stderr);
|
||||
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";
|
||||
|
||||
// Lossless options
|
||||
const minifyImagesOptsLossless = () => [
|
||||
imageminJpegtran({
|
||||
progressive: true,
|
||||
}),
|
||||
gulpImagemin.svgo({}),
|
||||
gulpImagemin.optipng({
|
||||
optimizationLevel: 3,
|
||||
}),
|
||||
imageminGifsicle({
|
||||
optimizationLevel: 3,
|
||||
colors: 128,
|
||||
}),
|
||||
];
|
||||
|
||||
// Lossy options
|
||||
const minifyImagesOpts = () => [
|
||||
gulpImagemin.mozjpeg({
|
||||
quality: 80,
|
||||
maxMemory: 1024 * 1024 * 8,
|
||||
}),
|
||||
gulpImagemin.svgo({}),
|
||||
imageminPngquant({
|
||||
speed: 1,
|
||||
strip: true,
|
||||
quality: [0.65, 0.9],
|
||||
dithering: false,
|
||||
verbose: false,
|
||||
}),
|
||||
gulpImagemin.optipng({
|
||||
optimizationLevel: 3,
|
||||
}),
|
||||
imageminGifsicle({
|
||||
optimizationLevel: 3,
|
||||
colors: 128,
|
||||
}),
|
||||
];
|
||||
|
||||
// Where the resources folder are
|
||||
const resourcesDestFolder = path.join(buildFolder, "res");
|
||||
|
||||
/**
|
||||
* Determines if an atlas must use lossless compression
|
||||
* @param {string} fname
|
||||
*/
|
||||
function fileMustBeLossless(fname) {
|
||||
return fname.indexOf("lossless") >= 0;
|
||||
}
|
||||
|
||||
/////////////// ATLAS /////////////////////
|
||||
|
||||
export async function buildAtlas() {
|
||||
const config = JSON.stringify("../res_raw/atlas.json");
|
||||
const source = JSON.stringify("../res_raw");
|
||||
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 {
|
||||
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?");
|
||||
}
|
||||
}
|
||||
|
||||
// Converts .atlas LibGDX files to JSON
|
||||
export async function atlasToJson() {
|
||||
atlas2Json("../res_built/atlas");
|
||||
}
|
||||
|
||||
// Copies the atlas to the final destination
|
||||
export function atlas() {
|
||||
return gulp.src(["../res_built/atlas/*.png"]).pipe(gulp.dest(resourcesDestFolder));
|
||||
}
|
||||
|
||||
// Copies the atlas to the final destination after optimizing it (lossy compression)
|
||||
export function atlasOptimized() {
|
||||
return gulp
|
||||
.src(["../res_built/atlas/*.png"])
|
||||
.pipe(
|
||||
gulpIf(
|
||||
fname => fileMustBeLossless(fname.history[0]),
|
||||
gulpImagemin(minifyImagesOptsLossless()),
|
||||
gulpImagemin(minifyImagesOpts())
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(resourcesDestFolder));
|
||||
}
|
||||
|
||||
//////////////////// RESOURCES //////////////////////
|
||||
|
||||
// Copies all resources which are no ui resources
|
||||
export function copyNonImageResources() {
|
||||
return gulp.src(nonImageResourcesGlobs).pipe(gulp.dest(resourcesDestFolder));
|
||||
}
|
||||
|
||||
// Copies all ui resources
|
||||
export function copyImageResources() {
|
||||
return gulp
|
||||
.src(imageResourcesGlobs)
|
||||
.pipe(gulpCached("imgres.copyImageResources"))
|
||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||
}
|
||||
|
||||
// Copies all ui resources and optimizes them
|
||||
export function copyImageResourcesOptimized() {
|
||||
return gulp
|
||||
.src(imageResourcesGlobs)
|
||||
.pipe(
|
||||
gulpIf(
|
||||
fname => fileMustBeLossless(fname.history[0]),
|
||||
gulpImagemin(minifyImagesOptsLossless()),
|
||||
gulpImagemin(minifyImagesOpts())
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||
}
|
||||
|
||||
// Copies all resources and optimizes them
|
||||
export const allOptimized = gulp.parallel(
|
||||
gulp.series(buildAtlas, atlasToJson, atlasOptimized),
|
||||
copyNonImageResources,
|
||||
copyImageResourcesOptimized
|
||||
);
|
||||
|
||||
// Cleans up unused images which are instead inline into the css
|
||||
export function cleanupUnusedCssInlineImages() {
|
||||
return gulp
|
||||
.src(
|
||||
[
|
||||
path.join(buildFolder, "res", "ui", "**", "*.png"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.jpg"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.svg"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.gif"),
|
||||
],
|
||||
{ read: false }
|
||||
)
|
||||
.pipe(gulpIf(fname => fname.history[0].indexOf("noinline") < 0, gulpClean({ force: true })));
|
||||
}
|
||||
import fs from "fs/promises";
|
||||
import path from "path/posix";
|
||||
import gulp from "gulp";
|
||||
import { buildFolder } from "./config.js";
|
||||
import atlas2Json from "./atlas2json.js";
|
||||
|
||||
import childProcess from "child_process";
|
||||
import { promisify } from "util";
|
||||
const exec = promisify(childProcess.exec);
|
||||
const execute = command => {
|
||||
const promise = exec(command, {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
promise.child.stderr.pipe(process.stderr);
|
||||
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";
|
||||
|
||||
// Lossless options
|
||||
const minifyImagesOptsLossless = () => [
|
||||
imageminJpegtran({
|
||||
progressive: true,
|
||||
}),
|
||||
gulpImagemin.svgo({}),
|
||||
gulpImagemin.optipng({
|
||||
optimizationLevel: 3,
|
||||
}),
|
||||
imageminGifsicle({
|
||||
optimizationLevel: 3,
|
||||
colors: 128,
|
||||
}),
|
||||
];
|
||||
|
||||
// Lossy options
|
||||
const minifyImagesOpts = () => [
|
||||
gulpImagemin.mozjpeg({
|
||||
quality: 80,
|
||||
maxMemory: 1024 * 1024 * 8,
|
||||
}),
|
||||
gulpImagemin.svgo({}),
|
||||
imageminPngquant({
|
||||
speed: 1,
|
||||
strip: true,
|
||||
quality: [0.65, 0.9],
|
||||
dithering: false,
|
||||
verbose: false,
|
||||
}),
|
||||
gulpImagemin.optipng({
|
||||
optimizationLevel: 3,
|
||||
}),
|
||||
imageminGifsicle({
|
||||
optimizationLevel: 3,
|
||||
colors: 128,
|
||||
}),
|
||||
];
|
||||
|
||||
// Where the resources folder are
|
||||
const resourcesDestFolder = path.join(buildFolder, "res");
|
||||
|
||||
/**
|
||||
* Determines if an atlas must use lossless compression
|
||||
* @param {string} fname
|
||||
*/
|
||||
function fileMustBeLossless(fname) {
|
||||
return fname.indexOf("lossless") >= 0;
|
||||
}
|
||||
|
||||
/////////////// ATLAS /////////////////////
|
||||
|
||||
export async function buildAtlas() {
|
||||
const config = JSON.stringify("../res_raw/atlas.json");
|
||||
const source = JSON.stringify("../res_raw");
|
||||
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 {
|
||||
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?");
|
||||
}
|
||||
}
|
||||
|
||||
// Converts .atlas LibGDX files to JSON
|
||||
export async function atlasToJson() {
|
||||
atlas2Json("../res_built/atlas");
|
||||
}
|
||||
|
||||
// Copies the atlas to the final destination
|
||||
export function atlas() {
|
||||
return gulp.src(["../res_built/atlas/*.png"]).pipe(gulp.dest(resourcesDestFolder));
|
||||
}
|
||||
|
||||
// Copies the atlas to the final destination after optimizing it (lossy compression)
|
||||
export function atlasOptimized() {
|
||||
return gulp
|
||||
.src(["../res_built/atlas/*.png"])
|
||||
.pipe(
|
||||
gulpIf(
|
||||
fname => fileMustBeLossless(fname.history[0]),
|
||||
gulpImagemin(minifyImagesOptsLossless()),
|
||||
gulpImagemin(minifyImagesOpts())
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(resourcesDestFolder));
|
||||
}
|
||||
|
||||
//////////////////// RESOURCES //////////////////////
|
||||
|
||||
// Copies all resources which are no ui resources
|
||||
export function copyNonImageResources() {
|
||||
return gulp.src(nonImageResourcesGlobs).pipe(gulp.dest(resourcesDestFolder));
|
||||
}
|
||||
|
||||
// Copies all ui resources
|
||||
export function copyImageResources() {
|
||||
return gulp
|
||||
.src(imageResourcesGlobs)
|
||||
.pipe(gulpCached("imgres.copyImageResources"))
|
||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||
}
|
||||
|
||||
// Copies all ui resources and optimizes them
|
||||
export function copyImageResourcesOptimized() {
|
||||
return gulp
|
||||
.src(imageResourcesGlobs)
|
||||
.pipe(
|
||||
gulpIf(
|
||||
fname => fileMustBeLossless(fname.history[0]),
|
||||
gulpImagemin(minifyImagesOptsLossless()),
|
||||
gulpImagemin(minifyImagesOpts())
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||
}
|
||||
|
||||
// Copies all resources and optimizes them
|
||||
export const allOptimized = gulp.parallel(
|
||||
gulp.series(buildAtlas, atlasToJson, atlasOptimized),
|
||||
copyNonImageResources,
|
||||
copyImageResourcesOptimized
|
||||
);
|
||||
|
||||
// Cleans up unused images which are instead inline into the css
|
||||
export function cleanupUnusedCssInlineImages() {
|
||||
return gulp
|
||||
.src(
|
||||
[
|
||||
path.join(buildFolder, "res", "ui", "**", "*.png"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.jpg"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.svg"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.gif"),
|
||||
],
|
||||
{ read: false }
|
||||
)
|
||||
.pipe(gulpIf(fname => fname.history[0].indexOf("noinline") < 0, gulpClean({ force: true })));
|
||||
}
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
import path from "path/posix";
|
||||
import fs from "fs/promises";
|
||||
import YAML from "yaml";
|
||||
import gulp from "gulp";
|
||||
|
||||
import gulpPlumber from "gulp-plumber";
|
||||
import gulpYaml from "gulp-yaml";
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
export const fullBuild = convertToJson;
|
||||
import path from "path/posix";
|
||||
import fs from "fs/promises";
|
||||
import YAML from "yaml";
|
||||
import gulp from "gulp";
|
||||
|
||||
import gulpPlumber from "gulp-plumber";
|
||||
import gulpYaml from "gulp-yaml";
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
export const fullBuild = convertToJson;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user