Skip to content

Instantly share code, notes, and snippets.

@asdacap
Created March 9, 2017 14:42
Show Gist options
  • Save asdacap/c9825c807563b4585bbf4bdd06789888 to your computer and use it in GitHub Desktop.
Save asdacap/c9825c807563b4585bbf4bdd06789888 to your computer and use it in GitHub Desktop.
ReactNative transformer that works well with typescript, or any preprocessor that output sourcemaps, which should then be fed to react-native packager.
/**
* Its a copy of the built in transformer, but instead of a somewhat
* two stage approach, it pass directly to babel, which allow things like
* sourceMap merging.
*
* Also, it assume .babelrc is always available
*/
const babel = require('babel-core');
const externalHelpersPlugin = require('babel-plugin-external-helpers');
const fs = require('fs');
const generate = require('babel-generator').default;
const inlineRequiresPlugin = require('babel-preset-fbjs/plugins/inline-requires');
const json5 = require('json5');
const makeHMRConfig = require('babel-preset-react-native/configs/hmr');
const path = require('path');
const resolvePlugins = require('babel-preset-react-native/lib/resolvePlugins');
const convertSourceMap = require('convert-source-map');
const _ = require('lodash');
/**
* Return a memoized function that checks for the existence of a
* project level .babelrc file, and if it doesn't exist, reads the
* default RN babelrc file and uses that.
*/
const getBabelRC = (function() {
let babelRC = null;
return function _getBabelRC(projectRoots) {
if (babelRC !== null) {
return babelRC;
}
babelRC = { plugins: [] }; // empty babelrc
// Let's look for the .babelrc in the first project root.
// In the future let's look into adding a command line option to specify
// this location.
let projectBabelRCPath;
if (projectRoots && projectRoots.length > 0) {
projectBabelRCPath = path.resolve(projectRoots[0], '.babelrc');
}
babelRC.extends = projectBabelRCPath;
return babelRC;
};
})();
/**
* Given a filename and options, build a Babel
* config object with the appropriate plugins.
*/
function buildBabelConfig(filename, options) {
const babelRC = getBabelRC(options.projectRoots);
const extraConfig = {
filename,
};
let config = Object.assign({}, babelRC, extraConfig);
// Add extra plugins
const extraPlugins = [externalHelpersPlugin];
var inlineRequires = options.inlineRequires;
var blacklist = inlineRequires && inlineRequires.blacklist;
if (inlineRequires && !(blacklist && filename in blacklist)) {
extraPlugins.push(inlineRequiresPlugin);
}
config.plugins = extraPlugins.concat(config.plugins);
if (options.hot) {
const hmrConfig = makeHMRConfig(options, filename);
config = Object.assign({}, config, hmrConfig);
}
return Object.assign({}, babelRC, config);
}
function transform(src, filename, options) {
options = options || {};
const OLD_BABEL_ENV = process.env.BABEL_ENV;
process.env.BABEL_ENV = options.dev ? 'development' : 'production';
try {
const babelConfig = buildBabelConfig(filename, options);
const result = babel.transform(src, babelConfig);
return {
ast: result.ast,
code: result.code,
filename,
map: result.map
};
} finally {
process.env.BABEL_ENV = OLD_BABEL_ENV;
}
}
module.exports = function(data, callback) {
let result;
try {
result = transform(data.sourceCode, data.filename, data.options);
} catch (e) {
callback(e);
return;
}
callback(null, result);
};
// export for use in jest
module.exports.transform = transform;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment