Skip to content
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

[RFC] Remove knowledge of fbjs from the packager #5084

Closed
wants to merge 8 commits into from

Conversation

skevy
Copy link
Contributor

@skevy skevy commented Jan 3, 2016

As @spicyj mentioned in commit 6a838a4, the ideal state of affairs when it comes to consuming react and fbjs from NPM is for the packager not to have knowledge of either package. This PR addresses the fbjs part of that, and relies on facebook/fbjs#95. DO NOT MERGE until #95 (or a variation) is in fbjs and is released to npm.

This PR does several things:

  1. Adds stub modules within RN that expose fbjs modules to be required using Haste. After discussing a few ideas with @spicyj, this seemed like a good option to keep internal FB devs happy (and not make them change the way they write JS), but allow for removing packager complexity and fit in better with the NPM ecosystem. Note -- it skips stubbing fetch, ExecutionEnvironment, and ErrorUtils, due to the fact that these need to have Native specific implementations, and there's no reason for those implementations to exist in fbjs.
  2. Removes the modules that were previously being used in lieu of their fbjs equivalent modules, but didn't really need to be. These include: Map, isEmpty, crc32, and Promise. Promise is a special case - it has been moved to Promise.native.js in fbjs, so that a package such as Relay can require('fbjs/lib/Promise'), and not cause problems.
  3. Removes the fbjs modules from the packager blacklist (yay!), and removes fbjs from the list of packages that the RN packager consumes Haste modules from. I left in the downstream modules, but I think those should really live within an FB-specific blacklist that you keep in your internal codebase. Let me know your thoughts there.
  4. Adds fbjs to unmockedModulePathPatterns for Jest, to allow tests to not behave weirdly. This matches FB's internal Jest config.
  5. Remove everything except fetch, ExecutionEnvironment, and ErrorUtils from the flowconfig ignore list.
  6. Fix InteractionManager-test to make sure ErrorUtils is mocked. Quite honestly, I'm not sure why this was working before.

This, combined with facebook/fbjs#95 and a yet to be submitted Relay PR, allow for Relay to be used OOTB with React Native. Woo!

Looking forward to your comments :)

/cc @vjeux @spicyj

P.S. - The tests are going to fail here, until the fbjs dep is updated.

@skevy skevy self-assigned this Jan 3, 2016
@skevy skevy added the Size/L label Jan 3, 2016
@facebook-github-bot
Copy link
Contributor

By analyzing the blame information on this pull request, we identified @spicyj, @cpojer and @none to be potential reviewers.

@skevy skevy added the Cleanup label Jan 3, 2016
@facebook-github-bot facebook-github-bot added GH Review: review-needed CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. labels Jan 3, 2016
@vjeux
Copy link
Contributor

vjeux commented Jan 3, 2016

@martinbigio

