Merge pull request #16370 from Bouncey/fix/babelPipeline

fix(rechallenge): Remove JS files from build pipeline when JS is disabled
pull/16789/head
Berkeley Martinez 2018-02-26 12:10:11 -08:00 committed by GitHub
commit 6cf3fb6049
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 17 deletions

View File

@ -1,4 +1,5 @@
import React, { PropTypes, PureComponent } from 'react';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import ns from './ns.json';

View File

@ -1,7 +1,9 @@
import {
attempt,
cond,
flow,
identity,
isError,
matchesProperty,
overEvery,
overSome,
@ -35,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')`
@ -105,13 +107,26 @@ export const replaceNBSP = cond([
[ stubTrue, identity ]
]);
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:', '');
throw new Error(friendlyError);
}
return result;
};
}
export const babelTransformer = cond([
[
testJS$JSX,
flow(
partial(
vinyl.transformHeadTailAndContents,
babelTransformCode
tryTransform(babelTransformCode)
),
partial(vinyl.setExt, 'js')
)

View File

@ -12,7 +12,8 @@ import {
codeLockedSelector,
showPreviewSelector,
testsSelector
testsSelector,
disableJSOnError
} from './';
import {
buildFromFiles,
@ -26,7 +27,8 @@ import {
import {
createErrorObservable,
challengeSelector
challengeSelector,
doActionOnError
} from '../../../redux';
@ -55,13 +57,12 @@ export function updateMainEpic(actions, { getState }, { document }) {
.flatMapLatest(() => buildFromFiles(getState(), true)
.map(frameMain)
.ignoreElements()
.catch(createErrorObservable)
.catch(doActionOnError(() => disableJSOnError()))
);
return Observable.merge(buildAndFrameMain, proxyLogger.map(updateOutput));
});
}
export function executeChallengeEpic(actions, { getState }, { document }) {
return Observable.of(document)
// if document is not defined then none of this epic will run

View File

@ -77,6 +77,7 @@ export const types = createTypes([
'checkChallenge',
createAsyncTypes('submitChallenge'),
'moveToNextChallenge',
'disableJSOnError',
'checkForNextBlock',
// help
@ -153,6 +154,8 @@ export const submitChallengeComplete = createAction(
export const moveToNextChallenge = createAction(types.moveToNextChallenge);
export const checkForNextBlock = createAction(types.checkForNextBlock);
export const disableJSOnError = createAction(types.disableJSOnError);
// help
export const openHelpModal = createAction(types.openHelpModal);
export const closeHelpModal = createAction(types.closeHelpModal);
@ -308,6 +311,7 @@ export default combineReducers(
[
combineActions(
types.classicEditorUpdated,
types.disableJSOnError,
types.modernEditorUpdated
)
]: state => ({

View File

@ -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,11 +44,25 @@ const globalRequires = [
jQuery
];
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(shouldProxyConsole ? proxyLoggerTransformer : identity)

View File

@ -5,11 +5,11 @@ import castToObservable from '../app/utils/cast-to-observable.js';
// createFileStream(
// files: Dictionary[Path, PolyVinyl]
// files: [...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)
);
}
@ -116,7 +116,7 @@ export function setContent(contents, poly) {
};
}
// setExt(contents: String, poly: PolyVinyl) => PolyVinyl
// setExt(ext: String, poly: PolyVinyl) => PolyVinyl
export function setExt(ext, poly) {
checkPoly(poly);
const newPoly = {
@ -129,7 +129,7 @@ export function setExt(ext, poly) {
return newPoly;
}
// setName(contents: String, poly: PolyVinyl) => PolyVinyl
// setName(name: String, poly: PolyVinyl) => PolyVinyl
export function setName(name, poly) {
checkPoly(poly);
const newPoly = {
@ -142,7 +142,7 @@ export function setName(name, poly) {
return newPoly;
}
// setError(contents: String, poly: PolyVinyl) => PolyVinyl
// setError(error: Object, poly: PolyVinyl) => PolyVinyl
export function setError(error, poly) {
invariant(
typeof error === 'object',
@ -166,6 +166,7 @@ export function clearHeadTail(poly) {
};
}
// appendToTail (tail: String, poly: PolyVinyl) => PolyVinyl
export function appendToTail(tail, poly) {
checkPoly(poly);
return {
@ -174,7 +175,7 @@ export function appendToTail(tail, poly) {
};
}
// compileHeadTail(contents: String, poly: PolyVinyl) => PolyVinyl
// compileHeadTail(padding: String, poly: PolyVinyl) => PolyVinyl
export function compileHeadTail(padding = '', poly) {
return clearHeadTail(transformContents(
() => [ poly.head, poly.contents, poly.tail ].join(padding),