-
Notifications
You must be signed in to change notification settings - Fork 24.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Packager] Fix @providesModule not being ignored properly #3625
Conversation
By analyzing the blame information on this pull request, we identified @martinbigio, @amasad and @vjeux to be potential reviewers. |
@@ -22,6 +22,7 @@ jest | |||
var Fastfs = require('../fastfs'); | |||
var Module = require('../Module'); | |||
var ModuleCache = require('../ModuleCache'); | |||
var Helpers = require('../DependencyGraph/Helpers'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to rename this module to be more descriptive (not sure what though. DependencyGraphHelpers?) since it's being used outside of DependencyGraph now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally agree.
@skevy updated the pull request. |
@martinbigio should I update and rebase this PR, or are you guys fixing this issue in a different way? |
@skevy fyi Martin is in PTO for three weeks starting today :x Let me take it |
Yay time off! I wish I could get some of that. :( |
Thanks for taking over! |
@facebook-github-bot import |
Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/417058798495156/int_phab to review. |
@@ -85,7 +86,7 @@ class Module { | |||
this._reading = this._fastfs.readFile(this.path).then(content => { | |||
const data = {}; | |||
const moduleDocBlock = docblock.parseAsObject(content); | |||
if (moduleDocBlock.providesModule || moduleDocBlock.provides) { | |||
if (!this._helpers.isNodeModulesDir(this.path) && (moduleDocBlock.providesModule || moduleDocBlock.provides)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: 80 columns.
if (!this._helpers.isNodeModulesDir(this.path) &&
(moduleDocBlock.providesModule || moduleDocBlock.provides)) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I prefer:
if (!this._helpers.isNodeModulesDir(this.path) &&
(moduleDocBlock.providesModule || moduleDocBlock.provides)
) {
but I don't wanna bikeshed :P
@skevy updated the pull request. |
@facebook-github-bot import |
Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/417058798495156/int_phab to review. |
The tests are not passing because it uses variables that are never defined :x |
Could you rebase? :) I have no idea what i'm doing here :x |
Sorry @vjeux, I didn't mean to push. I'm working on this now. |
This issue with rebasing definitely has something to do with the work @cpojer is doing on the packager I think. I need to take a little bit of a look at what he's up to, and complete the rebase tomorrow when I'm fresh. Thanks for being johnny on the spot with this @vjeux...hopefully we can get it all fixed up and ready to ship tomorrow! :) |
I'm about to pull out the resolver into a separate repo sometime this week. It would be great if you could rebase this asap and land it, so I don't run into issues with syncing this. Sorry for the trouble! |
@@ -15,7 +15,7 @@ const replacePatterns = require('./replacePatterns'); | |||
|
|||
class Module { | |||
|
|||
constructor(file, fastfs, moduleCache, cache) { | |||
constructor(file, fastfs, moduleCache, cache, helpers) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably change this into taking a single object, and use destructuring in here.
@martinbigio yah I'm reopening this now, because we actually determined that the test failures were a Facebook internal infra problem (related to a babel-transform that isn't open sourced), not a problem with this PR. Wait till @vjeux tells you about this one :) |
Oh yeah, he told me how you guys fixed it. XP for the win :) |
@cpojer do any of the modified file should be modified on node-haste as well? |
const moduleDocBlock = docblock.parseAsObject(content); | ||
if (moduleDocBlock.providesModule || moduleDocBlock.provides) { | ||
if (!this._depGraphHelpers.isNodeModulesDir(this.path) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should add a comment explaining why checking for this is necessary. It's not immediately obvious to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure np.
Looks great to me. @cpojer what do you want to do with the changes that affect node-haste? How far away are we from getting rid of the duplicated code? Maybe we should think about a strategy to avoid missing changes. |
@skevy updated the pull request. |
// 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@martinbigio check out this explanation and let me know if that's good.
@skevy updated the pull request. |
74821ac
to
7b69278
Compare
@skevy updated the pull request. |
I'll chat with @cpojer to see how we can pull changes into the new resolver repo |
7b69278
to
eab854c
Compare
@skevy updated the pull request. |
…cyGraph This resolves the packager not properly ignoring @providesModule when naming modules.
…ad() Adds a comment that explains, in detail, why we should check whether the dependency is in the node_modules directory (or a whitelisted node_module) before getting it's name from @providesModule
…_modules' test case. Rather than adding an additional test case for selectively whitelisted @providesModule, add to existing test case more robust tests that handle the previously unaccounted-for use case.
…le classes. Renaming `_read` method in Module.js and Packager.js to `read`, as to not be a private method. This is done in order to allow for proper class inheritance, even when using Facebook's internal "babel-plugin-class-private-props" transform, which actually mangles method names starting with '_', preventing child classes from overriding the method.
eab854c
to
1ddc0ab
Compare
@skevy updated the pull request. |
} | ||
|
||
invalidate() { | ||
this._cache.invalidate(this.path); | ||
} | ||
|
||
_read() { | ||
read() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vjeux just pointing out that I renamed this method as we discussed, as to allow for proper class inheritance and to not break due to babel-plugin-class-private-props
.
cc @martinbigio
@facebook-github-bot shipit |
Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/417058798495156/int_phab to review. |
Yay this finally merged! Thanks @vjeux |
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 facebook/react-native#3625 Reviewed By: svcscm Differential Revision: D2632317 Pulled By: vjeux fb-gh-sync-id: efd8066eaf6f18fcf79698beab36cab90bf5cd6d
There's quite a bit of code scattered around the packager regarding ignoring the
@providesModule
Haste pragma in any file that isn't inreact-native
,react-tools
orparse
. There is even a (passing) test case.However, there's an edge case.
Take, for example,
fbjs
. It has a module inside of it calledErrorUtils
.react-relay
requires this file normally, in Common.JS style, by doingrequire('fbjs/libs/ErrorUtils')
. But whenreact-native
attempts to requireErrorUtils
using the HasteModule format (in it's JavaScript initialization), it resolves thefbjs
ErrorUtils
module, instead of RN'sErrorUtils
.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 whenModule.getName
is called, it will always use thatdata.id
that was set, thus creating the wrong dependency tree.This PR fixes that. :)