OpenAuth_server/views/build.js

171 lines
4.7 KiB
JavaScript
Raw Normal View History

2020-03-09 17:46:41 +00:00
const {
lstatSync,
readdirSync,
mkdirSync,
copyFileSync,
writeFileSync,
readFileSync,
2020-08-07 14:16:39 +00:00
exists,
} = require("fs");
const { join, basename, dirname } = require("path");
2020-03-09 17:46:41 +00:00
2020-08-07 14:16:39 +00:00
const isDirectory = (source) => lstatSync(source).isDirectory();
const getDirectories = (source) =>
readdirSync(source)
.map((name) => join(source, name))
.filter(isDirectory);
2020-03-09 17:46:41 +00:00
function ensureDir(folder) {
try {
2020-08-07 14:16:39 +00:00
if (!isDirectory(folder)) mkdirSync(folder);
2020-03-09 17:46:41 +00:00
} catch (e) {
2020-08-07 14:16:39 +00:00
mkdirSync(folder);
2020-03-09 17:46:41 +00:00
}
}
2020-08-07 14:16:39 +00:00
const fileExists = (filename) =>
new Promise((yes, no) => exists(filename, (exi) => yes(exi)));
ensureDir("./out");
2020-03-09 17:46:41 +00:00
2020-08-07 14:16:39 +00:00
const sass = require("sass");
2020-03-09 17:46:41 +00:00
function findHead(elm) {
if (elm.tagName === "head") return elm;
for (let i = 0; i < elm.childNodes.length; i++) {
2020-08-07 14:16:39 +00:00
let res = findHead(elm.childNodes[i]);
2020-03-09 17:46:41 +00:00
if (res) return res;
}
return undefined;
}
2020-08-07 14:16:39 +00:00
const rollup = require("rollup");
const includepaths = require("rollup-plugin-includepaths");
2020-03-09 17:46:41 +00:00
const typescript = require("rollup-plugin-typescript2");
const resolve = require("rollup-plugin-node-resolve");
2020-08-07 14:16:39 +00:00
const minify = require("html-minifier").minify;
const gzipSize = require("gzip-size");
2020-03-09 17:46:41 +00:00
async function file_name(folder, name, exts) {
for (let ext of exts) {
let basefile = `${folder}/${name}.${ext}`;
if (await fileExists(basefile)) return basefile;
}
return null;
}
async function buildPage(folder) {
const pagename = basename(folder);
const outpath = "./out/" + pagename;
2020-08-07 14:16:39 +00:00
ensureDir(outpath);
2020-03-09 17:46:41 +00:00
const basefile = await file_name(folder, pagename, ["tsx", "ts", "js"]);
let bundle = await rollup.rollup({
input: basefile,
plugins: [
includepaths({
2020-08-07 14:16:39 +00:00
paths: ["shared", "node_modules"],
2020-03-09 17:46:41 +00:00
}),
typescript(),
resolve({
// not all files you want to resolve are .js files
2020-08-07 14:16:39 +00:00
extensions: [".mjs", ".js", ".jsx", ".json"], // Default: [ '.mjs', '.js', '.json', '.node' ]
2020-03-09 17:46:41 +00:00
// whether to prefer built-in modules (e.g. `fs`, `path`) or
// local ones with the same names
2020-08-07 14:16:39 +00:00
preferBuiltins: false, // Default: true
}),
2020-03-09 17:46:41 +00:00
],
2020-08-07 14:16:39 +00:00
treeshake: true,
});
2020-03-09 17:46:41 +00:00
let { output } = await bundle.generate({
format: "iife",
2020-08-07 14:16:39 +00:00
compact: true,
});
2020-03-09 17:46:41 +00:00
let { code } = output[0];
let sass_res = sass.renderSync({
file: folder + `/${pagename}.scss`,
includePaths: ["./node_modules", folder, "./shared"],
2020-08-07 14:16:39 +00:00
outputStyle: "compressed",
});
2020-03-09 17:46:41 +00:00
let css = "<style>\n" + sass_res.css.toString("utf8") + "\n</style>\n";
let script = "<script>\n" + code + "\n</script>\n";
let html = readFileSync(`${folder}/${pagename}.hbs`).toString("utf8");
2020-08-07 14:16:39 +00:00
let idx = html.indexOf("</head>");
if (idx < 0) throw new Error("No head element found");
let idx2 = html.indexOf("</body>");
if (idx2 < 0) throw new Error("No body element found");
2020-03-09 17:46:41 +00:00
if (idx < idx2) {
2020-08-07 14:16:39 +00:00
let part1 = html.slice(0, idx);
2020-03-09 17:46:41 +00:00
let part2 = html.slice(idx, idx2);
let part3 = html.slice(idx2, html.length);
html = part1 + css + part2 + script + part3;
} else {
2020-08-07 14:16:39 +00:00
let part1 = html.slice(0, idx2);
2020-03-09 17:46:41 +00:00
let part2 = html.slice(idx2, idx);
let part3 = html.slice(idx, html.length);
html = part1 + script + part2 + css + part3;
}
let result = minify(html, {
removeAttributeQuotes: true,
collapseWhitespace: true,
html5: true,
keepClosingSlash: true,
minifyCSS: false,
minifyJS: false,
removeComments: true,
2020-08-07 14:16:39 +00:00
useShortDoctype: true,
});
2020-03-09 17:46:41 +00:00
2020-08-07 14:16:39 +00:00
let gzips = await gzipSize(result);
writeFileSync(`${outpath}/${pagename}.html`, result);
2020-03-09 17:46:41 +00:00
let stats = {
sass: sass_res.stats,
js: {
2020-08-07 14:16:39 +00:00
chars: code.length,
2020-03-09 17:46:41 +00:00
},
css: {
2020-08-07 14:16:39 +00:00
chars: css.length,
2020-03-09 17:46:41 +00:00
},
bundle_size: result.length,
2020-08-07 14:16:39 +00:00
gzip_size: gzips,
};
2020-03-09 17:46:41 +00:00
2020-08-07 14:16:39 +00:00
writeFileSync(outpath + `/stats.json`, JSON.stringify(stats, null, " "));
2020-03-09 17:46:41 +00:00
}
async function run() {
console.log("Start compiling!");
let pages = getDirectories("./src");
2020-08-07 14:16:39 +00:00
await Promise.all(
pages.map(async (e) => {
try {
await buildPage(e);
} catch (er) {
console.error("Failed compiling", basename(e));
console.log(er);
}
})
);
console.log("Finished compiling!");
2020-03-09 17:46:41 +00:00
}
const chokidar = require("chokidar");
if (process.argv.join(" ").toLowerCase().indexOf("watch") >= 0)
2020-08-07 14:16:39 +00:00
chokidar
.watch(
["./src", "./node_modules", "./package.json", "./package-lock.json"],
{
ignoreInitial: true,
}
)
2020-03-09 17:46:41 +00:00
.on("all", () => run());
2020-08-07 14:16:39 +00:00
run();