mirror of
https://github.com/status-im/metro.git
synced 2025-02-08 17:24:54 +00:00
Summary:
- [x] Explain the **motivation** for making this change.
- [x] Provide a **test plan** demonstrating that the code is solid.
- [x] Match the **code formatting** of the rest of the codebase.
- [x] Target the `master` branch, NOT a "stable" branch.
I have a need to bundle a pre-optimized external lib with my RN application. Until RN 0.42 I had been using a .babelignore to prevent the packager from trying to optimize this file and choke.
It seems in 0.42 and higher I'm no longer allowed to ignore the file.
This issue has also been reported as #12071
Details on the reasoning for this patch can be found in the issue I originally filed: https://github.com/facebook/react-native/issues/13168
What existing problem does the pull request solve?
This PR restores the functionality with babel ignoring files that existed in 0.41 before this patch:
0849f84df2 (diff-4676ea0b3c55c65c3929aa993144f07f)
Here's a screenshot of this patch properly ignoring the file I referenced in https://github.com/facebook/react-native/issues/13168 to be ignored.
![screen shot 2017-04-27 at 12 48 32 am](https://cloud.githubusercontent.com/assets/21967/25469653/524dbc0c-2ae3-11e7-81a6-faca2f4d21fe.png)
The patch relies on the `ignored` value of the call to `babel.transform` and if true returns the src in a object per instruction from loganfsmyth from BabelJS core team.
To test, add a file to the `ignore` array of a `.babelrc` file in a React Native project with this fork.
I was unable to locate a test file for the transformer.js
Fixes #12071, #13168
Closes https://github.com/facebook/react-native/pull/13681
Differential Revision: D5017565
Pulled By: davidaurelio
fbshipit-source-id: 421f57b5ce192eedd46fae4285d8a741cb5f8e71
157 lines
4.4 KiB
JavaScript
157 lines
4.4 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 crypto = require('crypto');
|
|
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 {compactMapping} = require('./src/Bundler/source-map');
|
|
|
|
const cacheKeyParts = [
|
|
fs.readFileSync(__filename),
|
|
require('babel-plugin-external-helpers/package.json').version,
|
|
require('babel-preset-fbjs/package.json').version,
|
|
require('babel-preset-react-native/package.json').version,
|
|
];
|
|
|
|
/**
|
|
* 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(projectRoot) {
|
|
if (babelRC !== null) {
|
|
return babelRC;
|
|
}
|
|
|
|
babelRC = {plugins: []}; // empty babelrc
|
|
|
|
// Let's look for the .babelrc in the project root.
|
|
// In the future let's look into adding a command line option to specify
|
|
// this location.
|
|
let projectBabelRCPath;
|
|
if (projectRoot) {
|
|
projectBabelRCPath = path.resolve(projectRoot, '.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, '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);
|
|
} else {
|
|
// if we find a .babelrc file we tell babel to use it
|
|
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.projectRoot);
|
|
|
|
const extraConfig = {
|
|
code: false,
|
|
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 {ast, ignored} = babel.transform(src, babelConfig);
|
|
|
|
if (ignored) {
|
|
return {
|
|
ast: null,
|
|
code: src,
|
|
filename,
|
|
map: null
|
|
};
|
|
} else {
|
|
const result = generate(ast, {
|
|
comments: false,
|
|
compact: false,
|
|
filename,
|
|
sourceFileName: filename,
|
|
sourceMaps: true,
|
|
}, src);
|
|
|
|
return {
|
|
ast,
|
|
code: result.code,
|
|
filename,
|
|
map: options.generateSourceMaps ? result.map : result.rawMappings.map(compactMapping),
|
|
};
|
|
}
|
|
} finally {
|
|
process.env.BABEL_ENV = OLD_BABEL_ENV;
|
|
}
|
|
}
|
|
|
|
function getCacheKey(options) {
|
|
var key = crypto.createHash('md5');
|
|
cacheKeyParts.forEach(part => key.update(part));
|
|
return key.digest('hex');
|
|
}
|
|
|
|
module.exports = {
|
|
transform,
|
|
getCacheKey,
|
|
};
|