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; 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) { async image (options) {
const output = resolve(options.output); const output = resolve(options.output);
const contents = await readFile(options.input); const contents = await readFile(options.input);

View File

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

View File

@ -34,6 +34,9 @@ const EXT = exports.EXT = {
HBS: '.hbs', HBS: '.hbs',
HTML: '.html', HTML: '.html',
XML: '.xml', XML: '.xml',
CSS: '.css',
SCSS: '.scss',
JS: '.js',
}; };
const { const {
@ -47,21 +50,11 @@ const {
HBS, HBS,
HTML, HTML,
XML, XML,
CSS,
SCSS,
JS,
} = EXT; } = 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 = { const NORMALIZE_EXT = {
[JPG]: JPEG, [JPG]: JPEG,
[M4V]: MP4, [M4V]: MP4,
@ -79,6 +72,7 @@ const isHandlebars = exports.isHandlebars = is(XML, HBS, HTML);
const isMarkdown = exports.isMarkdown = is(MD); const isMarkdown = exports.isMarkdown = is(MD);
const isPage = exports.isPage = is(isHandlebars, isMarkdown); const isPage = exports.isPage = is(isHandlebars, isMarkdown);
const isAsset = exports.isAsset = is(isImage, isVideo); const isAsset = exports.isAsset = is(isImage, isVideo);
const isArtifact = exports.isArtifact = is(CSS, SCSS, JS);
exports.isCleanUrl = is(HBS, MD); exports.isCleanUrl = is(HBS, MD);
@ -88,6 +82,8 @@ const TYPE = exports.TYPE = {
VIDEO: 'VIDEO', VIDEO: 'VIDEO',
HANDLEBARS: 'HANDLEBARS', HANDLEBARS: 'HANDLEBARS',
MARKDOWN: 'MARKDOWN', MARKDOWN: 'MARKDOWN',
SCRIPT: 'SCRIPT',
STYLE: 'STYLE',
OTHER: 'OTHER', OTHER: 'OTHER',
}; };
@ -96,19 +92,23 @@ exports.type = dictMatch({
[TYPE.HANDLEBARS]: isHandlebars, [TYPE.HANDLEBARS]: isHandlebars,
[TYPE.MARKDOWN]: isMarkdown, [TYPE.MARKDOWN]: isMarkdown,
[TYPE.VIDEO]: isVideo, [TYPE.VIDEO]: isVideo,
[TYPE.SCRIPT]: is(JS),
[TYPE.STYLE]: is(SCSS, CSS),
}, TYPE.OTHER); }, TYPE.OTHER);
const KIND = exports.KIND = { const KIND = exports.KIND = {
PAGE: 'PAGE', PAGE: 'PAGE',
ASSET: 'ASSET', ASSET: 'ASSET',
OTHER: 'OTHER', ARTIFACT: 'ARTIFACT',
OTHER: 'OTHER',
}; };
exports.kind = dictMatch({ exports.kind = dictMatch({
[KIND.ASSET]: isAsset, [KIND.ASSET]: isAsset,
[KIND.PAGE]: isPage, [KIND.PAGE]: isPage,
[KIND.ARTIFACT]: isArtifact,
}, KIND.OTHER); }, KIND.OTHER);
@ -129,7 +129,7 @@ exports.engine = dictMatch({
exports.readFile = function readFile (fpath) { exports.readFile = function readFile (fpath) {
fpath = exports.resolve(fpath); fpath = exports.resolve(fpath);
return fs.readFile(fpath).catch((err) => { 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,
} ];
}
}

View File

@ -8,10 +8,7 @@ var content = require('./content');
const everything = content.everything(); const everything = content.everything();
everything.prod = content.everything(true); everything.prod = content.everything(true);
exports.everything = everything; exports.go = series(everything);
var scssTask = require('./scss');
exports.scss = scssTask;
var jsTask = require('./scripts'); var jsTask = require('./scripts');
exports.js = jsTask; exports.js = jsTask;
@ -28,13 +25,11 @@ exports.cloudfront = cloudfront;
/** **************************************************************************************************************** **/ /** **************************************************************************************************************** **/
var prodBuildTask = parallel( var prodBuildTask = parallel(
scssTask.prod,
jsTask.prod, jsTask.prod,
everything.prod, everything.prod,
); );
var devBuildTask = parallel( var devBuildTask = parallel(
scssTask,
jsTask, jsTask,
everything, everything,
); );
@ -56,9 +51,9 @@ function watcher () {
watch([ watch([
'public/**/*', 'public/**/*',
'templates/*.{md,hbs,html}', 'templates/*.{md,hbs,html}',
'scss/*.scss',
], everything); ], everything);
watch('scss/*.scss', scssTask);
watch('js/*.js', jsTask); watch('js/*.js', jsTask);
var forever = require('forever'); var forever = require('forever');

View File

@ -1,59 +0,0 @@
const path = require('path');
const { src, dest } = require('gulp');
const scss = require('gulp-sass');
const rev = require('gulp-rev');
const asyncthrough = require('./lib/through');
const crass = require('./lib/crass');
const concat = require('gulp-concat');
const merge = require('merge-stream');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
// const minifyCSS = require('gulp-minify-css');
const ROOT = path.dirname(__dirname);
const DEST = 'dist/css';
module.exports = exports = function buildScss () {
const scssStream = src([ 'scss/*.scss', '!scss/_*.scss' ])
.pipe(scss({
includePaths: [ path.join(ROOT, 'node_modules') ],
}));
return merge(
scssStream,
src([
require.resolve('magnific-popup/dist/magnific-popup.css'),
]),
)
.pipe(concat('style.css'))
.pipe(postcss([
autoprefixer(),
]))
.pipe(dest(DEST));
};
exports.prod = function buildScssForProd () {
return exports()
.pipe(crass())
.pipe(dest(DEST))
.pipe(rev())
.pipe(dest(DEST))
.pipe(asyncthrough(async (stream, file) => {
// Change rev's original base path back to the public root so that it uses the full
// path as the original file name key in the manifest
var base = path.resolve(ROOT, 'dist');
file.revOrigBase = base;
file.base = base;
stream.push(file);
}))
.pipe(rev.manifest({
merge: true, // Merge with the existing manifest if one exists
}))
.pipe(dest('.'))
;
};

170
package-lock.json generated
View File

@ -1349,32 +1349,6 @@
"tape": "~2.3.2" "tape": "~2.3.2"
} }
}, },
"caller-callsite": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
"integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
"dev": true,
"requires": {
"callsites": "^2.0.0"
},
"dependencies": {
"callsites": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
"dev": true
}
}
},
"caller-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
"integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
"dev": true,
"requires": {
"caller-callsite": "^2.0.0"
}
},
"callsites": { "callsites": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -1902,46 +1876,6 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true "dev": true
}, },
"cosmiconfig": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
"integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
"dev": true,
"requires": {
"import-fresh": "^2.0.0",
"is-directory": "^0.3.1",
"js-yaml": "^3.13.1",
"parse-json": "^4.0.0"
},
"dependencies": {
"import-fresh": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
"integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
"dev": true,
"requires": {
"caller-path": "^2.0.0",
"resolve-from": "^3.0.0"
}
},
"parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
"dev": true,
"requires": {
"error-ex": "^1.3.1",
"json-parse-better-errors": "^1.0.1"
}
},
"resolve-from": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
"dev": true
}
}
},
"crass": { "crass": {
"version": "0.12.3", "version": "0.12.3",
"resolved": "https://registry.npmjs.org/crass/-/crass-0.12.3.tgz", "resolved": "https://registry.npmjs.org/crass/-/crass-0.12.3.tgz",
@ -4693,19 +4627,6 @@
} }
} }
}, },
"gulp-postcss": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-8.0.0.tgz",
"integrity": "sha512-Wtl6vH7a+8IS/fU5W9IbOpcaLqKxd5L1DUOzaPmlnCbX1CrG0aWdwVnC3Spn8th0m8D59YbysV5zPUe1n/GJYg==",
"dev": true,
"requires": {
"fancy-log": "^1.3.2",
"plugin-error": "^1.0.1",
"postcss": "^7.0.2",
"postcss-load-config": "^2.0.0",
"vinyl-sourcemaps-apply": "^0.2.1"
}
},
"gulp-rev": { "gulp-rev": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/gulp-rev/-/gulp-rev-9.0.0.tgz", "resolved": "https://registry.npmjs.org/gulp-rev/-/gulp-rev-9.0.0.tgz",
@ -4740,49 +4661,6 @@
} }
} }
}, },
"gulp-sass": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-4.0.2.tgz",
"integrity": "sha512-q8psj4+aDrblJMMtRxihNBdovfzGrXJp1l4JU0Sz4b/Mhsi2DPrKFYCGDwjIWRENs04ELVHxdOJQ7Vs98OFohg==",
"dev": true,
"requires": {
"chalk": "^2.3.0",
"lodash.clonedeep": "^4.3.2",
"node-sass": "^4.8.3",
"plugin-error": "^1.0.1",
"replace-ext": "^1.0.0",
"strip-ansi": "^4.0.0",
"through2": "^2.0.0",
"vinyl-sourcemaps-apply": "^0.2.0"
},
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
}
},
"through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"dev": true,
"requires": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
}
}
}
},
"gulplog": { "gulplog": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
@ -5127,15 +5005,6 @@
"queue": "6.0.1" "queue": "6.0.1"
} }
}, },
"import-cwd": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
"integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
"dev": true,
"requires": {
"import-from": "^2.1.0"
}
},
"import-fresh": { "import-fresh": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
@ -5146,23 +5015,6 @@
"resolve-from": "^4.0.0" "resolve-from": "^4.0.0"
} }
}, },
"import-from": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
"integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
"dev": true,
"requires": {
"resolve-from": "^3.0.0"
},
"dependencies": {
"resolve-from": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
"dev": true
}
}
},
"imurmurhash": { "imurmurhash": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@ -5377,12 +5229,6 @@
} }
} }
}, },
"is-directory": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
"dev": true
},
"is-extendable": { "is-extendable": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@ -5677,12 +5523,6 @@
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"dev": true "dev": true
}, },
"json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
"dev": true
},
"json-schema": { "json-schema": {
"version": "0.2.3", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
@ -7290,16 +7130,6 @@
} }
} }
}, },
"postcss-load-config": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz",
"integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==",
"dev": true,
"requires": {
"cosmiconfig": "^5.0.0",
"import-cwd": "^2.0.0"
}
},
"postcss-value-parser": { "postcss-value-parser": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz",

View File

@ -55,9 +55,7 @@
"gulp-concat": "~2.6.1", "gulp-concat": "~2.6.1",
"gulp-filter": "~6.0.0", "gulp-filter": "~6.0.0",
"gulp-minify": "~3.1.0", "gulp-minify": "~3.1.0",
"gulp-postcss": "~8.0.0",
"gulp-rev": "~9.0.0", "gulp-rev": "~9.0.0",
"gulp-sass": "~4.0.2",
"handlebars": "~4.7.3", "handlebars": "~4.7.3",
"hbs-kit": "~1.2.0", "hbs-kit": "~1.2.0",
"html-minifier-terser": "~5.0.4", "html-minifier-terser": "~5.0.4",
@ -76,6 +74,7 @@
"plugin-error": "~1.0.1", "plugin-error": "~1.0.1",
"png-to-ico": "~2.0.6", "png-to-ico": "~2.0.6",
"popper.js": "~1.16.0", "popper.js": "~1.16.0",
"postcss": "~7.0.27",
"rev-hash": "~3.0.0", "rev-hash": "~3.0.0",
"rev-path": "~2.0.0", "rev-path": "~2.0.0",
"rollup": "~1.31.1", "rollup": "~1.31.1",

View File

@ -102,3 +102,4 @@ $header-full-height: 100px;
@import "./markup"; @import "./markup";
@import "./pager"; @import "./pager";
|node_modules/magnific-popup/dist/magnific-popup.css|