From d476461120b9bf5d98c1c4f8c2ded2cba3e66eaa Mon Sep 17 00:00:00 2001 From: Pilwon Huh Date: Fri, 3 Apr 2015 11:39:29 -0700 Subject: [PATCH] react-packager: Add ES6 import statement support to DependencyGraph. Summary: This PR teaches packager's `DependencyGraph` how to extract dependencies written with ES6 `import` statements. It fixes the issue where you are not able to write your app with ES6 `import` statements when your custom transformer (replacing the default [JSTransform](https://github.com/facebook/jstransform), for example, [babel](http://babeljs.io/)) already supports the ES6 `import` syntax. It will also be useful for [JSTransform](https://github.com/facebook/jstransform) later on once it implements `import` feature too. Closes https://github.com/facebook/react-native/pull/386 Github Author: Pilwon Huh Test Plan: runJestTests.sh --- .../__tests__/DependencyGraph-test.js | 2 +- .../haste/DependencyGraph/index.js | 8 +- .../__tests__/HasteDependencyResolver-test.js | 287 +++++++++++++++++- .../src/DependencyResolver/haste/index.js | 22 +- .../{requirePattern.js => replacePatterns.js} | 5 +- 5 files changed, 297 insertions(+), 27 deletions(-) rename react-packager/src/DependencyResolver/haste/{requirePattern.js => replacePatterns.js} (68%) diff --git a/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js b/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js index 5f6ec882..5bca3013 100644 --- a/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js +++ b/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js @@ -13,7 +13,7 @@ jest .dontMock('path') .dontMock('absolute-path') .dontMock('../docblock') - .dontMock('../../requirePattern') + .dontMock('../../replacePatterns') .setMock('../../../ModuleDescriptor', function(data) {return data;}); describe('DependencyGraph', function() { diff --git a/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js b/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js index 9ca430c4..554db134 100644 --- a/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js +++ b/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js @@ -12,7 +12,7 @@ var ModuleDescriptor = require('../../ModuleDescriptor'); var Promise = require('bluebird'); var fs = require('fs'); var docblock = require('./docblock'); -var requirePattern = require('../requirePattern'); +var replacePatterns = require('../replacePatterns'); var path = require('path'); var isAbsolutePath = require('absolute-path'); var debug = require('debug')('DependecyGraph'); @@ -609,7 +609,11 @@ function extractRequires(code) { code .replace(blockCommentRe, '') .replace(lineCommentRe, '') - .replace(requirePattern, function(match, _, dep) { + .replace(replacePatterns.IMPORT_RE, function(match, pre, quot, dep, post) { + deps.push(dep); + return match; + }) + .replace(replacePatterns.REQUIRE_RE, function(match, pre, quot, dep, post) { deps.push(dep); }); diff --git a/react-packager/src/DependencyResolver/haste/__tests__/HasteDependencyResolver-test.js b/react-packager/src/DependencyResolver/haste/__tests__/HasteDependencyResolver-test.js index 2a24f2d1..8620d488 100644 --- a/react-packager/src/DependencyResolver/haste/__tests__/HasteDependencyResolver-test.js +++ b/react-packager/src/DependencyResolver/haste/__tests__/HasteDependencyResolver-test.js @@ -10,7 +10,7 @@ jest.dontMock('../') .dontMock('q') - .dontMock('../requirePattern') + .dontMock('../replacePatterns') .setMock('../../ModuleDescriptor', function(data) {return data;}); var Promise = require('bluebird'); @@ -228,13 +228,148 @@ describe('HasteDependencyResolver', function() { var depGraph = depResolver._depGraph; var dependencies = ['x', 'y', 'z', 'a', 'b']; + + /*eslint-disable */ var code = [ + "import'x';", + "import 'x';", + "import 'x' ;", + "import Default from 'x';", + "import * as All from 'x';", + "import {} from 'x';", + "import { } from 'x';", + "import {Foo} from 'x';", + "import { Foo } from 'x';", + "import { Foo, } from 'x';", + "import {Foo as Bar} from 'x';", + "import { Foo as Bar } from 'x';", + "import { Foo as Bar, } from 'x';", + "import { Foo, Bar } from 'x';", + "import { Foo, Bar, } from 'x';", + "import { Foo as Bar, Baz } from 'x';", + "import { Foo as Bar, Baz, } from 'x';", + "import { Foo, Bar as Baz } from 'x';", + "import { Foo, Bar as Baz, } from 'x';", + "import { Foo as Bar, Baz as Qux } from 'x';", + "import { Foo as Bar, Baz as Qux, } from 'x';", + "import { Foo, Bar, Baz } from 'x';", + "import { Foo, Bar, Baz, } from 'x';", + "import { Foo as Bar, Baz, Qux } from 'x';", + "import { Foo as Bar, Baz, Qux, } from 'x';", + "import { Foo, Bar as Baz, Qux } from 'x';", + "import { Foo, Bar as Baz, Qux, } from 'x';", + "import { Foo, Bar, Baz as Qux } from 'x';", + "import { Foo, Bar, Baz as Qux, } from 'x';", + "import { Foo as Bar, Baz as Qux, Norf } from 'x';", + "import { Foo as Bar, Baz as Qux, Norf, } from 'x';", + "import { Foo as Bar, Baz, Qux as Norf } from 'x';", + "import { Foo as Bar, Baz, Qux as Norf, } from 'x';", + "import { Foo, Bar as Baz, Qux as Norf } from 'x';", + "import { Foo, Bar as Baz, Qux as Norf, } from 'x';", + "import { Foo as Bar, Baz as Qux, Norf as Enuf } from 'x';", + "import { Foo as Bar, Baz as Qux, Norf as Enuf, } from 'x';", + "import Default, * as All from 'x';", + "import Default, { } from 'x';", + "import Default, { Foo } from 'x';", + "import Default, { Foo, } from 'x';", + "import Default, { Foo as Bar } from 'x';", + "import Default, { Foo as Bar, } from 'x';", + "import Default, { Foo, Bar } from 'x';", + "import Default, { Foo, Bar, } from 'x';", + "import Default, { Foo as Bar, Baz } from 'x';", + "import Default, { Foo as Bar, Baz, } from 'x';", + "import Default, { Foo, Bar as Baz } from 'x';", + "import Default, { Foo, Bar as Baz, } from 'x';", + "import Default, { Foo as Bar, Baz as Qux } from 'x';", + "import Default, { Foo as Bar, Baz as Qux, } from 'x';", + "import Default, { Foo, Bar, Baz } from 'x';", + "import Default, { Foo, Bar, Baz, } from 'x';", + "import Default, { Foo as Bar, Baz, Qux } from 'x';", + "import Default, { Foo as Bar, Baz, Qux, } from 'x';", + "import Default, { Foo, Bar as Baz, Qux } from 'x';", + "import Default, { Foo, Bar as Baz, Qux, } from 'x';", + "import Default, { Foo, Bar, Baz as Qux } from 'x';", + "import Default, { Foo, Bar, Baz as Qux, } from 'x';", + "import Default, { Foo as Bar, Baz as Qux, Norf } from 'x';", + "import Default, { Foo as Bar, Baz as Qux, Norf, } from 'x';", + "import Default, { Foo as Bar, Baz, Qux as Norf } from 'x';", + "import Default, { Foo as Bar, Baz, Qux as Norf, } from 'x';", + "import Default, { Foo, Bar as Baz, Qux as Norf } from 'x';", + "import Default, { Foo, Bar as Baz, Qux as Norf, } from 'x';", + "import Default, { Foo as Bar, Baz as Qux, Norf as NoMore } from 'x';", + "import Default, { Foo as Bar, Baz as Qux, Norf as NoMore, } from 'x';", + "import Default , { } from 'x';", + 'import "x";', + 'import Default from "x";', + 'import * as All from "x";', + 'import { } from "x";', + 'import { Foo } from "x";', + 'import { Foo, } from "x";', + 'import { Foo as Bar } from "x";', + 'import { Foo as Bar, } from "x";', + 'import { Foo, Bar } from "x";', + 'import { Foo, Bar, } from "x";', + 'import { Foo as Bar, Baz } from "x";', + 'import { Foo as Bar, Baz, } from "x";', + 'import { Foo, Bar as Baz } from "x";', + 'import { Foo, Bar as Baz, } from "x";', + 'import { Foo as Bar, Baz as Qux } from "x";', + 'import { Foo as Bar, Baz as Qux, } from "x";', + 'import { Foo, Bar, Baz } from "x";', + 'import { Foo, Bar, Baz, } from "x";', + 'import { Foo as Bar, Baz, Qux } from "x";', + 'import { Foo as Bar, Baz, Qux, } from "x";', + 'import { Foo, Bar as Baz, Qux } from "x";', + 'import { Foo, Bar as Baz, Qux, } from "x";', + 'import { Foo, Bar, Baz as Qux } from "x";', + 'import { Foo, Bar, Baz as Qux, } from "x";', + 'import { Foo as Bar, Baz as Qux, Norf } from "x";', + 'import { Foo as Bar, Baz as Qux, Norf, } from "x";', + 'import { Foo as Bar, Baz, Qux as Norf } from "x";', + 'import { Foo as Bar, Baz, Qux as Norf, } from "x";', + 'import { Foo, Bar as Baz, Qux as Norf } from "x";', + 'import { Foo, Bar as Baz, Qux as Norf, } from "x";', + 'import { Foo as Bar, Baz as Qux, Norf as NoMore } from "x";', + 'import { Foo as Bar, Baz as Qux, Norf as NoMore, } from "x";', + 'import Default, * as All from "x";', + 'import Default, { } from "x";', + 'import Default, { Foo } from "x";', + 'import Default, { Foo, } from "x";', + 'import Default, { Foo as Bar } from "x";', + 'import Default, { Foo as Bar, } from "x";', + 'import Default, { Foo, Bar } from "x";', + 'import Default, { Foo, Bar, } from "x";', + 'import Default, { Foo as Bar, Baz } from "x";', + 'import Default, { Foo as Bar, Baz, } from "x";', + 'import Default, { Foo, Bar as Baz } from "x";', + 'import Default, { Foo, Bar as Baz, } from "x";', + 'import Default, { Foo as Bar, Baz as Qux } from "x";', + 'import Default, { Foo as Bar, Baz as Qux, } from "x";', + 'import Default, { Foo, Bar, Baz } from "x";', + 'import Default, { Foo, Bar, Baz, } from "x";', + 'import Default, { Foo as Bar, Baz, Qux } from "x";', + 'import Default, { Foo as Bar, Baz, Qux, } from "x";', + 'import Default, { Foo, Bar as Baz, Qux } from "x";', + 'import Default, { Foo, Bar as Baz, Qux, } from "x";', + 'import Default, { Foo, Bar, Baz as Qux } from "x";', + 'import Default, { Foo, Bar, Baz as Qux, } from "x";', + 'import Default, { Foo as Bar, Baz as Qux, Norf } from "x";', + 'import Default, { Foo as Bar, Baz as Qux, Norf, } from "x";', + 'import Default, { Foo as Bar, Baz, Qux as Norf } from "x";', + 'import Default, { Foo as Bar, Baz, Qux as Norf, } from "x";', + 'import Default, { Foo, Bar as Baz, Qux as Norf } from "x";', + 'import Default, { Foo, Bar as Baz, Qux as Norf, } from "x";', + 'import Default, { Foo as Bar, Baz as Qux, Norf as Enuf } from "x";', + 'import Default, { Foo as Bar, Baz as Qux, Norf as Enuf, } from "x";', + 'import Default from "y";', + 'import * as All from \'z\';', 'require("x")', 'require("y")', - 'require( "z" )', + 'require( \'z\' )', 'require( "a")', 'require("b" )', ].join('\n'); + /*eslint-disable */ depGraph.resolveDependency.mockImpl(function(fromModule, toModuleName) { if (toModuleName === 'x') { @@ -242,7 +377,7 @@ describe('HasteDependencyResolver', function() { id: 'changed' }; } else if (toModuleName === 'y') { - return { id: 'y' }; + return { id: 'Y' }; } return null; }); @@ -254,13 +389,145 @@ describe('HasteDependencyResolver', function() { }, code); expect(processedCode).toEqual([ - '__d(\'test module\',["changed","y"],function(global,' + - ' require, requireDynamic, requireLazy, module, exports) {' + - ' require(\'changed\')', - 'require(\'y\')', - 'require("z")', - 'require("a")', - 'require("b")});', + '__d(\'test module\',["changed","Y"],function(global,' + + ' require, requireDynamic, requireLazy, module, exports) { ' + + "import'x';", + "import 'changed';", + "import 'changed' ;", + "import Default from 'changed';", + "import * as All from 'changed';", + "import {} from 'changed';", + "import { } from 'changed';", + "import {Foo} from 'changed';", + "import { Foo } from 'changed';", + "import { Foo, } from 'changed';", + "import {Foo as Bar} from 'changed';", + "import { Foo as Bar } from 'changed';", + "import { Foo as Bar, } from 'changed';", + "import { Foo, Bar } from 'changed';", + "import { Foo, Bar, } from 'changed';", + "import { Foo as Bar, Baz } from 'changed';", + "import { Foo as Bar, Baz, } from 'changed';", + "import { Foo, Bar as Baz } from 'changed';", + "import { Foo, Bar as Baz, } from 'changed';", + "import { Foo as Bar, Baz as Qux } from 'changed';", + "import { Foo as Bar, Baz as Qux, } from 'changed';", + "import { Foo, Bar, Baz } from 'changed';", + "import { Foo, Bar, Baz, } from 'changed';", + "import { Foo as Bar, Baz, Qux } from 'changed';", + "import { Foo as Bar, Baz, Qux, } from 'changed';", + "import { Foo, Bar as Baz, Qux } from 'changed';", + "import { Foo, Bar as Baz, Qux, } from 'changed';", + "import { Foo, Bar, Baz as Qux } from 'changed';", + "import { Foo, Bar, Baz as Qux, } from 'changed';", + "import { Foo as Bar, Baz as Qux, Norf } from 'changed';", + "import { Foo as Bar, Baz as Qux, Norf, } from 'changed';", + "import { Foo as Bar, Baz, Qux as Norf } from 'changed';", + "import { Foo as Bar, Baz, Qux as Norf, } from 'changed';", + "import { Foo, Bar as Baz, Qux as Norf } from 'changed';", + "import { Foo, Bar as Baz, Qux as Norf, } from 'changed';", + "import { Foo as Bar, Baz as Qux, Norf as Enuf } from 'changed';", + "import { Foo as Bar, Baz as Qux, Norf as Enuf, } from 'changed';", + "import Default, * as All from 'changed';", + "import Default, { } from 'changed';", + "import Default, { Foo } from 'changed';", + "import Default, { Foo, } from 'changed';", + "import Default, { Foo as Bar } from 'changed';", + "import Default, { Foo as Bar, } from 'changed';", + "import Default, { Foo, Bar } from 'changed';", + "import Default, { Foo, Bar, } from 'changed';", + "import Default, { Foo as Bar, Baz } from 'changed';", + "import Default, { Foo as Bar, Baz, } from 'changed';", + "import Default, { Foo, Bar as Baz } from 'changed';", + "import Default, { Foo, Bar as Baz, } from 'changed';", + "import Default, { Foo as Bar, Baz as Qux } from 'changed';", + "import Default, { Foo as Bar, Baz as Qux, } from 'changed';", + "import Default, { Foo, Bar, Baz } from 'changed';", + "import Default, { Foo, Bar, Baz, } from 'changed';", + "import Default, { Foo as Bar, Baz, Qux } from 'changed';", + "import Default, { Foo as Bar, Baz, Qux, } from 'changed';", + "import Default, { Foo, Bar as Baz, Qux } from 'changed';", + "import Default, { Foo, Bar as Baz, Qux, } from 'changed';", + "import Default, { Foo, Bar, Baz as Qux } from 'changed';", + "import Default, { Foo, Bar, Baz as Qux, } from 'changed';", + "import Default, { Foo as Bar, Baz as Qux, Norf } from 'changed';", + "import Default, { Foo as Bar, Baz as Qux, Norf, } from 'changed';", + "import Default, { Foo as Bar, Baz, Qux as Norf } from 'changed';", + "import Default, { Foo as Bar, Baz, Qux as Norf, } from 'changed';", + "import Default, { Foo, Bar as Baz, Qux as Norf } from 'changed';", + "import Default, { Foo, Bar as Baz, Qux as Norf, } from 'changed';", + "import Default, { Foo as Bar, Baz as Qux, Norf as NoMore } from 'changed';", + "import Default, { Foo as Bar, Baz as Qux, Norf as NoMore, } from 'changed';", + "import Default , { } from 'changed';", + 'import "changed";', + 'import Default from "changed";', + 'import * as All from "changed";', + 'import { } from "changed";', + 'import { Foo } from "changed";', + 'import { Foo, } from "changed";', + 'import { Foo as Bar } from "changed";', + 'import { Foo as Bar, } from "changed";', + 'import { Foo, Bar } from "changed";', + 'import { Foo, Bar, } from "changed";', + 'import { Foo as Bar, Baz } from "changed";', + 'import { Foo as Bar, Baz, } from "changed";', + 'import { Foo, Bar as Baz } from "changed";', + 'import { Foo, Bar as Baz, } from "changed";', + 'import { Foo as Bar, Baz as Qux } from "changed";', + 'import { Foo as Bar, Baz as Qux, } from "changed";', + 'import { Foo, Bar, Baz } from "changed";', + 'import { Foo, Bar, Baz, } from "changed";', + 'import { Foo as Bar, Baz, Qux } from "changed";', + 'import { Foo as Bar, Baz, Qux, } from "changed";', + 'import { Foo, Bar as Baz, Qux } from "changed";', + 'import { Foo, Bar as Baz, Qux, } from "changed";', + 'import { Foo, Bar, Baz as Qux } from "changed";', + 'import { Foo, Bar, Baz as Qux, } from "changed";', + 'import { Foo as Bar, Baz as Qux, Norf } from "changed";', + 'import { Foo as Bar, Baz as Qux, Norf, } from "changed";', + 'import { Foo as Bar, Baz, Qux as Norf } from "changed";', + 'import { Foo as Bar, Baz, Qux as Norf, } from "changed";', + 'import { Foo, Bar as Baz, Qux as Norf } from "changed";', + 'import { Foo, Bar as Baz, Qux as Norf, } from "changed";', + 'import { Foo as Bar, Baz as Qux, Norf as NoMore } from "changed";', + 'import { Foo as Bar, Baz as Qux, Norf as NoMore, } from "changed";', + 'import Default, * as All from "changed";', + 'import Default, { } from "changed";', + 'import Default, { Foo } from "changed";', + 'import Default, { Foo, } from "changed";', + 'import Default, { Foo as Bar } from "changed";', + 'import Default, { Foo as Bar, } from "changed";', + 'import Default, { Foo, Bar } from "changed";', + 'import Default, { Foo, Bar, } from "changed";', + 'import Default, { Foo as Bar, Baz } from "changed";', + 'import Default, { Foo as Bar, Baz, } from "changed";', + 'import Default, { Foo, Bar as Baz } from "changed";', + 'import Default, { Foo, Bar as Baz, } from "changed";', + 'import Default, { Foo as Bar, Baz as Qux } from "changed";', + 'import Default, { Foo as Bar, Baz as Qux, } from "changed";', + 'import Default, { Foo, Bar, Baz } from "changed";', + 'import Default, { Foo, Bar, Baz, } from "changed";', + 'import Default, { Foo as Bar, Baz, Qux } from "changed";', + 'import Default, { Foo as Bar, Baz, Qux, } from "changed";', + 'import Default, { Foo, Bar as Baz, Qux } from "changed";', + 'import Default, { Foo, Bar as Baz, Qux, } from "changed";', + 'import Default, { Foo, Bar, Baz as Qux } from "changed";', + 'import Default, { Foo, Bar, Baz as Qux, } from "changed";', + 'import Default, { Foo as Bar, Baz as Qux, Norf } from "changed";', + 'import Default, { Foo as Bar, Baz as Qux, Norf, } from "changed";', + 'import Default, { Foo as Bar, Baz, Qux as Norf } from "changed";', + 'import Default, { Foo as Bar, Baz, Qux as Norf, } from "changed";', + 'import Default, { Foo, Bar as Baz, Qux as Norf } from "changed";', + 'import Default, { Foo, Bar as Baz, Qux as Norf, } from "changed";', + 'import Default, { Foo as Bar, Baz as Qux, Norf as Enuf } from "changed";', + 'import Default, { Foo as Bar, Baz as Qux, Norf as Enuf, } from "changed";', + 'import Default from "Y";', + 'import * as All from \'z\';', + 'require("changed")', + 'require("Y")', + 'require( \'z\' )', + 'require( "a")', + 'require("b" )});', ].join('\n')); }); }); diff --git a/react-packager/src/DependencyResolver/haste/index.js b/react-packager/src/DependencyResolver/haste/index.js index 941a687e..e5736623 100644 --- a/react-packager/src/DependencyResolver/haste/index.js +++ b/react-packager/src/DependencyResolver/haste/index.js @@ -10,7 +10,7 @@ var path = require('path'); var DependencyGraph = require('./DependencyGraph'); -var requirePattern = require('./requirePattern'); +var replacePatterns = require('./replacePatterns'); var ModuleDescriptor = require('../ModuleDescriptor'); var declareOpts = require('../../lib/declareOpts'); @@ -144,20 +144,20 @@ HasteDependencyResolver.prototype.wrapModule = function(module, code) { } } - var relativizedCode = - code.replace(requirePattern, function(codeMatch, _, depName) { - var depId = resolvedDeps[depName]; - if (depId != null) { - return 'require(\'' + depId + '\')'; - } else { - return codeMatch.replace(/\s+/g, ''); - } - }); + var relativizeCode = function(codeMatch, pre, quot, depName, post) { + var depId = resolvedDeps[depName]; + if (depId) { + return pre + quot + depId + post; + } else { + return codeMatch; + } + }; return DEFINE_MODULE_CODE.replace(DEFINE_MODULE_REPLACE_RE, function(key) { return { '_moduleName_': module.id, - '_code_': relativizedCode, + '_code_': code.replace(replacePatterns.IMPORT_RE, relativizeCode) + .replace(replacePatterns.REQUIRE_RE, relativizeCode), '_deps_': JSON.stringify(resolvedDepsArr), }[key]; }); diff --git a/react-packager/src/DependencyResolver/haste/requirePattern.js b/react-packager/src/DependencyResolver/haste/replacePatterns.js similarity index 68% rename from react-packager/src/DependencyResolver/haste/requirePattern.js rename to react-packager/src/DependencyResolver/haste/replacePatterns.js index 26d807ff..cde2d873 100644 --- a/react-packager/src/DependencyResolver/haste/requirePattern.js +++ b/react-packager/src/DependencyResolver/haste/replacePatterns.js @@ -9,6 +9,5 @@ 'use strict'; -var REQUIRE_RE = /\brequire\s*?\(\s*?([\'"])([^"\']+)\1\s*?\)/g; - -module.exports = REQUIRE_RE; +exports.IMPORT_RE = /(\bimport\s+?(?:.+\s+?from\s+?)?)(['"])([^'"]+)(\2)/g; +exports.REQUIRE_RE = /(\brequire\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g;