2015-11-04 16:04:44 -08:00
|
|
|
/**
|
|
|
|
* 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';
|
|
|
|
|
|
|
|
|
2015-11-09 13:32:42 -08:00
|
|
|
const path = require('path');
|
|
|
|
const Activity = require('../Activity');
|
|
|
|
const DependencyGraph = require('../DependencyResolver/DependencyGraph');
|
2015-11-16 22:48:28 -08:00
|
|
|
const replacePatterns = require('../DependencyResolver/lib/replacePatterns');
|
2015-11-09 13:32:42 -08:00
|
|
|
const Polyfill = require('../DependencyResolver/Polyfill');
|
|
|
|
const declareOpts = require('../lib/declareOpts');
|
|
|
|
const Promise = require('promise');
|
|
|
|
|
|
|
|
const validateOpts = declareOpts({
|
2015-11-04 16:04:44 -08:00
|
|
|
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,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2015-11-09 13:32:42 -08:00
|
|
|
const getDependenciesValidateOpts = declareOpts({
|
2015-11-04 16:04:44 -08:00
|
|
|
dev: {
|
|
|
|
type: 'boolean',
|
|
|
|
default: true,
|
|
|
|
},
|
|
|
|
platform: {
|
|
|
|
type: 'string',
|
|
|
|
required: false,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
class Resolver {
|
|
|
|
|
|
|
|
constructor(options) {
|
2015-11-09 13:32:42 -08:00
|
|
|
const opts = validateOpts(options);
|
2015-11-04 16:04:44 -08:00
|
|
|
|
|
|
|
this._depGraph = new DependencyGraph({
|
2015-11-09 13:32:42 -08:00
|
|
|
activity: Activity,
|
2015-11-04 16:04:44 -08:00
|
|
|
roots: opts.projectRoots,
|
|
|
|
assetRoots_DEPRECATED: opts.assetRoots,
|
|
|
|
assetExts: opts.assetExts,
|
|
|
|
ignoreFilePath: function(filepath) {
|
|
|
|
return filepath.indexOf('__tests__') !== -1 ||
|
|
|
|
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
|
|
|
},
|
2015-11-09 13:32:46 -08:00
|
|
|
providesModuleNodeModules: [
|
|
|
|
'fbjs-haste',
|
|
|
|
'react-haste',
|
|
|
|
'react-native',
|
|
|
|
// Parse requires AsyncStorage. They will
|
|
|
|
// change that to require('react-native') which
|
|
|
|
// should work after this release and we can
|
|
|
|
// remove it from here.
|
|
|
|
'parse',
|
|
|
|
],
|
|
|
|
platforms: ['ios', 'android'],
|
2015-11-04 16:04:44 -08:00
|
|
|
fileWatcher: opts.fileWatcher,
|
|
|
|
cache: opts.cache,
|
|
|
|
});
|
|
|
|
|
|
|
|
this._polyfillModuleNames = opts.polyfillModuleNames || [];
|
|
|
|
}
|
|
|
|
|
|
|
|
getDependencies(main, options) {
|
2015-11-09 13:32:42 -08:00
|
|
|
const opts = getDependenciesValidateOpts(options);
|
2015-11-04 16:04:44 -08:00
|
|
|
|
|
|
|
return this._depGraph.getDependencies(main, opts.platform).then(
|
|
|
|
resolutionResponse => {
|
|
|
|
this._getPolyfillDependencies(opts.dev).reverse().forEach(
|
|
|
|
polyfill => resolutionResponse.prependDependency(polyfill)
|
|
|
|
);
|
|
|
|
|
|
|
|
return resolutionResponse.finalize();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
_getPolyfillDependencies(isDev) {
|
2015-11-09 13:32:42 -08:00
|
|
|
const polyfillModuleNames = [
|
2015-11-04 16:04:44 -08:00
|
|
|
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'),
|
2015-11-06 17:19:55 -08:00
|
|
|
path.join(__dirname, 'polyfills/Array.es6.js'),
|
2015-11-11 22:53:04 -08:00
|
|
|
path.join(__dirname, 'polyfills/babelHelpers.js'),
|
2015-11-04 16:04:44 -08:00
|
|
|
].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;
|