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

Uncaught Invariant Violation: 4.3.1 -> 5.0.1 w/ monorepo use of shared components #6769

Closed
crobinson42 opened this issue Jun 7, 2019 · 7 comments

Comments

@crobinson42
Copy link

New bug when upgrading from 4.3.1 -> 5.0.1

Version

5.0.1

Steps to reproduce

Using a monorepo or npm link for local development with a shared components package that contains a component which imports react-router-dom and contains a NavLink the application breaks with Error: Invariant failed: You should not use <NavLink> outside a <Router>.

I've proved this by moving the shared components package into the node_modules of the project using the shared components and all works fine.

Expected Behavior

I should be able to npm link a local package that contains components that import their own react-router-dom to use NavLink without any issues.

Actual Behavior

Error: Invariant failed: You should not use <NavLink> outside a <Router>

Note: rolling back to 4.3.1 resolves this issue.

@timdorr
Copy link
Member

timdorr commented Jun 8, 2019

This is a symptom of what I want to solve with #6755.

Unfortunately, this isn't actually a bug with this library. You have two copies of react-router, one from the host project and one from the guest project. AFAIK, there isn't a way to resolve this when using a link. This is a "bug" of npm, essentially.

@timdorr timdorr closed this as completed Jun 8, 2019
@crobinson42
Copy link
Author

Isn’t this related to not having the same context due to importing from different packages?

@timdorr
Copy link
Member

timdorr commented Jun 8, 2019

Yes, the context pair has to be the exact same instance.

@Richacinas
Copy link

I solved this issue using a Webpack alias in your client App. That way, when your shared packages library imports anything from react-router-dom, it will get the same instance as your client App.

Like this:

const config = {
  ...
  ...
  resolve: {
    modules: ['src', 'node_modules'],
    extensions: ['.json', '.js', '.jsx'],
    alias: {
      'react-router-dom': path.join(PROJECT_ROOT_DIR_CONST, 'node_modules/react-router-dom/')
    },
  }
  ...

@SampsonCrowley
Copy link

SampsonCrowley commented Jul 15, 2019

You're basically saying no one can create a library that includes the Link component from react-router-dom without a lot of extra effort and aliases.

I thought 5.x was supposed to be fully 4.x compatible, and the only reason for the major version bump was so you could start pinning versions

@SampsonCrowley
Copy link

SampsonCrowley commented Jul 15, 2019

Webpack Externals is probably the correct answer here for library creators. I will report back with my results

webpack.config.js:

module.exports = {
  ...
  externals: {
    react: 'react',
    'react-dom': 'react-dom',
    'react-router-dom': 'react-router-dom',
    'react-router': 'react-router',
  },
  ...
}

@SampsonCrowley
Copy link

^ it worked. If you are publishing a library with rrd involved, make sure it is exported as an external in webpack

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants