From d71797058d70a42d3a1dc5491d8db31b3539daac Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Thu, 12 Jul 2018 19:26:49 -0400 Subject: [PATCH] Use babel runtime instead of relying on global babelHelpers and regenerator --- .../package.json | 1 + .../src/configs/main.js | 8 ++++ .../src/plugins.js | 1 + .../__snapshots__/worker-test.js.snap | 25 ++++++++++ .../worker/__tests__/worker-test.js | 48 +++++++++++++++++-- .../lib/polyfills/__tests__/require-test.js | 11 ++--- packages/metro/src/reactNativeTransformer.js | 4 +- yarn.lock | 19 ++++++++ 8 files changed, 103 insertions(+), 14 deletions(-) diff --git a/packages/metro-react-native-babel-preset/package.json b/packages/metro-react-native-babel-preset/package.json index 7934a35f3e..9d167b5cdc 100644 --- a/packages/metro-react-native-babel-preset/package.json +++ b/packages/metro-react-native-babel-preset/package.json @@ -40,6 +40,7 @@ "@babel/plugin-transform-react-jsx": "7.0.0-beta.54", "@babel/plugin-transform-react-jsx-source": "7.0.0-beta.54", "@babel/plugin-transform-regenerator": "7.0.0-beta.54", + "@babel/plugin-transform-runtime": "7.0.0-beta.54", "@babel/plugin-transform-shorthand-properties": "7.0.0-beta.54", "@babel/plugin-transform-spread": "7.0.0-beta.54", "@babel/plugin-transform-sticky-regex": "7.0.0-beta.54", diff --git a/packages/metro-react-native-babel-preset/src/configs/main.js b/packages/metro-react-native-babel-preset/src/configs/main.js index 5871eb5c7f..220910b2cb 100644 --- a/packages/metro-react-native-babel-preset/src/configs/main.js +++ b/packages/metro-react-native-babel-preset/src/configs/main.js @@ -32,6 +32,14 @@ const defaultPlugins = [ [require('@babel/plugin-transform-shorthand-properties')], [require('@babel/plugin-transform-react-jsx')], [require('@babel/plugin-transform-regenerator')], + [ + require('@babel/plugin-transform-runtime'), + { + helpers: true, + polyfill: false, + regenerator: true, + }, + ], [require('@babel/plugin-transform-sticky-regex')], [require('@babel/plugin-transform-unicode-regex')], [ diff --git a/packages/metro-react-native-babel-preset/src/plugins.js b/packages/metro-react-native-babel-preset/src/plugins.js index b53d23bbe4..d64cff8a4f 100644 --- a/packages/metro-react-native-babel-preset/src/plugins.js +++ b/packages/metro-react-native-babel-preset/src/plugins.js @@ -30,6 +30,7 @@ module.exports = { '@babel/plugin-transform-react-jsx': require('@babel/plugin-transform-react-jsx'), '@babel/plugin-transform-react-jsx-source': require('@babel/plugin-transform-react-jsx-source'), '@babel/plugin-transform-regenerator': require('@babel/plugin-transform-regenerator'), + '@babel/plugin-transform-runtime': require('@babel/plugin-transform-runtime'), '@babel/plugin-transform-spread': require('@babel/plugin-transform-spread'), '@babel/plugin-transform-sticky-regex': require('@babel/plugin-transform-sticky-regex'), '@babel/plugin-transform-unicode-regex': require('@babel/plugin-transform-unicode-regex'), diff --git a/packages/metro/src/JSTransformer/worker/__tests__/__snapshots__/worker-test.js.snap b/packages/metro/src/JSTransformer/worker/__tests__/__snapshots__/worker-test.js.snap index 4d0f5d305b..891d460c96 100644 --- a/packages/metro/src/JSTransformer/worker/__tests__/__snapshots__/worker-test.js.snap +++ b/packages/metro/src/JSTransformer/worker/__tests__/__snapshots__/worker-test.js.snap @@ -1,3 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`code transformation worker: reports filename when encountering unsupported dynamic dependency 1`] = `"/root/local/file.js:3:10: calls to \`require\` expect exactly 1 string literal argument, but this was found: \`require(a)\`."`; + +exports[`code transformation worker: transforms an es module with regenerator 1`] = ` +"__d(function (global, _$$_REQUIRE, module, exports, _dependencyMap) { + var _interopRequireDefault = _$$_REQUIRE(_dependencyMap[0], \\"@babel/runtime/helpers/interopRequireDefault\\"); + + Object.defineProperty(exports, \\"__esModule\\", { + value: true + }); + exports.test = test; + + var _regenerator = _interopRequireDefault(_$$_REQUIRE(_dependencyMap[1], \\"@babel/runtime/regenerator\\")); + + function test() { + return _regenerator.default.async(function test$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + case \\"end\\": + return _context.stop(); + } + } + }, null, this); + } +});" +`; diff --git a/packages/metro/src/JSTransformer/worker/__tests__/worker-test.js b/packages/metro/src/JSTransformer/worker/__tests__/worker-test.js index 0ee58efea8..d3305df5c2 100644 --- a/packages/metro/src/JSTransformer/worker/__tests__/worker-test.js +++ b/packages/metro/src/JSTransformer/worker/__tests__/worker-test.js @@ -145,24 +145,66 @@ describe('code transformation worker:', () => { '__d(function (global, _$$_REQUIRE, module, exports, _dependencyMap) {', " 'use strict';", '', - ' var _c = babelHelpers.interopRequireDefault(_$$_REQUIRE(_dependencyMap[0], "./c"));', + ' var _interopRequireDefault = _$$_REQUIRE(_dependencyMap[0], "@babel/runtime/helpers/interopRequireDefault");', '', - ' _$$_REQUIRE(_dependencyMap[1], "./a");', + ' var _c = _interopRequireDefault(_$$_REQUIRE(_dependencyMap[1], "./c"));', + '', + ' _$$_REQUIRE(_dependencyMap[2], "./a");', '', ' arbitrary(code);', '', - ' var b = _$$_REQUIRE(_dependencyMap[2], "b");', + ' var b = _$$_REQUIRE(_dependencyMap[3], "b");', '});', ].join('\n'), ); expect(result.output[0].data.map).toHaveLength(14); expect(result.dependencies).toEqual([ + { + isAsync: false, + name: '@babel/runtime/helpers/interopRequireDefault', + }, {isAsync: false, name: './c'}, {isAsync: false, name: './a'}, {isAsync: false, name: 'b'}, ]); }); + it('transforms an es module with regenerator', async () => { + fs.writeFileSync( + '/root/local/file.js', + ['export async function test() {}'].join('\n'), + ); + + const {result} = await transformCode( + '/root/local/file.js', + 'local/file.js', + transformerPath, + { + dev: true, + transform: {}, + }, + [], + '', + 'minifyModulePath', + 'asyncRequire', + 'reject', + ); + + expect(result.output[0].type).toBe('js/module'); + expect(result.output[0].data.code).toMatchSnapshot(); + expect(result.output[0].data.map).toHaveLength(13); + expect(result.dependencies).toEqual([ + { + isAsync: false, + name: '@babel/runtime/helpers/interopRequireDefault', + }, + { + isAsync: false, + name: '@babel/runtime/regenerator', + }, + ]); + }); + it('reports filename when encountering unsupported dynamic dependency', async () => { fs.writeFileSync( '/root/local/file.js', diff --git a/packages/metro/src/lib/polyfills/__tests__/require-test.js b/packages/metro/src/lib/polyfills/__tests__/require-test.js index 7195074f68..56f2daf1cd 100644 --- a/packages/metro/src/lib/polyfills/__tests__/require-test.js +++ b/packages/metro/src/lib/polyfills/__tests__/require-test.js @@ -14,10 +14,6 @@ const fs = require('fs'); const {transformSync} = require('@babel/core'); -// Include the external-helpers plugin to be able to detect if they're -// needed when transforming the requirejs implementation. -const PLUGINS = ['@babel/plugin-external-helpers']; - function createModule( moduleSystem, moduleId, @@ -34,7 +30,6 @@ describe('require', () => { return transformSync(rawCode, { ast: false, babelrc: false, - plugins: PLUGINS.map(require), presets: [require.resolve('metro-react-native-babel-preset')], retainLines: true, sourceMaps: 'inline', @@ -56,9 +51,9 @@ describe('require', () => { }); it('does not need any babel helper logic', () => { - // Super-simple check to validate that no babel helpers are used. - // This check will need to be updated if https://fburl.com/6z0y2kf8 changes. - expect(moduleSystemCode.includes('babelHelpers')).toBe(false); + // The react native preset uses @babel/transform-runtime so helpers will be + // imported from @babel/runtime. + expect(moduleSystemCode.includes('@babel/runtime')).toBe(false); }); it('works with plain bundles', () => { diff --git a/packages/metro/src/reactNativeTransformer.js b/packages/metro/src/reactNativeTransformer.js index 973f54e4a0..1e4dec9b9f 100644 --- a/packages/metro/src/reactNativeTransformer.js +++ b/packages/metro/src/reactNativeTransformer.js @@ -12,7 +12,6 @@ 'use strict'; const crypto = require('crypto'); -const externalHelpersPlugin = require('babel-plugin-external-helpers'); const fs = require('fs'); const inlineRequiresPlugin = require('babel-preset-fbjs/plugins/inline-requires'); const json5 = require('json5'); @@ -28,7 +27,6 @@ type ModuleES6 = {__esModule?: boolean, default?: {}}; const cacheKeyParts = [ fs.readFileSync(__filename), - require('babel-plugin-external-helpers/package.json').version, require('babel-preset-fbjs/package.json').version, ]; @@ -127,7 +125,7 @@ function buildBabelConfig(filename, options, plugins?: BabelPlugins = []) { let config = Object.assign({}, babelRC, extraConfig); // Add extra plugins - const extraPlugins = [externalHelpersPlugin]; + const extraPlugins = []; if (options.inlineRequires) { extraPlugins.push(inlineRequiresPlugin); diff --git a/yarn.lock b/yarn.lock index 02b1903fe8..d3b289f77f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -497,9 +497,22 @@ dependencies: "@babel/helper-plugin-utils" "7.0.0-beta.54" +<<<<<<< HEAD "@babel/plugin-transform-spread@7.0.0-beta.54": version "7.0.0-beta.54" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.54.tgz#4f0852df0f4b1db2426c40facd8fe5f028a3dbc9" +======= +"@babel/plugin-transform-runtime@7.0.0-beta.48": + version "7.0.0-beta.48" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.0.0-beta.48.tgz#166ceb0a96948507c851edbd9e9c5aa98f8ead71" + dependencies: + "@babel/helper-module-imports" "7.0.0-beta.48" + "@babel/helper-plugin-utils" "7.0.0-beta.48" + +"@babel/plugin-transform-shorthand-properties@7.0.0-beta.48": + version "7.0.0-beta.48" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.48.tgz#5cc1c14bbc4f5132e5bd1ecf7ff3e9adeb9dfe35" +>>>>>>> Use babel runtime instead of relying on global babelHelpers and regenerator dependencies: "@babel/helper-plugin-utils" "7.0.0-beta.54" @@ -5152,9 +5165,15 @@ regenerator-runtime@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" +<<<<<<< HEAD regenerator-transform@^0.13.3: version "0.13.3" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" +======= +regenerator-transform@^0.12.3: + version "0.12.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.12.4.tgz#aa9b6c59f4b97be080e972506c560b3bccbfcff0" +>>>>>>> Use babel runtime instead of relying on global babelHelpers and regenerator dependencies: private "^0.1.6"