Feature(challenges): Run user js code through babel

This is a naive implementation.
Ideally we would detect the users environment
and dynamically load only the appropriate plugins
pull/10270/head
Berkeley Martinez 2016-08-18 18:23:44 -07:00
parent bfbe7214cc
commit 7d6250e8af
3 changed files with 48 additions and 7 deletions

View File

@ -1,3 +1,6 @@
import * as babel from 'babel-core';
import presetEs2015 from 'babel-preset-es2015';
import presetReact from 'babel-preset-react';
import { Observable } from 'rx';
/* eslint-disable import/no-unresolved */
import loopProtect from 'loop-protect';
@ -5,6 +8,7 @@ import loopProtect from 'loop-protect';
import { updateContents } from '../../common/utils/polyvinyl';
const babelOptions = { presets: [ presetEs2015, presetReact ] };
loopProtect.hit = function hit(line) {
var err = 'Error: Exiting potential infinite loop at line ' +
line +
@ -26,6 +30,21 @@ const transformersForHtmlJS = {
]
};
const transformersForJs = {
ext: /js/,
transformers: [
{
name: 'babel-transformer',
transformer: function babelTransformer(file) {
const result = babel.transform(file.contents, babelOptions);
return updateContents(
result.code,
file
);
}
}
]
};
// Observable[Observable[File]]::addLoopProtect() => Observable[String]
export default function transformers() {
@ -34,6 +53,16 @@ export default function transformers() {
if (!transformersForHtmlJS.ext.test(file.ext)) {
return Observable.just(file);
}
if (
transformersForJs.ext.test(file.ext) &&
transformersForHtmlJS.ext.test(file.ext)
) {
return Observable.of(
...transformersForHtmlJS.transformers,
...transformersForJs.transformers
)
.reduce((file, context) => context.transformer(file), file);
}
return Observable.from(transformersForHtmlJS.transformers)
.reduce((file, context) => context.transformer(file), file);
}));

View File

@ -33,6 +33,9 @@
"dependencies": {
"accepts": "^1.3.0",
"async": "^1.5.0",
"babel-core": "^6.3.26",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babel-register": "^6.3.0",
"body-parser": "^1.13.2",
"cheerio": "~0.20.0",
@ -120,13 +123,10 @@
"devDependencies": {
"adler32": "~0.1.7",
"babel-cli": "^6.3.17",
"babel-core": "^6.3.26",
"babel-eslint": "^6.1.2",
"babel-istanbul": "^0.11.0",
"babel-loader": "^6.2.1",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babel-preset-stage-0": "^6.3.13",
"browser-sync": "^2.9.12",
"chunk-manifest-webpack-plugin": "0.1.0",
@ -170,4 +170,4 @@
"yargs": "^4.1.0"
},
"snyk": true
}
}

View File

@ -10,6 +10,13 @@ module.exports = {
bundle: './client'
},
devtool: __DEV__ ? 'inline-source-map' : null,
node: {
// Mock Node.js modules that Babel require()s but that we don't
// particularly care about.
fs: 'empty',
module: 'empty',
net: 'empty'
},
output: {
filename: __DEV__ ? 'bundle.js' : 'bundle-[hash].js',
chunkFilename: __DEV__ ?
@ -43,14 +50,19 @@ module.exports = {
'loop-protect': 'loopProtect'
},
plugins: [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(true),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(__DEV__ ? 'development' : 'production')
},
__DEVTOOLS__: !__DEV__
})
}),
// Use browser version of visionmedia-debug
new webpack.NormalModuleReplacementPlugin(
/debug\/node/,
'debug/browser'
),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(true)
]
};