mirror of https://github.com/status-im/metro.git
Consume react, fbjs from npm
Summary: We don't (yet) treat these the same as any other modules because we still have special resolution rules for them in the packager allowing the use of `providesModule`, but I believe this allows people to use npm react in their RN projects and not have duplicate copies of React. Fixes facebook/react-native#2985. This relies on fbjs 0.6, which includes `.flow` files alongside the `.js` files to allow them to be typechecked without additional configuration. This also uses react 0.14.5, which shims a couple of files (as `.native.js`) to avoid DOM-specific bits. Once we fix these in React, we will use the same code on web and native. Hopefully we can also remove the packager support I'm adding here for `.native.js`. This diff is not the desired end state for us – ideally the packager would know nothing of react or fbjs, and we'll get there eventually by not relying on `providesModule` in order to load react and fbjs modules. (fbjs change posted here but not merged yet: https://github.com/facebook/fbjs/pull/84.) This should also allow relay to work seamlessly with RN, but I haven't verified this. public Reviewed By: sebmarkbage Differential Revision: D2786197 fb-gh-sync-id: ff50f28445e949edc9501f4b599df7970813870d
This commit is contained in:
parent
eed6dde1d4
commit
e41008f208
77
blacklist.js
77
blacklist.js
|
@ -13,36 +13,41 @@ var path = require('path');
|
||||||
// Don't forget to everything listed here to `testConfig.json`
|
// Don't forget to everything listed here to `testConfig.json`
|
||||||
// modulePathIgnorePatterns.
|
// modulePathIgnorePatterns.
|
||||||
var sharedBlacklist = [
|
var sharedBlacklist = [
|
||||||
'node_modules/react-haste/renderers/shared/event/eventPlugins/ResponderEventPlugin.js',
|
/node_modules[/\\]react[/\\]dist[/\\].*/,
|
||||||
'node_modules/react-haste/React.js',
|
'node_modules/react/lib/React.js',
|
||||||
'node_modules/react-haste/renderers/dom/ReactDOM.js',
|
'node_modules/react/lib/ReactDOM.js',
|
||||||
|
|
||||||
// For each of these fbjs files (especially the non-forks/stubs), we should
|
// For each of these fbjs files (especially the non-forks/stubs), we should
|
||||||
// consider deleting the conflicting copy and just using the fbjs version.
|
// consider deleting the conflicting copy and just using the fbjs version.
|
||||||
'node_modules/fbjs-haste/__forks__/Map.js',
|
//
|
||||||
'node_modules/fbjs-haste/__forks__/Promise.js',
|
// fbjs forks:
|
||||||
'node_modules/fbjs-haste/__forks__/fetch.js',
|
'node_modules/fbjs/lib/Map.js',
|
||||||
'node_modules/fbjs-haste/core/Deferred.js',
|
'node_modules/fbjs/lib/Promise.js',
|
||||||
'node_modules/fbjs-haste/core/PromiseMap.js',
|
'node_modules/fbjs/lib/fetch.js',
|
||||||
'node_modules/fbjs-haste/core/areEqual.js',
|
// fbjs stubs:
|
||||||
'node_modules/fbjs-haste/core/flattenArray.js',
|
'node_modules/fbjs/lib/ErrorUtils.js',
|
||||||
'node_modules/fbjs-haste/core/isEmpty.js',
|
'node_modules/fbjs/lib/URI.js',
|
||||||
'node_modules/fbjs-haste/core/removeFromArray.js',
|
// fbjs modules:
|
||||||
'node_modules/fbjs-haste/core/resolveImmediate.js',
|
'node_modules/fbjs/lib/Deferred.js',
|
||||||
'node_modules/fbjs-haste/core/sprintf.js',
|
'node_modules/fbjs/lib/PromiseMap.js',
|
||||||
'node_modules/fbjs-haste/crypto/crc32.js',
|
'node_modules/fbjs/lib/UserAgent.js',
|
||||||
'node_modules/fbjs-haste/fetch/fetchWithRetries.js',
|
'node_modules/fbjs/lib/areEqual.js',
|
||||||
'node_modules/fbjs-haste/functional/everyObject.js',
|
'node_modules/fbjs/lib/base62.js',
|
||||||
'node_modules/fbjs-haste/functional/filterObject.js',
|
'node_modules/fbjs/lib/crc32.js',
|
||||||
'node_modules/fbjs-haste/functional/forEachObject.js',
|
'node_modules/fbjs/lib/everyObject.js',
|
||||||
'node_modules/fbjs-haste/functional/someObject.js',
|
'node_modules/fbjs/lib/fetchWithRetries.js',
|
||||||
'node_modules/fbjs-haste/request/xhrSimpleDataSerializer.js',
|
'node_modules/fbjs/lib/filterObject.js',
|
||||||
'node_modules/fbjs-haste/stubs/ErrorUtils.js',
|
'node_modules/fbjs/lib/flattenArray.js',
|
||||||
'node_modules/fbjs-haste/stubs/URI.js',
|
'node_modules/fbjs/lib/forEachObject.js',
|
||||||
'node_modules/fbjs-haste/useragent/UserAgent.js',
|
'node_modules/fbjs/lib/isEmpty.js',
|
||||||
'node_modules/fbjs-haste/utils/nullthrows.js',
|
'node_modules/fbjs/lib/nullthrows.js',
|
||||||
|
'node_modules/fbjs/lib/removeFromArray.js',
|
||||||
|
'node_modules/fbjs/lib/resolveImmediate.js',
|
||||||
|
'node_modules/fbjs/lib/someObject.js',
|
||||||
|
'node_modules/fbjs/lib/sprintf.js',
|
||||||
|
'node_modules/fbjs/lib/xhrSimpleDataSerializer.js',
|
||||||
|
|
||||||
// Those conflicts with the ones in fbjs-haste/. We need to blacklist the
|
// Those conflicts with the ones in fbjs/. We need to blacklist the
|
||||||
// internal version otherwise they won't work in open source.
|
// internal version otherwise they won't work in open source.
|
||||||
'downstream/core/CSSCore.js',
|
'downstream/core/CSSCore.js',
|
||||||
'downstream/core/TouchEventUtils.js',
|
'downstream/core/TouchEventUtils.js',
|
||||||
|
@ -63,11 +68,8 @@ var sharedBlacklist = [
|
||||||
'downstream/core/invariant.js',
|
'downstream/core/invariant.js',
|
||||||
'downstream/core/nativeRequestAnimationFrame.js',
|
'downstream/core/nativeRequestAnimationFrame.js',
|
||||||
'downstream/core/toArray.js',
|
'downstream/core/toArray.js',
|
||||||
];
|
|
||||||
|
|
||||||
// Raw unescaped patterns in case you need to use wildcards
|
/website\/node_modules\/.*/,
|
||||||
var sharedBlacklistWildcards = [
|
|
||||||
'website\/node_modules\/.*',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
var platformBlacklists = {
|
var platformBlacklists = {
|
||||||
|
@ -85,10 +87,16 @@ var platformBlacklists = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
function escapeRegExp(str) {
|
function escapeRegExp(pattern) {
|
||||||
var escaped = str.replace(/[\-\[\]\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
|
if (Object.prototype.toString.call(pattern) === '[object RegExp]') {
|
||||||
// convert the '/' into an escaped local file separator
|
return pattern.source;
|
||||||
return escaped.replace(/\//g,'\\' + path.sep);
|
} else if (typeof pattern === 'string') {
|
||||||
|
var escaped = pattern.replace(/[\-\[\]\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
|
||||||
|
// convert the '/' into an escaped local file separator
|
||||||
|
return escaped.replace(/\//g,'\\' + path.sep);
|
||||||
|
} else {
|
||||||
|
throw new Error('Unexpected packager blacklist pattern: ' + pattern);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function blacklist(platform, additionalBlacklist) {
|
function blacklist(platform, additionalBlacklist) {
|
||||||
|
@ -96,7 +104,6 @@ function blacklist(platform, additionalBlacklist) {
|
||||||
(additionalBlacklist || []).concat(sharedBlacklist)
|
(additionalBlacklist || []).concat(sharedBlacklist)
|
||||||
.concat(platformBlacklists[platform] || [])
|
.concat(platformBlacklists[platform] || [])
|
||||||
.map(escapeRegExp)
|
.map(escapeRegExp)
|
||||||
.concat(sharedBlacklistWildcards)
|
|
||||||
.join('|') +
|
.join('|') +
|
||||||
')$'
|
')$'
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,12 +12,20 @@ const getPlatformExtension = require('../lib/getPlatformExtension');
|
||||||
const Promise = require('promise');
|
const Promise = require('promise');
|
||||||
|
|
||||||
const GENERIC_PLATFORM = 'generic';
|
const GENERIC_PLATFORM = 'generic';
|
||||||
|
const NATIVE_PLATFORM = 'native';
|
||||||
|
|
||||||
class HasteMap {
|
class HasteMap {
|
||||||
constructor({ extensions, fastfs, moduleCache, helpers }) {
|
constructor({
|
||||||
|
extensions,
|
||||||
|
fastfs,
|
||||||
|
moduleCache,
|
||||||
|
preferNativePlatform,
|
||||||
|
helpers,
|
||||||
|
}) {
|
||||||
this._extensions = extensions;
|
this._extensions = extensions;
|
||||||
this._fastfs = fastfs;
|
this._fastfs = fastfs;
|
||||||
this._moduleCache = moduleCache;
|
this._moduleCache = moduleCache;
|
||||||
|
this._preferNativePlatform = preferNativePlatform;
|
||||||
this._helpers = helpers;
|
this._helpers = helpers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,18 +81,19 @@ class HasteMap {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no platform is given we choose the generic platform module list.
|
// If platform is 'ios', we prefer .ios.js to .native.js which we prefer to
|
||||||
// If a platform is given and no modules exist we fallback
|
// a plain .js file.
|
||||||
// to the generic platform module list.
|
let module = undefined;
|
||||||
if (platform == null) {
|
if (module == null && platform != null) {
|
||||||
return modulesMap[GENERIC_PLATFORM];
|
module = modulesMap[platform];
|
||||||
} else {
|
|
||||||
let module = modulesMap[platform];
|
|
||||||
if (module == null) {
|
|
||||||
module = modulesMap[GENERIC_PLATFORM];
|
|
||||||
}
|
|
||||||
return module;
|
|
||||||
}
|
}
|
||||||
|
if (module == null && this._preferNativePlatform) {
|
||||||
|
module = modulesMap[NATIVE_PLATFORM];
|
||||||
|
}
|
||||||
|
if (module == null) {
|
||||||
|
module = modulesMap[GENERIC_PLATFORM];
|
||||||
|
}
|
||||||
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
_processHasteModule(file) {
|
_processHasteModule(file) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ const Promise = require('promise');
|
||||||
class ResolutionRequest {
|
class ResolutionRequest {
|
||||||
constructor({
|
constructor({
|
||||||
platform,
|
platform,
|
||||||
|
preferNativePlatform,
|
||||||
entryPath,
|
entryPath,
|
||||||
hasteMap,
|
hasteMap,
|
||||||
deprecatedAssetMap,
|
deprecatedAssetMap,
|
||||||
|
@ -26,6 +27,7 @@ class ResolutionRequest {
|
||||||
fastfs,
|
fastfs,
|
||||||
}) {
|
}) {
|
||||||
this._platform = platform;
|
this._platform = platform;
|
||||||
|
this._preferNativePlatform = preferNativePlatform;
|
||||||
this._entryPath = entryPath;
|
this._entryPath = entryPath;
|
||||||
this._hasteMap = hasteMap;
|
this._hasteMap = hasteMap;
|
||||||
this._deprecatedAssetMap = deprecatedAssetMap;
|
this._deprecatedAssetMap = deprecatedAssetMap;
|
||||||
|
@ -329,6 +331,9 @@ class ResolutionRequest {
|
||||||
} else if (this._platform != null &&
|
} else if (this._platform != null &&
|
||||||
this._fastfs.fileExists(potentialModulePath + '.' + this._platform + '.js')) {
|
this._fastfs.fileExists(potentialModulePath + '.' + this._platform + '.js')) {
|
||||||
file = potentialModulePath + '.' + this._platform + '.js';
|
file = potentialModulePath + '.' + this._platform + '.js';
|
||||||
|
} else if (this._preferNativePlatform &&
|
||||||
|
this._fastfs.fileExists(potentialModulePath + '.native.js')) {
|
||||||
|
file = potentialModulePath + '.native.js';
|
||||||
} else if (this._fastfs.fileExists(potentialModulePath + '.js')) {
|
} else if (this._fastfs.fileExists(potentialModulePath + '.js')) {
|
||||||
file = potentialModulePath + '.js';
|
file = potentialModulePath + '.js';
|
||||||
} else if (this._fastfs.fileExists(potentialModulePath + '.json')) {
|
} else if (this._fastfs.fileExists(potentialModulePath + '.json')) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ class DependencyGraph {
|
||||||
assetExts,
|
assetExts,
|
||||||
providesModuleNodeModules,
|
providesModuleNodeModules,
|
||||||
platforms,
|
platforms,
|
||||||
|
preferNativePlatform,
|
||||||
cache,
|
cache,
|
||||||
extensions,
|
extensions,
|
||||||
mocksPattern,
|
mocksPattern,
|
||||||
|
@ -51,6 +52,7 @@ class DependencyGraph {
|
||||||
assetExts: assetExts || [],
|
assetExts: assetExts || [],
|
||||||
providesModuleNodeModules,
|
providesModuleNodeModules,
|
||||||
platforms: platforms || [],
|
platforms: platforms || [],
|
||||||
|
preferNativePlatform: preferNativePlatform || false,
|
||||||
cache,
|
cache,
|
||||||
extensions: extensions || ['js', 'json'],
|
extensions: extensions || ['js', 'json'],
|
||||||
mocksPattern,
|
mocksPattern,
|
||||||
|
@ -105,7 +107,7 @@ class DependencyGraph {
|
||||||
fastfs: this._fastfs,
|
fastfs: this._fastfs,
|
||||||
extensions: this._opts.extensions,
|
extensions: this._opts.extensions,
|
||||||
moduleCache: this._moduleCache,
|
moduleCache: this._moduleCache,
|
||||||
assetExts: this._opts.exts,
|
preferNativePlatform: this._opts.preferNativePlatform,
|
||||||
helpers: this._helpers,
|
helpers: this._helpers,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -147,6 +149,7 @@ class DependencyGraph {
|
||||||
const absPath = this._getAbsolutePath(entryPath);
|
const absPath = this._getAbsolutePath(entryPath);
|
||||||
const req = new ResolutionRequest({
|
const req = new ResolutionRequest({
|
||||||
platform,
|
platform,
|
||||||
|
preferNativePlatform: this._opts.preferNativePlatform,
|
||||||
entryPath: absPath,
|
entryPath: absPath,
|
||||||
deprecatedAssetMap: this._deprecatedAssetMap,
|
deprecatedAssetMap: this._deprecatedAssetMap,
|
||||||
hasteMap: this._hasteMap,
|
hasteMap: this._hasteMap,
|
||||||
|
|
|
@ -81,8 +81,8 @@ class Resolver {
|
||||||
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
||||||
},
|
},
|
||||||
providesModuleNodeModules: [
|
providesModuleNodeModules: [
|
||||||
'fbjs-haste',
|
'fbjs',
|
||||||
'react-haste',
|
'react',
|
||||||
'react-native',
|
'react-native',
|
||||||
// Parse requires AsyncStorage. They will
|
// Parse requires AsyncStorage. They will
|
||||||
// change that to require('react-native') which
|
// change that to require('react-native') which
|
||||||
|
@ -92,6 +92,7 @@ class Resolver {
|
||||||
'react-transform-hmr',
|
'react-transform-hmr',
|
||||||
],
|
],
|
||||||
platforms: ['ios', 'android'],
|
platforms: ['ios', 'android'],
|
||||||
|
preferNativePlatform: true,
|
||||||
fileWatcher: opts.fileWatcher,
|
fileWatcher: opts.fileWatcher,
|
||||||
cache: opts.cache,
|
cache: opts.cache,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue