mirror of https://github.com/status-im/metro.git
135 lines
3.9 KiB
JavaScript
135 lines
3.9 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* Note: This is a fork of the fb-specific transform.js
|
|
*/
|
|
'use strict';
|
|
|
|
const babel = require('babel-core');
|
|
const externalHelpersPlugin = require('babel-plugin-external-helpers');
|
|
const fs = require('fs');
|
|
const makeHMRConfig = require('babel-preset-react-native/configs/hmr');
|
|
const resolvePlugins = require('babel-preset-react-native/lib/resolvePlugins');
|
|
const inlineRequiresPlugin = require('fbjs-scripts/babel-6/inline-requires');
|
|
const json5 = require('json5');
|
|
const path = require('path');
|
|
|
|
/**
|
|
* 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.
|
|
//
|
|
// NOTE: we're not reading the project's .babelrc here. We leave it up to
|
|
// Babel to do that automatically and apply the transforms accordingly
|
|
// (which works because we pass in `filename` and `sourceFilename` to
|
|
// Babel when we transform).
|
|
let projectBabelRCPath;
|
|
if (projectRoots && projectRoots.length > 0) {
|
|
projectBabelRCPath = path.resolve(projectRoots[0], '.babelrc');
|
|
}
|
|
|
|
// If a .babelrc file doesn't exist in the project,
|
|
// use the Babel config provided with react-native.
|
|
if (!projectBabelRCPath || !fs.existsSync(projectBabelRCPath)) {
|
|
babelRC = json5.parse(
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, 'react-packager', 'rn-babelrc.json'))
|
|
);
|
|
|
|
// Require the babel-preset's listed in the default babel config
|
|
babelRC.presets = babelRC.presets.map((preset) => require('babel-preset-' + preset));
|
|
babelRC.plugins = resolvePlugins(babelRC.plugins);
|
|
}
|
|
|
|
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,
|
|
sourceFileName: 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,
|
|
map: result.map,
|
|
filename: filename,
|
|
};
|
|
} 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;
|