feat(sass): Enable client-side sass compiling (#16747)

This commit is contained in:
Stuart Taylor
2018-02-19 20:41:01 +00:00
committed by Quincy Larson
parent 3131c55782
commit 1a5cab57a1
4 changed files with 86 additions and 38 deletions

View File

@@ -95,7 +95,7 @@ export function concactHtml(required, template) {
const body = source
.flatMap(file => file.reduce((body, file) => {
return body + file.contents + htmlCatch;
return body + file.contents + file.tail + htmlCatch;
}, ''))
.map(source => ({ source }))
.map(createBody);

View File

@@ -1,4 +1,13 @@
import _ from 'lodash';
import {
cond,
flow,
identity,
matchesProperty,
overEvery,
overSome,
partial,
stubTrue
} from 'lodash';
import * as babel from 'babel-core';
import presetEs2015 from 'babel-preset-es2015';
@@ -24,15 +33,34 @@ function loopProtectHit(line) {
const console$logReg = /(?:\b)console(\.log\S+)/g;
const NBSPReg = new RegExp(String.fromCharCode(160), 'g');
const isJS = _.matchesProperty('ext', 'js');
const testHTMLJS = _.overSome(isJS, _.matchesProperty('ext', 'html'));
const testJS$JSX = _.overSome(isJS, _.matchesProperty('ext', 'jsx'));
const isJS = matchesProperty('ext', 'js');
const testHTMLJS = overSome(isJS, matchesProperty('ext', 'html'));
const testJS$JSX = overSome(isJS, matchesProperty('ext', 'jsx'));
// work around the absence of multi-flile editing
// this can be replaced with `matchesProperty('ext', 'sass')`
// when the time comes
const testSASS = file => (/type='text\/sass'/i).test(file.contents);
// This can be done in the transformer when we have multi-file editing
const browserSassCompiler = `
<script>
var styleTags = [ ...document.querySelectorAll('style') ];
[].slice.call(styleTags, 1).forEach(
function compileSass(tag) {
var scss = tag.innerHTML;
Sass.compile(scss, function(result) {
tag.type = 'text/css';
tag.innerHTML = result.text;
});
}
)
</script>
`;
// if shouldProxyConsole then we change instances of console log
// to `window.__console.log`
// this let's us tap into logging into the console.
// currently we only do this to the main window and not the test window
export const proxyLoggerTransformer = _.partial(
export const proxyLoggerTransformer = partial(
vinyl.transformHeadTailAndContents,
source => (
source.replace(console$logReg, (match, methodCall) => {
@@ -40,7 +68,7 @@ export const proxyLoggerTransformer = _.partial(
})),
);
const addLoopProtect = _.partial(
const addLoopProtect = partial(
vinyl.transformContents,
contents => {
/* eslint-disable import/no-unresolved */
@@ -51,11 +79,11 @@ const addLoopProtect = _.partial(
}
);
export const addLoopProtectHtmlJsJsx = _.cond([
export const addLoopProtectHtmlJsJsx = cond([
[
_.overEvery(
overEvery(
testHTMLJS,
_.partial(
partial(
vinyl.testContents,
contents => contents.toLowerCase().includes('<script>')
)
@@ -63,38 +91,50 @@ export const addLoopProtectHtmlJsJsx = _.cond([
addLoopProtect
],
[ testJS$JSX, addLoopProtect ],
[ _.stubTrue, _.identity ]
[ stubTrue, identity ]
]);
export const replaceNBSP = _.cond([
export const replaceNBSP = cond([
[
testHTMLJS,
_.partial(
partial(
vinyl.transformContents,
contents => contents.replace(NBSPReg, ' ')
)
],
[ _.stubTrue, _.identity ]
[ stubTrue, identity ]
]);
export const babelTransformer = _.cond([
export const babelTransformer = cond([
[
testJS$JSX,
_.flow(
_.partial(
flow(
partial(
vinyl.transformHeadTailAndContents,
babelTransformCode
),
_.partial(vinyl.setExt, 'js')
partial(vinyl.setExt, 'js')
)
],
[ _.stubTrue, _.identity ]
[ stubTrue, identity ]
]);
export const sassTransformer = cond([
[
testSASS,
partial(
vinyl.appendToTail,
browserSassCompiler
)
],
[ stubTrue, identity ]
]);
export const _transformers = [
addLoopProtectHtmlJsJsx,
replaceNBSP,
babelTransformer
babelTransformer,
sassTransformer
];
export function applyTransformers(file, transformers = _transformers) {

View File

@@ -166,6 +166,14 @@ export function clearHeadTail(poly) {
};
}
export function appendToTail(tail, poly) {
checkPoly(poly);
return {
...poly,
tail: poly.tail.concat(tail)
};
}
// compileHeadTail(contents: String, poly: PolyVinyl) => PolyVinyl
export function compileHeadTail(padding = '', poly) {
return clearHeadTail(transformContents(