OpenAuth_server/views/build.js
2019-03-12 21:06:09 -04:00

195 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const {
lstatSync,
readdirSync,
mkdirSync,
copyFileSync,
writeFileSync,
readFileSync,
exists
} = require('fs')
const {
join,
basename,
dirname
} = require('path')
const isDirectory = source => lstatSync(source).isDirectory()
const getDirectories = source =>
readdirSync(source).map(name => join(source, name)).filter(isDirectory)
function ensureDir(folder) {
try {
if (!isDirectory(folder)) mkdirSync(folder)
} catch (e) {
mkdirSync(folder)
}
}
const fileExists = (filename) => new Promise((yes, no) => exists(filename, (exi) => yes(exi)));
ensureDir("./out")
const sass = require('sass');
function findHead(elm) {
if (elm.tagName === "head") return elm;
for (let i = 0; i < elm.childNodes.length; i++) {
let res = findHead(elm.childNodes[i])
if (res) return res;
}
return undefined;
}
const rollup = require("rollup")
const includepaths = require("rollup-plugin-includepaths")
const typescript = require("rollup-plugin-typescript2");
const resolve = require("rollup-plugin-node-resolve");
const minify = require("html-minifier").minify
const gzipSize = require('gzip-size');
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;
ensureDir(outpath)
const basefile = await file_name(folder, pagename, ["tsx", "ts", "js"]);
let bundle = await rollup.rollup({
input: basefile,
plugins: [
includepaths({
paths: ["shared", "node_modules"]
}),
typescript(),
resolve({
// use "module" field for ES6 module if possible
module: true, // Default: true
// use "jsnext:main" if possible
// legacy field pointing to ES6 module in third-party libraries,
// deprecated in favor of "pkg.module":
// - see: https://github.com/rollup/rollup/wiki/pkg.module
jsnext: true, // Default: false
// use "main" field or index.js, even if it's not an ES6 module
// (needs to be converted from CommonJS to ES6
// see https://github.com/rollup/rollup-plugin-commonjs
main: true, // Default: true
// some package.json files have a `browser` field which
// specifies alternative files to load for people bundling
// for the browser. If that's you, use this option, otherwise
// pkg.browser will be ignored
browser: true, // Default: false
// not all files you want to resolve are .js files
extensions: ['.mjs', '.js', '.jsx', '.json'], // Default: [ '.mjs', '.js', '.json', '.node' ]
// whether to prefer built-in modules (e.g. `fs`, `path`) or
// local ones with the same names
preferBuiltins: false, // Default: true
// If true, inspect resolved files to check that they are
// ES2015 modules
modulesOnly: true, // Default: false
})
],
treeshake: true
})
let { output } = await bundle.generate({
format: "iife",
compact: true
})
let { code } = output[0];
let sass_res = sass.renderSync({
file: folder + `/${pagename}.scss`,
includePaths: ["./node_modules", folder, "./shared"],
outputStyle: "compressed"
})
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");
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")
if (idx < idx2) {
let part1 = html.slice(0, idx)
let part2 = html.slice(idx, idx2);
let part3 = html.slice(idx2, html.length);
html = part1 + css + part2 + script + part3;
} else {
let part1 = html.slice(0, idx2)
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,
useShortDoctype: true
})
let gzips = await gzipSize(result)
writeFileSync(`${outpath}/${pagename}.html`, result)
let stats = {
sass: sass_res.stats,
js: {
chars: code.length
},
css: {
chars: css.length
},
bundle_size: result.length,
gzip_size: gzips
}
writeFileSync(outpath + `/stats.json`, JSON.stringify(stats, null, " "))
}
async function run() {
console.log("Start compiling!");
let pages = getDirectories("./src");
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!")
}
const chokidar = require("chokidar");
if (process.argv.join(" ").toLowerCase().indexOf("watch") >= 0)
chokidar.watch(["./src", "./node_modules", "./package.json", "./package-lock.json"], {
ignoreInitial: true
})
.on("all", () => run());
run()