Now building scss within the content processor

This commit is contained in:
Jocelyn Badgley (Twipped)
2020-02-28 09:15:21 -08:00
parent 133cd48bbc
commit 6ca289017f
9 changed files with 116 additions and 257 deletions

View File

@@ -33,6 +33,13 @@ const actions = {
return body;
},
async write ({ output, content }) {
output = resolve(output);
await fs.ensureDir(path.dirname(output));
await fs.writeFile(output, content);
return Buffer.from(content);
},
async image (options) {
const output = resolve(options.output);
const contents = await readFile(options.input);

View File

@@ -10,6 +10,7 @@ const evaluate = require('./evaluate');
const { resolve } = require('./resolve');
const favicon = require('./favicon');
const scss = require('./scss');
const svg = require('./svg');
exports.everything = function (prod = false) {
@@ -28,6 +29,7 @@ exports.everything = function (prod = false) {
// compile all tasks to be completed
const tasks = await Promise.all([
PublicFiles.tasks,
scss(prod),
svg(prod),
favicon(prod),
]);

View File

@@ -34,6 +34,9 @@ const EXT = exports.EXT = {
HBS: '.hbs',
HTML: '.html',
XML: '.xml',
CSS: '.css',
SCSS: '.scss',
JS: '.js',
};
const {
@@ -47,21 +50,11 @@ const {
HBS,
HTML,
XML,
CSS,
SCSS,
JS,
} = EXT;
exports.RE = {
JPG: re(/.jpg$/),
JPEG: re(/.jpeg$/),
PNG: re(/.png$/),
GIF: re(/.gif$/),
MP4: re(/.mp4$/),
M4V: re(/.m4v$/),
MD: re(/.md$/),
HBS: re(/.hbs$/),
HTML: re(/.html$/),
XML: re(/.xml$/),
};
const NORMALIZE_EXT = {
[JPG]: JPEG,
[M4V]: MP4,
@@ -79,6 +72,7 @@ const isHandlebars = exports.isHandlebars = is(XML, HBS, HTML);
const isMarkdown = exports.isMarkdown = is(MD);
const isPage = exports.isPage = is(isHandlebars, isMarkdown);
const isAsset = exports.isAsset = is(isImage, isVideo);
const isArtifact = exports.isArtifact = is(CSS, SCSS, JS);
exports.isCleanUrl = is(HBS, MD);
@@ -88,6 +82,8 @@ const TYPE = exports.TYPE = {
VIDEO: 'VIDEO',
HANDLEBARS: 'HANDLEBARS',
MARKDOWN: 'MARKDOWN',
SCRIPT: 'SCRIPT',
STYLE: 'STYLE',
OTHER: 'OTHER',
};
@@ -96,19 +92,23 @@ exports.type = dictMatch({
[TYPE.HANDLEBARS]: isHandlebars,
[TYPE.MARKDOWN]: isMarkdown,
[TYPE.VIDEO]: isVideo,
[TYPE.SCRIPT]: is(JS),
[TYPE.STYLE]: is(SCSS, CSS),
}, TYPE.OTHER);
const KIND = exports.KIND = {
PAGE: 'PAGE',
ASSET: 'ASSET',
OTHER: 'OTHER',
PAGE: 'PAGE',
ASSET: 'ASSET',
ARTIFACT: 'ARTIFACT',
OTHER: 'OTHER',
};
exports.kind = dictMatch({
[KIND.ASSET]: isAsset,
[KIND.PAGE]: isPage,
[KIND.ASSET]: isAsset,
[KIND.PAGE]: isPage,
[KIND.ARTIFACT]: isArtifact,
}, KIND.OTHER);
@@ -129,7 +129,7 @@ exports.engine = dictMatch({
exports.readFile = function readFile (fpath) {
fpath = exports.resolve(fpath);
return fs.readFile(fpath).catch((err) => {
throw new Error(err.trace);
throw new Error(err.message);
});
};

84
gulp/content/scss.js Normal file
View File

@@ -0,0 +1,84 @@
const glob = require('../lib/glob');
const { ROOT, readFile, resolve } = require('./resolve');
const actions = require('./actions');
const File = require('./file');
const sass = require('node-sass');
const Promise = require('bluebird');
const postcss = require('postcss');
const autoprefixer = require('autoprefixer');
const crass = require('crass');
module.exports = exports = async function styles (prod) {
const files = await Promise.map(glob('scss/*.scss', { cwd: ROOT, nodir: true }), async (filepath) => {
const f = new Sass(filepath);
if (f.preprocessed) return false;
await f.load(prod);
return f;
}).filter(Boolean);
const tasks = files.map((f) => f.tasks()).flat();
return tasks;
};
class Sass extends File {
_dir (dir) {
dir = dir.split('/');
if (dir[0] === 'scss') dir.shift();
dir.unshift('css');
return dir;
}
async load (prod) {
let contents = (await readFile(this.input).catch(() => null)).toString('utf8');
for (const [ match, fpath ] of contents.matchAll(/\|(.+?)\|/)) {
const insert = await readFile(fpath);
contents = contents.replace(match, insert);
}
const sassOptions = {
data: contents,
file: resolve(this.input),
includePaths: [
resolve(this.cwd),
resolve('node_modules'),
],
sourceMapEmbed: true,
};
let { css } = await (new Promise((resolve, reject) => { // eslint-disable-line no-shadow
sass.render(sassOptions, (err, result) => (
err ? reject(err) : resolve(result)
));
}));
if (prod) {
css = (await postcss([ autoprefixer ]).process(css, {
from: this.input,
to: this.out,
map: { inline: true },
})).css;
var parsed = crass.parse(css);
parsed = parsed.optimize({ O1: true });
// if (options.pretty) parsed = parsed.pretty();
css = Buffer.from(parsed.toString());
}
this.content = css;
}
tasks () {
return [ {
input: this.input,
output: this.out,
content: this.content,
action: actions.write,
nocache: true,
} ];
}
}