91 lines
2.1 KiB
JavaScript
Raw Normal View History

2020-02-28 10:31:13 -08:00
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;
}
2020-02-28 10:23:13 -08:00
_out () {
this.ext = '.css';
super._out();
}
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,
} ];
}
}