Move minification into page-writer so it hits everything

This commit is contained in:
Jocelyn Badgley (Twipped) 2020-04-07 10:35:10 -07:00
parent d330d845b1
commit 8f4a862e8e
2 changed files with 57 additions and 35 deletions

View File

@ -3,7 +3,6 @@ const path = require('path');
const fs = require('fs-extra'); const fs = require('fs-extra');
const log = require('fancy-log'); const log = require('fancy-log');
const { minify } = require('html-minifier-terser');
const { resolve, readFile, ENGINE, TYPE } = require('./resolve'); const { resolve, readFile, ENGINE, TYPE } = require('./resolve');
const Handlebars = require('handlebars'); const Handlebars = require('handlebars');
@ -41,6 +40,17 @@ const markdownEngines = {
}; };
function markdown (mode, input, env) { function markdown (mode, input, env) {
if (mode === 'preview') {
input = striptags(input
.replace(/<!--\[[\s\S]*?\]-->/g, '')
.replace(/æææ[\s\S]*?æææ/gi, '')
.replace(/\{!\{([\s\S]*?)\}!\}/mg, ''),
).trim();
if (input.length > 1000) input = input.slice(0, 1000) + '…';
} else {
input = input.replace(/\{!\{([\s\S]*?)\}!\}/mg, (match, contents) => { input = input.replace(/\{!\{([\s\S]*?)\}!\}/mg, (match, contents) => {
try { try {
const result = Handlebars.compile(contents)(env); const result = Handlebars.compile(contents)(env);
@ -51,14 +61,6 @@ function markdown (mode, input, env) {
} }
}); });
if (mode === 'preview') {
input = striptags(input
.replace(/<!--\[[\s\S]*?\]-->/g, '')
.replace(/æææ[\s\S]*?æææ/gi, ''),
).trim();
if (input.length > 1000) input = input.slice(0, 1000) + '…';
input = input ? markdownEngines[mode].render(input) : '';
} else {
input = input.replace(/<!--[[\]]-->/g, ''); input = input.replace(/<!--[[\]]-->/g, '');
} }
@ -87,16 +89,9 @@ function stripIndent (input) {
return input; return input;
} }
const MINIFY_CONFIG = {
conservativeCollapse: true,
collapseWhitespace: true,
minifyCSS: true,
removeComments: true,
removeRedundantAttributes: true,
};
const HANDLEBARS_PARTIALS = { const HANDLEBARS_PARTIALS = {
layout: 'templates/layout.hbs', layout: 'templates/layout.hbs',
list: 'templates/list.hbs',
page: 'templates/page.hbs', page: 'templates/page.hbs',
post: 'templates/post.hbs', post: 'templates/post.hbs',
}; };
@ -123,16 +118,15 @@ module.exports = exports = async function (prod) {
Handlebars.registerHelper('prod', helpers.production()); Handlebars.registerHelper('prod', helpers.production());
Handlebars.registerHelper('rev', helpers.rev()); Handlebars.registerHelper('rev', helpers.rev());
const shrink = (input) => (prod ? minify(input, MINIFY_CONFIG) : input);
const result = { const result = {
[TYPE.HANDLEBARS]: handlebars, [TYPE.HANDLEBARS]: handlebars,
[TYPE.MARKDOWN]: (source, env) => markdown('full', source, env), [TYPE.MARKDOWN]: (source, env) => markdown('full', source, env),
[TYPE.OTHER]: (source) => source, [TYPE.OTHER]: (source) => source,
[ENGINE.PAGE]: (source, env) => shrink(templates.page({ ...env, contents: markdown('full', source, env) })), [ENGINE.LIST]: (source, env) => templates.list({ ...env, contents: markdown('full', source, env) }),
[ENGINE.POST]: (source, env) => shrink(templates.post({ ...env, contents: markdown('full', source, env) })), [ENGINE.PAGE]: (source, env) => templates.page({ ...env, contents: markdown('full', source, env) }),
[ENGINE.HTML]: (source) => shrink(source), [ENGINE.POST]: (source, env) => templates.post({ ...env, contents: markdown('full', source, env) }),
[ENGINE.HTML]: (source) => source,
[ENGINE.OTHER]: (source) => source, [ENGINE.OTHER]: (source) => source,
preview: (source, env) => markdown('preview', source, env), preview: (source, env) => markdown('preview', source, env),
@ -221,14 +215,16 @@ class Injectables {
const self = this; const self = this;
return function (tpath, ...args) { return function (tpath, ...args) {
const { hash, data } = args.pop(); const { hash, data } = args.pop();
const value = args.shift(); const value = args.shift() || this;
const context = Handlebars.createFrame(value || data.root); const frame = Handlebars.createFrame(data);
Object.assign(context, hash || {}); const context = (typeof value === 'object')
? { ...value, ...(hash || {}), _parent: this }
: value;
tpath = self._parsePath(tpath, data.root.local, 'hbs'); tpath = self._parsePath(tpath, data.root.local, 'hbs');
try { try {
const contents = self._template(tpath, Handlebars.compile)(context); const contents = self._template(tpath, Handlebars.compile)(context, { data: frame });
return new Handlebars.SafeString(contents); return new Handlebars.SafeString(contents);
} catch (e) { } catch (e) {
log.error('Could not execute import template ' + tpath, e); log.error('Could not execute import template ' + tpath, e);

View File

@ -2,12 +2,19 @@ const path = require('path');
const Promise = require('bluebird'); const Promise = require('bluebird');
const fs = require('fs-extra'); const fs = require('fs-extra');
const { map, uniq } = require('lodash'); const { map, uniq } = require('lodash');
const { resolve, ROOT } = require('./resolve'); const { resolve, ROOT, TYPE } = require('./resolve');
const { siteInfo } = require(resolve('package.json')); const { siteInfo } = require(resolve('package.json'));
const log = require('fancy-log'); const { minify } = require('html-minifier-terser');
const MINIFY_CONFIG = {
conservativeCollapse: true,
collapseWhitespace: true,
minifyCSS: true,
removeComments: true,
removeRedundantAttributes: true,
};
module.exports = exports = async function writePageContent (engines, pages, posts, prod) { module.exports = exports = async function writePageContent (prod, engines, pages, posts) {
const postIndex = index(posts, engines); const postIndex = index(posts, engines);
await processPages(engines, [ ...posts, ...pages ], postIndex, prod); await processPages(engines, [ ...posts, ...pages ], postIndex, prod);
postIndex.latest = { ...pageJSON(postIndex.latest), content: postIndex.latest.content }; postIndex.latest = { ...pageJSON(postIndex.latest), content: postIndex.latest.content };
@ -20,7 +27,14 @@ function index (posts, engines) {
siblings(posts); siblings(posts);
// fill in post content // fill in post content
posts.forEach((p) => { p.content = engines[p.type](p.source, pageState(p)); }); posts.forEach((p) => {
if (p.type === TYPE.MARKDOWN) {
p.preview = engines.preview(p.source, pageState(p));
p.classes.push(p.preview.trim() ? 'has-preview' : 'no-preview');
p.flags[ p.preview.trim() ? 'has-preview' : 'no-preview' ] = true;
}
p.content = engines[p.type](p.source, pageState(p));
});
const reducedPosts = posts.map(pageJSON); const reducedPosts = posts.map(pageJSON);
@ -88,7 +102,9 @@ function pageJSON (post) {
title: post.meta.title, title: post.meta.title,
subtitle: post.meta.subtitle, subtitle: post.meta.subtitle,
description: post.meta.description, description: post.meta.description,
preview: post.preview,
date: post.dateCreated, date: post.dateCreated,
modified: post.dateModified,
titlecard: post.titlecard, titlecard: post.titlecard,
tags: post.meta.tags, tags: post.meta.tags,
author: post.meta.author, author: post.meta.author,
@ -97,15 +113,25 @@ function pageJSON (post) {
} }
function processPages (engines, pages, posts, prod) { function processPages (engines, pages, posts, prod) {
const shrink = (input) => (prod ? minify(input, MINIFY_CONFIG) : input);
return Promise.map(pages, async (page) => { return Promise.map(pages, async (page) => {
const state = pageState(page, posts); const state = pageState(page.toJson(), posts);
const json = pageJSON(page); const json = pageJSON(page);
try { try {
var html = String(engines[page.engine](page.source, state)); var html = String(engines[page.engine](page.source, state));
} catch (e) { } catch (e) {
throw new Error(`Error while processing page "${page.input}": ${e.message}`); e.message = `Error while processing page "${page.input}": ${e.message}`;
throw e;
}
try {
html = shrink(html);
} catch (e) {
e.message = `Error while minifying page "${page.input}": ${e.message.slice(0, 50)}`;
throw e;
} }
json.content = page.content; json.content = page.content;