mirror of
https://github.com/osmarks/website
synced 2025-09-01 10:17:56 +00:00
rework compilation process
- minify (some) JS - minify HTML output (markdown-it output, for example, isn't minified) - switch stylus to SASS as stylus is not well maintained Probably worth considering too: - pre-gzip everything, reconfigure webserver to use that - better parallelization
This commit is contained in:
67
src/index.js
67
src/index.js
@@ -1,4 +1,3 @@
|
||||
const fs = require("fs")
|
||||
const fsp = require("fs").promises
|
||||
const fse = require("fs-extra")
|
||||
const MarkdownIt = require("markdown-it")
|
||||
@@ -7,15 +6,16 @@ const path = require("path")
|
||||
const matter = require("gray-matter")
|
||||
const mustache = require("mustache")
|
||||
const globalData = require("./global.json")
|
||||
const stylus = require("stylus")
|
||||
const util = require("util")
|
||||
const sass = require("sass")
|
||||
const R = require("ramda")
|
||||
const dayjs = require("dayjs")
|
||||
const customParseFormat = require("dayjs/plugin/customParseFormat")
|
||||
const nanoid = require("nanoid")
|
||||
const htmlMinifier = require("html-minifier").minify
|
||||
const terser = require("terser")
|
||||
const { minify } = require("html-minifier")
|
||||
|
||||
dayjs.extend(customParseFormat)
|
||||
const stylusRender = util.promisify(stylus.render)
|
||||
|
||||
const root = path.join(__dirname, "..")
|
||||
const templateDir = path.join(root, "templates")
|
||||
@@ -32,7 +32,41 @@ const removeExtension = x => x.replace(/\.[^/.]+$/, "")
|
||||
|
||||
const readFile = path => fsp.readFile(path, { encoding: "utf8" })
|
||||
const md = new MarkdownIt()
|
||||
const minifyHTML = x => htmlMinifier(x, {
|
||||
collapseWhitespace: true,
|
||||
sortAttributes: true,
|
||||
sortClassName: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeAttributeQuotes: true,
|
||||
conservativeCollapse: true,
|
||||
collapseBooleanAttributes: true
|
||||
})
|
||||
const renderMarkdown = x => md.render(x)
|
||||
// basically just whitespace removal - fast and still pretty good versus unminified code
|
||||
const minifyJS = (x, filename) => {
|
||||
const res = terser.minify(x, {
|
||||
mangle: true,
|
||||
compress: true,
|
||||
sourceMap: {
|
||||
filename,
|
||||
url: filename + ".map"
|
||||
}
|
||||
})
|
||||
if (res.warnings) {
|
||||
for (const warn of res.warnings) {
|
||||
console.warn("MINIFY WARNING:", warn)
|
||||
}
|
||||
}
|
||||
if (res.error) {
|
||||
console.warn("MINIFY ERROR:", res.error)
|
||||
throw new Error("could not minify " + filename)
|
||||
}
|
||||
return res
|
||||
}
|
||||
const minifyJSFile = (incode, filename, out) => {
|
||||
const res = minifyJS(incode, filename)
|
||||
return Promise.all([ fsp.writeFile(out, res.code), fsp.writeFile(out + ".map", res.map) ])
|
||||
}
|
||||
|
||||
const parseFrontMatter = content => {
|
||||
const raw = matter(content)
|
||||
@@ -60,7 +94,7 @@ const applyTemplate = async (template, input, getOutput, options = {}) => {
|
||||
if (options.processMeta) { options.processMeta(page.data) }
|
||||
if (options.processContent) { page.content = options.processContent(page.content) }
|
||||
const rendered = template({ ...globalData, ...page.data, content: page.content })
|
||||
await fsp.writeFile(await getOutput(page), rendered)
|
||||
await fsp.writeFile(await getOutput(page), minifyHTML(rendered))
|
||||
return page.data
|
||||
}
|
||||
|
||||
@@ -86,7 +120,7 @@ const processExperiments = templates => {
|
||||
|
||||
const processBlog = templates => {
|
||||
return loadDir(blogDir, async (file, basename) => {
|
||||
return applyTemplate(templates.experiment, file, async page => {
|
||||
return applyTemplate(templates.blogPost, file, async page => {
|
||||
const out = path.join(outDir, page.data.slug)
|
||||
await fse.ensureDir(out)
|
||||
return path.join(out, "index.html")
|
||||
@@ -114,18 +148,27 @@ const processAssets = async templates => {
|
||||
|
||||
const copyAsset = subpath => fse.copy(path.join(assetsDir, subpath), path.join(outAssets, subpath))
|
||||
// Directly copy images, JS, CSS
|
||||
await copyAsset("images")
|
||||
await copyAsset("js")
|
||||
await copyAsset("css")
|
||||
await Promise.all([await copyAsset("images"), await copyAsset("css")])
|
||||
|
||||
const jsDir = path.join(assetsDir, "js")
|
||||
const jsOutDir = path.join(outAssets, "js")
|
||||
await Promise.all((await fsp.readdir(jsDir)).map(async file => {
|
||||
const fullpath = path.join(jsDir, file)
|
||||
await minifyJSFile(await readFile(fullpath), file, path.join(jsOutDir, file))
|
||||
}))
|
||||
|
||||
const serviceWorker = mustache.render(await readFile(path.join(assetsDir, "sw.js")), globalData)
|
||||
await fsp.writeFile(path.join(outDir, "sw.js"), serviceWorker)
|
||||
await minifyJSFile(serviceWorker, "sw.js", path.join(outDir, "sw.js"))
|
||||
}
|
||||
|
||||
globalData.renderDate = date => date.format("DD/MM/YYYY")
|
||||
|
||||
const run = async () => {
|
||||
const css = await stylusRender(await readFile(path.join(root, "style.styl")), { compress: true })
|
||||
const css = await sass.renderSync({
|
||||
data: await readFile(path.join(root, "style.sass")),
|
||||
outputStyle: "compressed",
|
||||
indentedSyntax: true
|
||||
}).css
|
||||
globalData.css = css
|
||||
|
||||
const templates = await loadDir(templateDir, async fullPath => pug.compile(await readFile(fullPath), { filename: fullPath }))
|
||||
@@ -143,4 +186,4 @@ const run = async () => {
|
||||
await fsp.writeFile(path.join(outDir, "buildID.txt"), buildID)
|
||||
}
|
||||
|
||||
run()
|
||||
run()
|
||||
|
Reference in New Issue
Block a user