mirror of
https://github.com/status-im/metro.git
synced 2025-01-17 14:41:09 +00:00
Start pulling DependencyResolver apart
Summary: I'm planning to split up `DependencyResolver` into the react-native specific implementation of it and a new, generic resolver that is going to replace `node-haste` for jest and other places where we might need JS dependency resolution. The plan is to split the two folders up so that: * `Resolver` is the folder for all the react-native specific resolver code * `DependencyResolver` will become a standalone library, eventually moving into a package called `node-haste`. There is still a lot to be figured out. This is just the first diff of likely many. The current goal is to make `DependencyResolver` standalone to be able to create an instance of a resolver and resolve all dependencies for a file. This is when I can start integrating it more seriously with jest. This diff simply moves a bunch of things around and turns `HasteModuleResolver` into an ES2015 class ( :) ). bypass-lint public Reviewed By: davidaurelio Differential Revision: D2614151 fb-gh-sync-id: ff4e434c4747d2fb032d34dc19fb85e0b0c553ac
This commit is contained in:
parent
29befc8d1c
commit
c731001864
@ -19,7 +19,7 @@ jest.mock('fs');
|
|||||||
|
|
||||||
var Bundler = require('../');
|
var Bundler = require('../');
|
||||||
var JSTransformer = require('../../JSTransformer');
|
var JSTransformer = require('../../JSTransformer');
|
||||||
var DependencyResolver = require('../../DependencyResolver');
|
var Resolver = require('../../Resolver');
|
||||||
var sizeOf = require('image-size');
|
var sizeOf = require('image-size');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ describe('Bundler', function() {
|
|||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
getDependencies = jest.genMockFn();
|
getDependencies = jest.genMockFn();
|
||||||
wrapModule = jest.genMockFn();
|
wrapModule = jest.genMockFn();
|
||||||
DependencyResolver.mockImpl(function() {
|
Resolver.mockImpl(function() {
|
||||||
return {
|
return {
|
||||||
getDependencies: getDependencies,
|
getDependencies: getDependencies,
|
||||||
wrapModule: wrapModule,
|
wrapModule: wrapModule,
|
||||||
|
4
react-packager/src/Bundler/index.js
vendored
4
react-packager/src/Bundler/index.js
vendored
@ -16,7 +16,7 @@ const ProgressBar = require('progress');
|
|||||||
const BundlesLayout = require('../BundlesLayout');
|
const BundlesLayout = require('../BundlesLayout');
|
||||||
const Cache = require('../Cache');
|
const Cache = require('../Cache');
|
||||||
const Transformer = require('../JSTransformer');
|
const Transformer = require('../JSTransformer');
|
||||||
const DependencyResolver = require('../DependencyResolver');
|
const Resolver = require('../Resolver');
|
||||||
const Bundle = require('./Bundle');
|
const Bundle = require('./Bundle');
|
||||||
const Activity = require('../Activity');
|
const Activity = require('../Activity');
|
||||||
const ModuleTransport = require('../lib/ModuleTransport');
|
const ModuleTransport = require('../lib/ModuleTransport');
|
||||||
@ -94,7 +94,7 @@ class Bundler {
|
|||||||
transformModulePath: opts.transformModulePath,
|
transformModulePath: opts.transformModulePath,
|
||||||
});
|
});
|
||||||
|
|
||||||
this._resolver = new DependencyResolver({
|
this._resolver = new Resolver({
|
||||||
projectRoots: opts.projectRoots,
|
projectRoots: opts.projectRoots,
|
||||||
blacklistRE: opts.blacklistRE,
|
blacklistRE: opts.blacklistRE,
|
||||||
polyfillModuleNames: opts.polyfillModuleNames,
|
polyfillModuleNames: opts.polyfillModuleNames,
|
||||||
|
@ -13,14 +13,14 @@ jest.dontMock('../index')
|
|||||||
|
|
||||||
var Promise = require('promise');
|
var Promise = require('promise');
|
||||||
var BundlesLayout = require('../index');
|
var BundlesLayout = require('../index');
|
||||||
var DependencyResolver = require('../../DependencyResolver');
|
var Resolver = require('../../Resolver');
|
||||||
var loadCacheSync = require('../../lib/loadCacheSync');
|
var loadCacheSync = require('../../lib/loadCacheSync');
|
||||||
|
|
||||||
describe('BundlesLayout', () => {
|
describe('BundlesLayout', () => {
|
||||||
function newBundlesLayout(options) {
|
function newBundlesLayout(options) {
|
||||||
return new BundlesLayout(Object.assign({
|
return new BundlesLayout(Object.assign({
|
||||||
projectRoots: ['/root'],
|
projectRoots: ['/root'],
|
||||||
dependencyResolver: new DependencyResolver(),
|
dependencyResolver: new Resolver(),
|
||||||
}, options));
|
}, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ describe('BundlesLayout', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pit('should bundle sync dependencies', () => {
|
pit('should bundle sync dependencies', () => {
|
||||||
DependencyResolver.prototype.getDependencies.mockImpl((path) => {
|
Resolver.prototype.getDependencies.mockImpl((path) => {
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case '/root/index.js':
|
case '/root/index.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@ -67,7 +67,7 @@ describe('BundlesLayout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pit('should separate async dependencies into different bundle', () => {
|
pit('should separate async dependencies into different bundle', () => {
|
||||||
DependencyResolver.prototype.getDependencies.mockImpl((path) => {
|
Resolver.prototype.getDependencies.mockImpl((path) => {
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case '/root/index.js':
|
case '/root/index.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@ -100,7 +100,7 @@ describe('BundlesLayout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pit('separate async dependencies of async dependencies', () => {
|
pit('separate async dependencies of async dependencies', () => {
|
||||||
DependencyResolver.prototype.getDependencies.mockImpl((path) => {
|
Resolver.prototype.getDependencies.mockImpl((path) => {
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case '/root/index.js':
|
case '/root/index.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@ -142,7 +142,7 @@ describe('BundlesLayout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pit('separate bundle sync dependencies of async ones on same bundle', () => {
|
pit('separate bundle sync dependencies of async ones on same bundle', () => {
|
||||||
DependencyResolver.prototype.getDependencies.mockImpl((path) => {
|
Resolver.prototype.getDependencies.mockImpl((path) => {
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case '/root/index.js':
|
case '/root/index.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@ -180,7 +180,7 @@ describe('BundlesLayout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pit('separate cache in which bundle is each dependency', () => {
|
pit('separate cache in which bundle is each dependency', () => {
|
||||||
DependencyResolver.prototype.getDependencies.mockImpl((path) => {
|
Resolver.prototype.getDependencies.mockImpl((path) => {
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case '/root/index.js':
|
case '/root/index.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@ -218,7 +218,7 @@ describe('BundlesLayout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pit('separate cache in which bundle is each dependency', () => {
|
pit('separate cache in which bundle is each dependency', () => {
|
||||||
DependencyResolver.prototype.getDependencies.mockImpl((path) => {
|
Resolver.prototype.getDependencies.mockImpl((path) => {
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case '/root/index.js':
|
case '/root/index.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
@ -20,7 +20,7 @@ jest.mock('fs');
|
|||||||
|
|
||||||
var BundlesLayout = require('../index');
|
var BundlesLayout = require('../index');
|
||||||
var Cache = require('../../Cache');
|
var Cache = require('../../Cache');
|
||||||
var DependencyResolver = require('../../DependencyResolver');
|
var Resolver = require('../../Resolver');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
describe('BundlesLayout', () => {
|
describe('BundlesLayout', () => {
|
||||||
@ -47,7 +47,7 @@ describe('BundlesLayout', () => {
|
|||||||
|
|
||||||
describe('generate', () => {
|
describe('generate', () => {
|
||||||
function newBundlesLayout() {
|
function newBundlesLayout() {
|
||||||
const resolver = new DependencyResolver({
|
const resolver = new Resolver({
|
||||||
projectRoots: ['/root', '/' + __dirname.split('/')[1]],
|
projectRoots: ['/root', '/' + __dirname.split('/')[1]],
|
||||||
fileWatcher: fileWatcher,
|
fileWatcher: fileWatcher,
|
||||||
cache: new Cache(),
|
cache: new Cache(),
|
||||||
@ -577,7 +577,7 @@ describe('BundlesLayout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function getBaseFs() {
|
function getBaseFs() {
|
||||||
const p = path.join(__dirname, '../../../DependencyResolver/polyfills').substring(1);
|
const p = path.join(__dirname, '../../../Resolver/polyfills').substring(1);
|
||||||
const root = {};
|
const root = {};
|
||||||
let currentPath = root;
|
let currentPath = root;
|
||||||
|
|
||||||
|
175
react-packager/src/DependencyResolver/index.js
vendored
175
react-packager/src/DependencyResolver/index.js
vendored
@ -1,175 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var path = require('path');
|
|
||||||
var DependencyGraph = require('./DependencyGraph');
|
|
||||||
var replacePatterns = require('./replacePatterns');
|
|
||||||
var Polyfill = require('./Polyfill');
|
|
||||||
var declareOpts = require('../lib/declareOpts');
|
|
||||||
var Promise = require('promise');
|
|
||||||
|
|
||||||
var validateOpts = declareOpts({
|
|
||||||
projectRoots: {
|
|
||||||
type: 'array',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
blacklistRE: {
|
|
||||||
type: 'object', // typeof regex is object
|
|
||||||
},
|
|
||||||
polyfillModuleNames: {
|
|
||||||
type: 'array',
|
|
||||||
default: [],
|
|
||||||
},
|
|
||||||
moduleFormat: {
|
|
||||||
type: 'string',
|
|
||||||
default: 'haste',
|
|
||||||
},
|
|
||||||
assetRoots: {
|
|
||||||
type: 'array',
|
|
||||||
default: [],
|
|
||||||
},
|
|
||||||
fileWatcher: {
|
|
||||||
type: 'object',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
assetExts: {
|
|
||||||
type: 'array',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
cache: {
|
|
||||||
type: 'object',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
function HasteDependencyResolver(options) {
|
|
||||||
var opts = validateOpts(options);
|
|
||||||
|
|
||||||
this._depGraph = new DependencyGraph({
|
|
||||||
roots: opts.projectRoots,
|
|
||||||
assetRoots_DEPRECATED: opts.assetRoots,
|
|
||||||
assetExts: opts.assetExts,
|
|
||||||
ignoreFilePath: function(filepath) {
|
|
||||||
return filepath.indexOf('__tests__') !== -1 ||
|
|
||||||
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
|
||||||
},
|
|
||||||
fileWatcher: opts.fileWatcher,
|
|
||||||
cache: opts.cache,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
this._polyfillModuleNames = opts.polyfillModuleNames || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
var getDependenciesValidateOpts = declareOpts({
|
|
||||||
dev: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
platform: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
HasteDependencyResolver.prototype.getDependencies = function(main, options) {
|
|
||||||
var opts = getDependenciesValidateOpts(options);
|
|
||||||
|
|
||||||
return this._depGraph.getDependencies(main, opts.platform).then(
|
|
||||||
resolutionResponse => {
|
|
||||||
this._getPolyfillDependencies(opts.dev).reverse().forEach(
|
|
||||||
polyfill => resolutionResponse.prependDependency(polyfill)
|
|
||||||
);
|
|
||||||
|
|
||||||
return resolutionResponse.finalize();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
HasteDependencyResolver.prototype._getPolyfillDependencies = function(isDev) {
|
|
||||||
var polyfillModuleNames = [
|
|
||||||
isDev
|
|
||||||
? path.join(__dirname, 'polyfills/prelude_dev.js')
|
|
||||||
: path.join(__dirname, 'polyfills/prelude.js'),
|
|
||||||
path.join(__dirname, 'polyfills/require.js'),
|
|
||||||
path.join(__dirname, 'polyfills/polyfills.js'),
|
|
||||||
path.join(__dirname, 'polyfills/console.js'),
|
|
||||||
path.join(__dirname, 'polyfills/error-guard.js'),
|
|
||||||
path.join(__dirname, 'polyfills/String.prototype.es6.js'),
|
|
||||||
path.join(__dirname, 'polyfills/Array.prototype.es6.js'),
|
|
||||||
].concat(this._polyfillModuleNames);
|
|
||||||
|
|
||||||
return polyfillModuleNames.map(
|
|
||||||
(polyfillModuleName, idx) => new Polyfill({
|
|
||||||
path: polyfillModuleName,
|
|
||||||
id: polyfillModuleName,
|
|
||||||
dependencies: polyfillModuleNames.slice(0, idx),
|
|
||||||
isPolyfill: true,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
HasteDependencyResolver.prototype.wrapModule = function(resolutionResponse, module, code) {
|
|
||||||
return Promise.resolve().then(() => {
|
|
||||||
if (module.isPolyfill()) {
|
|
||||||
return Promise.resolve(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
const resolvedDeps = Object.create(null);
|
|
||||||
const resolvedDepsArr = [];
|
|
||||||
|
|
||||||
return Promise.all(
|
|
||||||
resolutionResponse.getResolvedDependencyPairs(module).map(
|
|
||||||
([depName, depModule]) => {
|
|
||||||
if (depModule) {
|
|
||||||
return depModule.getName().then(name => {
|
|
||||||
resolvedDeps[depName] = name;
|
|
||||||
resolvedDepsArr.push(name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
).then(() => {
|
|
||||||
const relativizeCode = (codeMatch, pre, quot, depName, post) => {
|
|
||||||
const depId = resolvedDeps[depName];
|
|
||||||
if (depId) {
|
|
||||||
return pre + quot + depId + post;
|
|
||||||
} else {
|
|
||||||
return codeMatch;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return module.getName().then(
|
|
||||||
name => defineModuleCode({
|
|
||||||
code: code.replace(replacePatterns.IMPORT_RE, relativizeCode)
|
|
||||||
.replace(replacePatterns.EXPORT_RE, relativizeCode)
|
|
||||||
.replace(replacePatterns.REQUIRE_RE, relativizeCode),
|
|
||||||
moduleName: name,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
HasteDependencyResolver.prototype.getDebugInfo = function() {
|
|
||||||
return this._depGraph.getDebugInfo();
|
|
||||||
};
|
|
||||||
|
|
||||||
function defineModuleCode({moduleName, code}) {
|
|
||||||
return [
|
|
||||||
`__d(`,
|
|
||||||
`'${moduleName}',`,
|
|
||||||
'function(global, require, module, exports) {',
|
|
||||||
` ${code}`,
|
|
||||||
'\n});',
|
|
||||||
].join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = HasteDependencyResolver;
|
|
@ -10,19 +10,20 @@
|
|||||||
|
|
||||||
jest.dontMock('../')
|
jest.dontMock('../')
|
||||||
.dontMock('underscore')
|
.dontMock('underscore')
|
||||||
.dontMock('../replacePatterns');
|
.dontMock('../../DependencyResolver/replacePatterns');
|
||||||
|
|
||||||
jest.mock('path');
|
jest.mock('path');
|
||||||
|
|
||||||
var Promise = require('promise');
|
var Promise = require('promise');
|
||||||
var HasteDependencyResolver = require('../');
|
var Resolver = require('../');
|
||||||
var Module = require('../Module');
|
var Module = require('../../DependencyResolver/Module');
|
||||||
var Polyfill = require('../Polyfill');
|
var Polyfill = require('../../DependencyResolver/Polyfill');
|
||||||
|
var DependencyGraph = require('../../DependencyResolver/DependencyGraph');
|
||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
|
|
||||||
describe('HasteDependencyResolver', function() {
|
describe('Resolver', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
Polyfill.mockClear();
|
Polyfill.mockClear();
|
||||||
|
|
||||||
@ -60,13 +61,11 @@ describe('HasteDependencyResolver', function() {
|
|||||||
var module = createModule('index');
|
var module = createModule('index');
|
||||||
var deps = [module];
|
var deps = [module];
|
||||||
|
|
||||||
var depResolver = new HasteDependencyResolver({
|
var depResolver = new Resolver({
|
||||||
projectRoot: '/root',
|
projectRoot: '/root',
|
||||||
});
|
});
|
||||||
|
|
||||||
// Is there a better way? How can I mock the prototype instead?
|
DependencyGraph.prototype.getDependencies.mockImpl(function() {
|
||||||
var depGraph = depResolver._depGraph;
|
|
||||||
depGraph.getDependencies.mockImpl(function() {
|
|
||||||
return Promise.resolve(new ResolutionResponseMock({
|
return Promise.resolve(new ResolutionResponseMock({
|
||||||
dependencies: deps,
|
dependencies: deps,
|
||||||
mainModuleId: 'index',
|
mainModuleId: 'index',
|
||||||
@ -144,12 +143,11 @@ describe('HasteDependencyResolver', function() {
|
|||||||
var module = createModule('index');
|
var module = createModule('index');
|
||||||
var deps = [module];
|
var deps = [module];
|
||||||
|
|
||||||
var depResolver = new HasteDependencyResolver({
|
var depResolver = new Resolver({
|
||||||
projectRoot: '/root',
|
projectRoot: '/root',
|
||||||
});
|
});
|
||||||
|
|
||||||
var depGraph = depResolver._depGraph;
|
DependencyGraph.prototype.getDependencies.mockImpl(function() {
|
||||||
depGraph.getDependencies.mockImpl(function() {
|
|
||||||
return Promise.resolve(new ResolutionResponseMock({
|
return Promise.resolve(new ResolutionResponseMock({
|
||||||
dependencies: deps,
|
dependencies: deps,
|
||||||
mainModuleId: 'index',
|
mainModuleId: 'index',
|
||||||
@ -160,7 +158,7 @@ describe('HasteDependencyResolver', function() {
|
|||||||
return depResolver.getDependencies('/root/index.js', { dev: true })
|
return depResolver.getDependencies('/root/index.js', { dev: true })
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
expect(result.mainModuleId).toEqual('index');
|
expect(result.mainModuleId).toEqual('index');
|
||||||
expect(depGraph.getDependencies).toBeCalledWith('/root/index.js', undefined);
|
expect(DependencyGraph.mock.instances[0].getDependencies).toBeCalledWith('/root/index.js', undefined);
|
||||||
expect(result.dependencies[0]).toBe(Polyfill.mock.instances[0]);
|
expect(result.dependencies[0]).toBe(Polyfill.mock.instances[0]);
|
||||||
expect(result.dependencies[result.dependencies.length - 1])
|
expect(result.dependencies[result.dependencies.length - 1])
|
||||||
.toBe(module);
|
.toBe(module);
|
||||||
@ -171,13 +169,12 @@ describe('HasteDependencyResolver', function() {
|
|||||||
var module = createModule('index');
|
var module = createModule('index');
|
||||||
var deps = [module];
|
var deps = [module];
|
||||||
|
|
||||||
var depResolver = new HasteDependencyResolver({
|
var depResolver = new Resolver({
|
||||||
projectRoot: '/root',
|
projectRoot: '/root',
|
||||||
polyfillModuleNames: ['some module'],
|
polyfillModuleNames: ['some module'],
|
||||||
});
|
});
|
||||||
|
|
||||||
var depGraph = depResolver._depGraph;
|
DependencyGraph.prototype.getDependencies.mockImpl(function() {
|
||||||
depGraph.getDependencies.mockImpl(function() {
|
|
||||||
return Promise.resolve(new ResolutionResponseMock({
|
return Promise.resolve(new ResolutionResponseMock({
|
||||||
dependencies: deps,
|
dependencies: deps,
|
||||||
mainModuleId: 'index',
|
mainModuleId: 'index',
|
||||||
@ -209,11 +206,10 @@ describe('HasteDependencyResolver', function() {
|
|||||||
|
|
||||||
describe('wrapModule', function() {
|
describe('wrapModule', function() {
|
||||||
pit('should resolve modules', function() {
|
pit('should resolve modules', function() {
|
||||||
var depResolver = new HasteDependencyResolver({
|
var depResolver = new Resolver({
|
||||||
projectRoot: '/root',
|
projectRoot: '/root',
|
||||||
});
|
});
|
||||||
|
|
||||||
var depGraph = depResolver._depGraph;
|
|
||||||
var dependencies = ['x', 'y', 'z', 'a', 'b'];
|
var dependencies = ['x', 'y', 'z', 'a', 'b'];
|
||||||
|
|
||||||
/*eslint-disable */
|
/*eslint-disable */
|
178
react-packager/src/Resolver/index.js
vendored
Normal file
178
react-packager/src/Resolver/index.js
vendored
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
var DependencyGraph = require('../DependencyResolver/DependencyGraph');
|
||||||
|
var replacePatterns = require('../DependencyResolver/replacePatterns');
|
||||||
|
var Polyfill = require('../DependencyResolver/Polyfill');
|
||||||
|
var declareOpts = require('../lib/declareOpts');
|
||||||
|
var Promise = require('promise');
|
||||||
|
|
||||||
|
var validateOpts = declareOpts({
|
||||||
|
projectRoots: {
|
||||||
|
type: 'array',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
blacklistRE: {
|
||||||
|
type: 'object', // typeof regex is object
|
||||||
|
},
|
||||||
|
polyfillModuleNames: {
|
||||||
|
type: 'array',
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
moduleFormat: {
|
||||||
|
type: 'string',
|
||||||
|
default: 'haste',
|
||||||
|
},
|
||||||
|
assetRoots: {
|
||||||
|
type: 'array',
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
fileWatcher: {
|
||||||
|
type: 'object',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
assetExts: {
|
||||||
|
type: 'array',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
cache: {
|
||||||
|
type: 'object',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var getDependenciesValidateOpts = declareOpts({
|
||||||
|
dev: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
platform: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
class Resolver {
|
||||||
|
|
||||||
|
constructor(options) {
|
||||||
|
var opts = validateOpts(options);
|
||||||
|
|
||||||
|
this._depGraph = new DependencyGraph({
|
||||||
|
roots: opts.projectRoots,
|
||||||
|
assetRoots_DEPRECATED: opts.assetRoots,
|
||||||
|
assetExts: opts.assetExts,
|
||||||
|
ignoreFilePath: function(filepath) {
|
||||||
|
return filepath.indexOf('__tests__') !== -1 ||
|
||||||
|
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
||||||
|
},
|
||||||
|
fileWatcher: opts.fileWatcher,
|
||||||
|
cache: opts.cache,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._polyfillModuleNames = opts.polyfillModuleNames || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
getDependencies(main, options) {
|
||||||
|
var opts = getDependenciesValidateOpts(options);
|
||||||
|
|
||||||
|
return this._depGraph.getDependencies(main, opts.platform).then(
|
||||||
|
resolutionResponse => {
|
||||||
|
this._getPolyfillDependencies(opts.dev).reverse().forEach(
|
||||||
|
polyfill => resolutionResponse.prependDependency(polyfill)
|
||||||
|
);
|
||||||
|
|
||||||
|
return resolutionResponse.finalize();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getPolyfillDependencies(isDev) {
|
||||||
|
var polyfillModuleNames = [
|
||||||
|
isDev
|
||||||
|
? path.join(__dirname, 'polyfills/prelude_dev.js')
|
||||||
|
: path.join(__dirname, 'polyfills/prelude.js'),
|
||||||
|
path.join(__dirname, 'polyfills/require.js'),
|
||||||
|
path.join(__dirname, 'polyfills/polyfills.js'),
|
||||||
|
path.join(__dirname, 'polyfills/console.js'),
|
||||||
|
path.join(__dirname, 'polyfills/error-guard.js'),
|
||||||
|
path.join(__dirname, 'polyfills/String.prototype.es6.js'),
|
||||||
|
path.join(__dirname, 'polyfills/Array.prototype.es6.js'),
|
||||||
|
].concat(this._polyfillModuleNames);
|
||||||
|
|
||||||
|
return polyfillModuleNames.map(
|
||||||
|
(polyfillModuleName, idx) => new Polyfill({
|
||||||
|
path: polyfillModuleName,
|
||||||
|
id: polyfillModuleName,
|
||||||
|
dependencies: polyfillModuleNames.slice(0, idx),
|
||||||
|
isPolyfill: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapModule(resolutionResponse, module, code) {
|
||||||
|
return Promise.resolve().then(() => {
|
||||||
|
if (module.isPolyfill()) {
|
||||||
|
return Promise.resolve(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resolvedDeps = Object.create(null);
|
||||||
|
const resolvedDepsArr = [];
|
||||||
|
|
||||||
|
return Promise.all(
|
||||||
|
resolutionResponse.getResolvedDependencyPairs(module).map(
|
||||||
|
([depName, depModule]) => {
|
||||||
|
if (depModule) {
|
||||||
|
return depModule.getName().then(name => {
|
||||||
|
resolvedDeps[depName] = name;
|
||||||
|
resolvedDepsArr.push(name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).then(() => {
|
||||||
|
const relativizeCode = (codeMatch, pre, quot, depName, post) => {
|
||||||
|
const depId = resolvedDeps[depName];
|
||||||
|
if (depId) {
|
||||||
|
return pre + quot + depId + post;
|
||||||
|
} else {
|
||||||
|
return codeMatch;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return module.getName().then(
|
||||||
|
name => defineModuleCode({
|
||||||
|
code: code.replace(replacePatterns.IMPORT_RE, relativizeCode)
|
||||||
|
.replace(replacePatterns.EXPORT_RE, relativizeCode)
|
||||||
|
.replace(replacePatterns.REQUIRE_RE, relativizeCode),
|
||||||
|
moduleName: name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getDebugInfo() {
|
||||||
|
return this._depGraph.getDebugInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function defineModuleCode({moduleName, code}) {
|
||||||
|
return [
|
||||||
|
`__d(`,
|
||||||
|
`'${moduleName}',`,
|
||||||
|
'function(global, require, module, exports) {',
|
||||||
|
` ${code}`,
|
||||||
|
'\n});',
|
||||||
|
].join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Resolver;
|
@ -55,7 +55,7 @@
|
|||||||
mod.isInitialized = true;
|
mod.isInitialized = true;
|
||||||
|
|
||||||
// keep args in sync with with defineModuleCode in
|
// keep args in sync with with defineModuleCode in
|
||||||
// packager/react-packager/src/DependencyResolver/index.js
|
// packager/react-packager/src/Resolver/index.js
|
||||||
mod.factory.call(global, global, require, mod.module, mod.module.exports);
|
mod.factory.call(global, global, require, mod.module, mod.module.exports);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
mod.hasError = true;
|
mod.hasError = true;
|
Loading…
x
Reference in New Issue
Block a user