mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-13 09:20:15 +08:00
Fix @providesModule not being ignored properly
Summary:
There's quite a bit of code scattered around the packager regarding ignoring the `providesModule` Haste pragma in any file that isn't in `react-native`, `react-tools` or `parse`. There is even a (passing) test case.
However, there's an edge case.
Take, for example, `fbjs`. It has a module inside of it called `ErrorUtils`. `react-relay` requires this file normally, in Common.JS style, by doing `require('fbjs/libs/ErrorUtils')`. But when `react-native` attempts to require `ErrorUtils` using the HasteModule format (in it's JavaScript initialization), it resolves the `fbjs` `ErrorUtils` module, instead of RN's `ErrorUtils`.
This happens, it turns out, because when a module is read (in `Module._read`), it's not caring about whether or not it should pay attention to `providesModule`, and is just assigning the `providesModule` value as the id of the module no matter what. Then when `Module.getName` is called, it will always use that `data.id` that was set, thus creating the wrong dependency tree.
This
Closes https://github.com/facebook/react-native/pull/3625
Reviewed By: svcscm
Differential Revision: D2632317
Pulled By: vjeux
fb-gh-sync-id: efd8066eaf6f18fcf79698beab36cab90bf5cd6d
This commit is contained in:
committed by
facebook-github-bot-5
parent
59885911e3
commit
6cec263ca3
@@ -15,7 +15,7 @@ const extractRequires = require('./lib/extractRequires');
|
||||
|
||||
class Module {
|
||||
|
||||
constructor(file, fastfs, moduleCache, cache, extractor) {
|
||||
constructor({ file, fastfs, moduleCache, cache, extractor, depGraphHelpers }) {
|
||||
if (!isAbsolutePath(file)) {
|
||||
throw new Error('Expected file to be absolute path but got ' + file);
|
||||
}
|
||||
@@ -27,17 +27,18 @@ class Module {
|
||||
this._moduleCache = moduleCache;
|
||||
this._cache = cache;
|
||||
this._extractor = extractor;
|
||||
this._depGraphHelpers = depGraphHelpers;
|
||||
}
|
||||
|
||||
isHaste() {
|
||||
return this._read().then(data => !!data.id);
|
||||
return this.read().then(data => !!data.id);
|
||||
}
|
||||
|
||||
getName() {
|
||||
return this._cache.get(
|
||||
this.path,
|
||||
'name',
|
||||
() => this._read().then(data => {
|
||||
() => this.read().then(data => {
|
||||
if (data.id) {
|
||||
return data.id;
|
||||
}
|
||||
@@ -66,23 +67,31 @@ class Module {
|
||||
}
|
||||
|
||||
getDependencies() {
|
||||
return this._read().then(data => data.dependencies);
|
||||
return this.read().then(data => data.dependencies);
|
||||
}
|
||||
|
||||
getAsyncDependencies() {
|
||||
return this._read().then(data => data.asyncDependencies);
|
||||
return this.read().then(data => data.asyncDependencies);
|
||||
}
|
||||
|
||||
invalidate() {
|
||||
this._cache.invalidate(this.path);
|
||||
}
|
||||
|
||||
_read() {
|
||||
read() {
|
||||
if (!this._reading) {
|
||||
this._reading = this._fastfs.readFile(this.path).then(content => {
|
||||
const data = {};
|
||||
|
||||
// Set an id on the module if it's using @providesModule syntax
|
||||
// and if it's NOT in node_modules (and not a whitelisted node_module).
|
||||
// This handles the case where a project may have a dep that has @providesModule
|
||||
// docblock comments, but doesn't want it to conflict with whitelisted @providesModule
|
||||
// modules, such as react-haste, fbjs-haste, or react-native or with non-dependency,
|
||||
// project-specific code that is using @providesModule.
|
||||
const moduleDocBlock = docblock.parseAsObject(content);
|
||||
if (moduleDocBlock.providesModule || moduleDocBlock.provides) {
|
||||
if (!this._depGraphHelpers.isNodeModulesDir(this.path) &&
|
||||
(moduleDocBlock.providesModule || moduleDocBlock.provides)) {
|
||||
data.id = /^(\S*)/.exec(
|
||||
moduleDocBlock.providesModule || moduleDocBlock.provides
|
||||
)[1];
|
||||
|
||||
Reference in New Issue
Block a user