* 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.
*
* @providesModule CSSCore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's sad that we include a module named CSSCore in rn :(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not need to - I'd be happy to prune. But, I did see that CSSCore was blacklisted from downstream...so I thought there might be a place where you guys are using it internally...which is the only reason these stubs really exist anyway (otherwise we'd require from fbjs everywhere). But, I could be wrong. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we have one upstream module requires CSSCore :(

@martinbigio
Copy link
Contributor

I LOVE this change! wish one day we could remove providesModuleNodeModules support from the packager. We need to run both the oss and internal tests once fbjs#95 lands as many things could break. I don't have much to say from a review point of view, the change is pretty clean.

@martinbigio
Copy link
Contributor

What if we have have stubs only internally on Facebook. Otherwise, people on OSS may get confused trying to figure out why we expose both CommonJS and Haste modules for fbjs.

@skevy
Copy link
Contributor Author

skevy commented Jan 3, 2016

@martinbigio the reason I added the stubs here was after talking to @spicyj. We discussed that it would be a good thing to keep RN code using haste, for consistency throughout the RN codebase. Otherwise...you have require('fbjs/lib/keyMirror') next to things like require('TouchEventUtils'). Right now, just about every require in the RN code base (save these new fbjs stubs) uses Haste. This consistency could be good if one day we decided to add a prepublish task that rewrites requires to CommonJS for use in somebody's Webpack build :)

@skevy
Copy link
Contributor Author

skevy commented Jan 3, 2016

@martinbigio regarding your comment about the tests...for what it's worth, I've run flow and all the tests locally with the fbjs change included (that wasn't an easy task haha)...and the changes required are included in this diff (skevy@7c00d73, skevy@42af07e, skevy@bc4486a).

@martinbigio
Copy link
Contributor

@skevy sounds good. I'll import and test this internally once fbjs#95 lands

@skevy
Copy link
Contributor Author

skevy commented Jan 4, 2016

🚀

@skevy
Copy link
Contributor Author

skevy commented Jan 5, 2016

@martinbigio, just FYI, facebook/fbjs#95 is merged. :-)

@martinbigio
Copy link
Contributor

@facebook-github-bot import

@facebook-github-bot
Copy link
Contributor

Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/461611524028597/int_phab to review.

@davidaurelio
Copy link
Contributor

We might want to keep Promise.js, in order to be able to control warning behavior (for unhandled rejections)

@skevy
Copy link
Contributor Author

skevy commented Jan 5, 2016

@davidaurelio if we keep Promise, then projects like Relay that import "fbjs/lib/Promise" will break...hence me moving it to fbjs at Promise.native.js. Not sure if you have any thoughts on how that might be able to be fixed.

@davidaurelio
Copy link
Contributor

I will work around it in YellowBox, then. I tried to land the upgrade to [email protected] yesterday, but I can’t resolve an internal issue :-(

@skevy
Copy link
Contributor Author

skevy commented Jan 7, 2016

@davidaurelio I saw you updated Promise.js -- I guess I should bring these changes over to fbjs's Promise.native.js?

@skevy
Copy link
Contributor Author

skevy commented Jan 7, 2016

@davidaurelio PR'ed facebook/fbjs#100

@facebook-github-bot
Copy link
Contributor

@skevy updated the pull request.

@davidaurelio
Copy link
Contributor

@skevy very cool, thank you! I will probably replace this with a configurable hook in the future, so that we don’t leak too much RN specific stuff into fbjs. That should also make stack trace formatting easier.

@skevy
Copy link
Contributor Author

skevy commented Jan 8, 2016

@davidaurelio that's totally fine, just in lieu of this getting merged (because it involves so many coordinating PRs and infra changes)...I wanted to make sure we were keeping up to date.

bestander pushed a commit that referenced this pull request Feb 15, 2016
Summary:
Turns out, even after discussion that was had in #5294 (comment), we really do need this transform.

I've just included it in the preset...let me know if you all would rather publish to npm.

The actual reason why this is necessary is because in the latest sync from FB, fbjs was updated to use the `Symbol.iterator` express in it's isEmpty function: facebook/fbjs@064a484

We use this in RN in the ListView...and this change (once #5084 is merged) will cause ListView to break on older JSC context's.

This resolves that, and is probably something we should have had all along.
Closes #5824

Reviewed By: svcscm

Differential Revision: D2913315

Pulled By: vjeux

fb-gh-sync-id: abaf484a9431b3111e8118d01db8d2c0d2dd73ca
shipit-source-id: abaf484a9431b3111e8118d01db8d2c0d2dd73ca
ide referenced this pull request Feb 17, 2016
Summary:
This PR moves `react` from dependencies to peerDependencies.

In general, this would have only been important for those people using packages that depend on `react` and were using [email protected]@3 would automatically de-dupe.

However, when #5812 gets merged, dependencies will be scoped to react-native (on both npm@2 & npm@3), thus breaking projects that are using a package like `react-redux` for example, which depends on `react`. There would be two copies of React installed, and due to the use of haste modules in `react`, this would break the packager and cause naming collisions.

This PR does three things -

1. Moves the dependency from dependencies to peerDependencies
2. Updates the local-cli to run `npm install react --save` when a new project is initialized.
3. Updates `react-native upgrade` to warn if `react` is not listed in the package.json's dependencies.

**Note: This will require a shrinkwrap update.**
Closes #5813

Reviewed By: svcscm

Differential Revision: D2918380

Pulled By: androidtrunkagent

fb-gh-sync-id: 6e4234a45284be2fdf6fedf29e70b2d2d0262486
shipit-source-id: 6e4234a45284be2fdf6fedf29e70b2d2d0262486
skevy added a commit to skevy/react-native that referenced this pull request Feb 17, 2016
Currently, the `providesModuleNodeModules` option allows for specifying an array of package names, that the packager will look for within node_modules, no matter how deep they're nested, and treat them as packages that use the `@providesModule` pragma.

In reality, this is not actually the behavior we want.

npm, because of how it handles dependencies, can do all kinds of arbitrary nesting of packages when `npm install` is run. This causes a problem for how we deal with `providesModuleNodeModules`. Specifically...take `fbjs`. Currently, React Native relies on using the Haste version of `fbjs` (will be resolved in facebook#5084). Thus if npm installs multiple copies of fbjs...which is a very common thing for it to do (as can be seen by this list of issues: https://github.com/facebook/react-native/issues?utf8=%E2%9C%93&q=naming+collision+detected), we get into a state where the packager fails and says that we have a naming collision.

Really, the behavior we want is for the packager to treat only a *single* copy of a given package, that we specify in the `Resolver` in the `providesModuleNodeModules` option, as the package that it uses when trying to resolve Haste modules.

This PR provides that behavior, by changing `providesModuleNodeModules` from a list of strings to a list of objects that have a `name` key, specifying the package name, as well as a `parent` key. If `parent` is null, it will look for the package at the top level (directly under `node_modules`). If `parent` is specified, it will use the package that is nested under that parent as the Haste module.

To anyone who reads this PR and is familiar with the differences between npm2 and npm3 -- this solution works under both, given the fact that we are now shipping the NPM Shrinkwrap file with React Native when it's installed through `npm`. In both the npm2 and npm3 case, node_modules specified by RN's package.json are nested underneath `react-native` in node_modules, thus allowing us to specify, for example, that we want to use React Native's copy of `fbjs` (not any other copy that may be installed) as the module used by the packager to resolve any `requires` that reference a module in `fbjs`.
skevy added a commit to skevy/react-native that referenced this pull request Feb 17, 2016
Currently, the `providesModuleNodeModules` option allows for specifying an array of package names, that the packager will look for within node_modules, no matter how deep they're nested, and treat them as packages that use the `@providesModule` pragma.

In reality, this is not actually the behavior we want.

npm, because of how it handles dependencies, can do all kinds of arbitrary nesting of packages when `npm install` is run. This causes a problem for how we deal with `providesModuleNodeModules`. Specifically...take `fbjs`. Currently, React Native relies on using the Haste version of `fbjs` (will be resolved in facebook#5084). Thus if npm installs multiple copies of fbjs...which is a very common thing for it to do (as can be seen by this list of issues: https://github.com/facebook/react-native/issues?utf8=%E2%9C%93&q=naming+collision+detected), we get into a state where the packager fails and says that we have a naming collision.

Really, the behavior we want is for the packager to treat only a *single* copy of a given package, that we specify in the `Resolver` in the `providesModuleNodeModules` option, as the package that it uses when trying to resolve Haste modules.

This PR provides that behavior, by changing `providesModuleNodeModules` from a list of strings to a list of objects that have a `name` key, specifying the package name, as well as a `parent` key. If `parent` is null, it will look for the package at the top level (directly under `node_modules`). If `parent` is specified, it will use the package that is nested under that parent as the Haste module.

To anyone who reads this PR and is familiar with the differences between npm2 and npm3 -- this solution works under both, given the fact that we are now shipping the NPM Shrinkwrap file with React Native when it's installed through `npm`. In both the npm2 and npm3 case, node_modules specified by RN's package.json are nested underneath `react-native` in node_modules, thus allowing us to specify, for example, that we want to use React Native's copy of `fbjs` (not any other copy that may be installed) as the module used by the packager to resolve any `requires` that reference a module in `fbjs`.
chirag04 added a commit to 4Catalyzer/react-native that referenced this pull request Feb 23, 2016
@davidaurelio
Copy link
Contributor

Good news. Almost everything is green now. This will be coming soon

@marcshilling
Copy link

So this didn't make it into 0.21?

@bestander
Copy link
Contributor

Yeah, that is a can of worms.
Still in progress

On Tuesday, 1 March 2016, Marc Shilling [email protected] wrote:

So this didn't make it into 0.21?


Reply to this email directly or view it on GitHub
#5084 (comment)
.

@chirag04
Copy link
Contributor

chirag04 commented Mar 1, 2016

Using this in our fork and makes working with relay flawless. hope it gets merged soon.

@davidaurelio
Copy link
Contributor

I’m through with all internal failures. CI is running right now, and I’m waiting for review. It’s coming.

@ghost ghost closed this in ad8a335 Mar 2, 2016
ghost pushed a commit to facebook/relay that referenced this pull request Mar 2, 2016
Summary:Follow-up to facebook/react-native#5084

This…
- changes all requires within RN to `require('fbjs/lib/…')`
- updates `.flowconfig`
- updates `packager/blacklist.js`
- adapts tests
- removes things from `Libraries/vendor/{core,emitter}` that are also in fbjs
- removes knowledge of `fbjs` from the packager

Closes facebook/react-native#5084

public

Reviewed By: bestander

Differential Revision: D2926835

fb-gh-sync-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
shipit-source-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
@ide
Copy link
Contributor

ide commented Mar 3, 2016

@skevy @davidaurelio you guys are heroes! thanks :D

(& fingers crossed we can land this in 0.22)

@Kureev
Copy link
Contributor

Kureev commented Mar 3, 2016

thanks, guys ❤️

@chirag04
Copy link
Contributor

chirag04 commented Mar 3, 2016

You guys are amazing. Thanks for all the work 👍

venepe pushed a commit to venepe/relay that referenced this pull request Mar 7, 2016
Summary:Follow-up to facebook/react-native#5084

This…
- changes all requires within RN to `require('fbjs/lib/…')`
- updates `.flowconfig`
- updates `packager/blacklist.js`
- adapts tests
- removes things from `Libraries/vendor/{core,emitter}` that are also in fbjs
- removes knowledge of `fbjs` from the packager

Closes facebook/react-native#5084

public

Reviewed By: bestander

Differential Revision: D2926835

fb-gh-sync-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
shipit-source-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
pglotov pushed a commit to pglotov/react-native that referenced this pull request Mar 15, 2016
Summary:
Turns out, even after discussion that was had in facebook#5294 (comment), we really do need this transform.

I've just included it in the preset...let me know if you all would rather publish to npm.

The actual reason why this is necessary is because in the latest sync from FB, fbjs was updated to use the `Symbol.iterator` express in it's isEmpty function: facebook/fbjs@064a484

We use this in RN in the ListView...and this change (once facebook#5084 is merged) will cause ListView to break on older JSC context's.

This resolves that, and is probably something we should have had all along.
Closes facebook#5824

Reviewed By: svcscm

Differential Revision: D2913315

Pulled By: vjeux

fb-gh-sync-id: abaf484a9431b3111e8118d01db8d2c0d2dd73ca
shipit-source-id: abaf484a9431b3111e8118d01db8d2c0d2dd73ca
pglotov pushed a commit to pglotov/react-native that referenced this pull request Mar 15, 2016
Summary:
As spicyj mentioned in commit 6a838a4, the ideal state of affairs when it comes to consuming `react` and `fbjs` from NPM is for the packager not to have knowledge of either package. This PR addresses the `fbjs` part of that, and relies on facebook/fbjs#95. **DO NOT MERGE** until facebook#95 (or a variation) is in `fbjs` and is released to npm.

This PR does several things:

1. Adds stub modules within RN that expose `fbjs` modules to be required using Haste. After discussing a few ideas with spicyj, this seemed like a good option to keep internal FB devs happy (and not make them change the way they write JS), but allow for removing packager complexity and fit in better with the NPM ecosystem. Note -- it skips stubbing `fetch`, `ExecutionEnvironment`, and `ErrorUtils`, due to the fact that these need to have Native specific implementations, and there's no reason for those implementations to exist in `fbjs`.
2. Removes the modules that were previously being used in lieu of their `fbjs` eq
Closes facebook#5084

Reviewed By: bestander

Differential Revision: D2803288

Pulled By: davidaurelio

fb-gh-sync-id: fd257958ee2f8696eebe9048c1e7628c168bf4a2
shipit-source-id: fd257958ee2f8696eebe9048c1e7628c168bf4a2
pglotov pushed a commit to pglotov/react-native that referenced this pull request Mar 15, 2016
Summary:
As spicyj mentioned in commit 6a838a4, the ideal state of affairs when it comes to consuming `react` and `fbjs` from NPM is for the packager not to have knowledge of either package. This PR addresses the `fbjs` part of that, and relies on facebook/fbjs#95. **DO NOT MERGE** until facebook#95 (or a variation) is in `fbjs` and is released to npm.

This PR does several things:

1. Adds stub modules within RN that expose `fbjs` modules to be required using Haste. After discussing a few ideas with spicyj, this seemed like a good option to keep internal FB devs happy (and not make them change the way they write JS), but allow for removing packager complexity and fit in better with the NPM ecosystem. Note -- it skips stubbing `fetch`, `ExecutionEnvironment`, and `ErrorUtils`, due to the fact that these need to have Native specific implementations, and there's no reason for those implementations to exist in `fbjs`.
2. Removes the modules that were previously being used in lieu of their `fbjs` eq
Closes facebook#5084

Reviewed By: bestander

Differential Revision: D2803288

Pulled By: javache

fb-gh-sync-id: 121ae811ce4cc30e6ea79246f85a1e4f65648ce1
shipit-source-id: 121ae811ce4cc30e6ea79246f85a1e4f65648ce1
pglotov pushed a commit to pglotov/react-native that referenced this pull request Mar 15, 2016
Summary:Follow-up to facebook#5084

This…
- changes all requires within RN to `require('fbjs/lib/…')`
- updates `.flowconfig`
- updates `packager/blacklist.js`
- adapts tests
- removes things from `Libraries/vendor/{core,emitter}` that are also in fbjs
- removes knowledge of `fbjs` from the packager

Closes facebook#5084

Reviewed By: bestander

Differential Revision: D2926835

fb-gh-sync-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
shipit-source-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
cpojer pushed a commit to facebook/metro that referenced this pull request Jan 26, 2017
Summary:
As spicyj mentioned in commit 6a838a4, the ideal state of affairs when it comes to consuming `react` and `fbjs` from NPM is for the packager not to have knowledge of either package. This PR addresses the `fbjs` part of that, and relies on facebook/fbjs#95. **DO NOT MERGE** until #95 (or a variation) is in `fbjs` and is released to npm.

This PR does several things:

1. Adds stub modules within RN that expose `fbjs` modules to be required using Haste. After discussing a few ideas with spicyj, this seemed like a good option to keep internal FB devs happy (and not make them change the way they write JS), but allow for removing packager complexity and fit in better with the NPM ecosystem. Note -- it skips stubbing `fetch`, `ExecutionEnvironment`, and `ErrorUtils`, due to the fact that these need to have Native specific implementations, and there's no reason for those implementations to exist in `fbjs`.
2. Removes the modules that were previously being used in lieu of their `fbjs` eq
Closes facebook/react-native#5084

Reviewed By: bestander

Differential Revision: D2803288

Pulled By: davidaurelio

fb-gh-sync-id: fd257958ee2f8696eebe9048c1e7628c168bf4a2
shipit-source-id: fd257958ee2f8696eebe9048c1e7628c168bf4a2
cpojer pushed a commit to facebook/metro that referenced this pull request Jan 26, 2017
Summary:
As spicyj mentioned in commit 6a838a4, the ideal state of affairs when it comes to consuming `react` and `fbjs` from NPM is for the packager not to have knowledge of either package. This PR addresses the `fbjs` part of that, and relies on facebook/fbjs#95. **DO NOT MERGE** until #95 (or a variation) is in `fbjs` and is released to npm.

This PR does several things:

1. Adds stub modules within RN that expose `fbjs` modules to be required using Haste. After discussing a few ideas with spicyj, this seemed like a good option to keep internal FB devs happy (and not make them change the way they write JS), but allow for removing packager complexity and fit in better with the NPM ecosystem. Note -- it skips stubbing `fetch`, `ExecutionEnvironment`, and `ErrorUtils`, due to the fact that these need to have Native specific implementations, and there's no reason for those implementations to exist in `fbjs`.
2. Removes the modules that were previously being used in lieu of their `fbjs` eq
Closes facebook/react-native#5084

Reviewed By: bestander

Differential Revision: D2803288

Pulled By: javache

fb-gh-sync-id: 121ae811ce4cc30e6ea79246f85a1e4f65648ce1
shipit-source-id: 121ae811ce4cc30e6ea79246f85a1e4f65648ce1
cpojer pushed a commit to facebook/metro that referenced this pull request Jan 26, 2017
Summary:Follow-up to facebook/react-native#5084

This…
- changes all requires within RN to `require('fbjs/lib/…')`
- updates `.flowconfig`
- updates `packager/blacklist.js`
- adapts tests
- removes things from `Libraries/vendor/{core,emitter}` that are also in fbjs
- removes knowledge of `fbjs` from the packager

Closes facebook/react-native#5084

Reviewed By: bestander

Differential Revision: D2926835

fb-gh-sync-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
shipit-source-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
bartolkaruza pushed a commit to bartolkaruza/react-native-cameraroll that referenced this pull request Feb 23, 2019
Summary:Follow-up to facebook/react-native#5084

This…
- changes all requires within RN to `require('fbjs/lib/…')`
- updates `.flowconfig`
- updates `packager/blacklist.js`
- adapts tests
- removes things from `Libraries/vendor/{core,emitter}` that are also in fbjs
- removes knowledge of `fbjs` from the packager

Closes facebook/react-native#5084

Reviewed By: bestander

Differential Revision: D2926835

fb-gh-sync-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
shipit-source-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
bartolkaruza pushed a commit to bartolkaruza/react-native-cameraroll that referenced this pull request Feb 24, 2019
Summary:Follow-up to facebook/react-native#5084

This…
- changes all requires within RN to `require('fbjs/lib/…')`
- updates `.flowconfig`
- updates `packager/blacklist.js`
- adapts tests
- removes things from `Libraries/vendor/{core,emitter}` that are also in fbjs
- removes knowledge of `fbjs` from the packager

Closes facebook/react-native#5084

Reviewed By: bestander

Differential Revision: D2926835

fb-gh-sync-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
shipit-source-id: 2095e22b2f38e032599d1f2601722b3560e8b6e9
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.