feat(rechallenge): Remove JS files from build pipline if JS is disabled
This commit is contained in:
@ -50,28 +50,22 @@ const wrapInStyle = partial(transformContents, (content) => (
|
||||
const setExtToHTML = partial(setExt, 'html');
|
||||
const padContentWithJsCatch = partial(compileHeadTail, jsCatch);
|
||||
const padContentWithHTMLCatch = partial(compileHeadTail, htmlCatch);
|
||||
function transformErrorProtect(fn) {
|
||||
return cond([
|
||||
[ matchesProperty('transformError', false), fn ],
|
||||
[ stubTrue, identity ]
|
||||
]);
|
||||
}
|
||||
|
||||
export const jsToHtml = transformErrorProtect(cond([
|
||||
export const jsToHtml = cond([
|
||||
[
|
||||
matchesProperty('ext', 'js'),
|
||||
flow(padContentWithJsCatch, wrapInScript, setExtToHTML)
|
||||
],
|
||||
[ stubTrue, identity ]
|
||||
]));
|
||||
]);
|
||||
|
||||
export const cssToHtml = transformErrorProtect(cond([
|
||||
export const cssToHtml = cond([
|
||||
[
|
||||
matchesProperty('ext', 'css'),
|
||||
flow(padContentWithHTMLCatch, wrapInStyle, setExtToHTML)
|
||||
],
|
||||
[ stubTrue, identity ]
|
||||
]));
|
||||
]);
|
||||
|
||||
// FileStream::concactHtml(
|
||||
// required: [ ...Object ],
|
||||
|
@ -37,7 +37,7 @@ 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'));
|
||||
export const testJS$JSX = overSome(isJS, matchesProperty('ext', 'jsx'));
|
||||
|
||||
// work around the absence of multi-flile editing
|
||||
// this can be replaced with `matchesProperty('ext', 'sass')`
|
||||
@ -107,42 +107,28 @@ export const replaceNBSP = cond([
|
||||
[ stubTrue, identity ]
|
||||
]);
|
||||
|
||||
const transformErrorWarn = '/* __fcc--TransformError__ */';
|
||||
|
||||
function tryJSTransform(wrap = identity, defaultAssignment = 'code') {
|
||||
function tryTransform(wrap = identity) {
|
||||
return function transformWrappedPoly(source) {
|
||||
const result = attempt(wrap, source);
|
||||
if (isError(result)) {
|
||||
const friendlyError = `${result}`
|
||||
.match(/[\w\W]+?\n/)[0]
|
||||
.replace(' unknown:', '');
|
||||
console.error(friendlyError);
|
||||
return `var ${defaultAssignment} = null; ${transformErrorWarn}`;
|
||||
throw new Error(friendlyError);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function checkForTransformError(file) {
|
||||
const potentialError = file.contents.includes(transformErrorWarn);
|
||||
if (potentialError) {
|
||||
return {
|
||||
...vinyl.setTransformError(true, file)
|
||||
};
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
export const babelTransformer = cond([
|
||||
[
|
||||
testJS$JSX,
|
||||
flow(
|
||||
partial(
|
||||
vinyl.transformHeadTailAndContents,
|
||||
tryJSTransform(babelTransformCode, 'JSX')
|
||||
tryTransform(babelTransformCode)
|
||||
),
|
||||
partial(vinyl.setExt, 'js'),
|
||||
checkForTransformError
|
||||
partial(vinyl.setExt, 'js')
|
||||
)
|
||||
],
|
||||
[ stubTrue, identity ]
|
||||
|
@ -42,6 +42,7 @@ export function updateMainEpic(actions, { getState }, { document }) {
|
||||
const proxyLogger = new Subject();
|
||||
const frameMain = createMainFramer(document, getState, proxyLogger);
|
||||
const buildAndFrameMain = actions::ofType(
|
||||
types.unlockUntrustedCode,
|
||||
types.modernEditorUpdated,
|
||||
types.classicEditorUpdated,
|
||||
types.executeChallenge,
|
||||
@ -62,7 +63,6 @@ export function updateMainEpic(actions, { getState }, { document }) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function executeChallengeEpic(actions, { getState }, { document }) {
|
||||
return Observable.of(document)
|
||||
// if document is not defined then none of this epic will run
|
||||
|
@ -6,11 +6,13 @@ import throwers from '../rechallenge/throwers';
|
||||
import {
|
||||
backendFormValuesSelector,
|
||||
challengeTemplateSelector,
|
||||
challengeRequiredSelector
|
||||
challengeRequiredSelector,
|
||||
isJSEnabledSelector
|
||||
} from '../redux';
|
||||
import {
|
||||
applyTransformers,
|
||||
proxyLoggerTransformer
|
||||
proxyLoggerTransformer,
|
||||
testJS$JSX
|
||||
} from '../rechallenge/transformers';
|
||||
import {
|
||||
cssToHtml,
|
||||
@ -42,23 +44,27 @@ const globalRequires = [
|
||||
jQuery
|
||||
];
|
||||
|
||||
function postTransformCheck(file) {
|
||||
if (file.transformError) {
|
||||
// this will enable us to tap into the dipatch pipeline
|
||||
// and disable JS in the preview
|
||||
throw new Error('There was an error whilst transforming your code');
|
||||
}
|
||||
return file;
|
||||
function filterJSIfDisabled(state) {
|
||||
const isJSEnabled = isJSEnabledSelector(state);
|
||||
return file => {
|
||||
if (testJS$JSX(file) && !isJSEnabled) {
|
||||
return null;
|
||||
}
|
||||
return file;
|
||||
};
|
||||
}
|
||||
|
||||
export function buildFromFiles(state, shouldProxyConsole) {
|
||||
const files = filesSelector(state);
|
||||
const required = challengeRequiredSelector(state);
|
||||
const finalRequires = [...globalRequires, ...required ];
|
||||
return createFileStream(files)
|
||||
const requiredFiles = Object.keys(files)
|
||||
.map(key => files[key])
|
||||
.filter(filterJSIfDisabled(state))
|
||||
.filter(Boolean);
|
||||
return createFileStream(requiredFiles)
|
||||
::pipe(throwers)
|
||||
::pipe(applyTransformers)
|
||||
::pipe(postTransformCheck)
|
||||
::pipe(shouldProxyConsole ? proxyLoggerTransformer : identity)
|
||||
::pipe(jsToHtml)
|
||||
::pipe(cssToHtml)
|
||||
|
@ -5,11 +5,11 @@ import castToObservable from '../app/utils/cast-to-observable.js';
|
||||
|
||||
|
||||
// createFileStream(
|
||||
// files: Dictionary[Path, PolyVinyl]
|
||||
// files: List[ PolyVinyl ]
|
||||
// ) => Observable[...Observable[...PolyVinyl]]
|
||||
export function createFileStream(files = {}) {
|
||||
export function createFileStream(files = []) {
|
||||
return Observable.of(
|
||||
Observable.from(Object.keys(files).map(key => files[key]))
|
||||
Observable.from(files)
|
||||
);
|
||||
}
|
||||
|
||||
@ -77,8 +77,7 @@ export function createPoly({
|
||||
path: name + '.' + ext,
|
||||
key: name + ext,
|
||||
contents,
|
||||
error: null,
|
||||
transformError: false
|
||||
error: null
|
||||
};
|
||||
}
|
||||
|
||||
@ -156,19 +155,6 @@ export function setError(error, poly) {
|
||||
error
|
||||
};
|
||||
}
|
||||
// setTransformError(transformError: Boolean, poly: PolyVinyl) => PolyVinyl
|
||||
export function setTransformError(transformError, poly) {
|
||||
invariant(
|
||||
typeof transformError === 'boolean',
|
||||
'transformError must be a boolean, but got %',
|
||||
transformError
|
||||
);
|
||||
checkPoly(poly);
|
||||
return {
|
||||
...poly,
|
||||
transformError
|
||||
};
|
||||
}
|
||||
|
||||
// clearHeadTail(poly: PolyVinyl) => PolyVinyl
|
||||
export function clearHeadTail(poly) {
|
||||
|
Reference in New Issue
Block a user