I have an NPM react module that at its entry point instantiates the StyleRoot. I wanted to use this module in another project that uses Radium, but the two conflict with one another. In the project that uses my module, if I try to create a StyleRoot it breaks the context of the modules elements. Is there a way we can add a key to the StyleRoot to have the entities work alongside or is there a different solution.
Failed Context Types: Invalid context `_radiumStyleKeeper` of type `StyleKeeper` supplied to `ThemeProvider`, expected instance of `StyleKeeper`.
The project in question is located here.
I got the same issue when using a small component-library I built using Radium and using that library in another project. I did not have multiple StyleRoots but instead only one StyleRoot in my other project and no StyleRoots in the component-library (since it only exported components).
The solution that seemed to work for me was to add Radium as a peerDependency in my component-library instead of a normal dependency.
@Aktof the issue is that you have 2 different versions of Radium in your frontend bundle. So the React.PropTypes.instanceOf(Radium.StyleKeeper) check doesn't work because you have Radium1.StyleKeeper and Radium2.StyleKeeper which are at different locations in memory
If you do as @Cottin says and make Radium a peerDependency of react-mux, then anything that depends on react-mux will have to explicitly list Radium as a dependency. Once you've done this, you'll only have 1 Radium in memory and the warnings will disappear.
I've run into a similar problem:
I have 2 repos - one is a web app and one is a component library. The component library uses Radium and exports a bundled (webpack+babel) file. The web app also uses Radium, so when I go to render one of the components from my component library from within my webapp I get the same error:
Failed Context Types: Invalid context `_radiumStyleKeeper` of type `StyleKeeper` supplied to `MyComponent`, expected instance of `StyleKeeper`. Check the render method of `FooBar`.
I imagine peerDependencies doesn't solve this problem since I'm bundling the component library beforehand and will have a different instance of Radium. Any thoughts?
@amavisca why would you ever want to ship two copies of Radium down to the end user? It would be very wasteful, so I'm not sure why we'd want to encourage that by making StyleRoot duck-typed.
@ianobermiller I don't want to be shipping two copies down to the end user. Looks like I can take advantage of webpack externals to solve my issue. Thanks.
I've running into the same exact issue, as I've been building a component library and when importing those components within another project (using Radium, etc.), I get the error:
warning.js:44Warning: Failed Context Types: Invalid context `_radiumStyleKeeper` of type `StyleKeeper` supplied to `t`, expected instance of `e`.
@FarhadG : https://github.com/FormidableLabs/radium/issues/575#issuecomment-184462379
Thanks for the response, @tptee. I already tried making radium a peer dependency inside of the component library's package.json as follows:
"peerDependencies": {
"radium": "0.17.1"
},
and when I continue with the approach of importing this component into another project, I get the same error. I removed the the Styleroot from these module components and having that instantiated within the projects that use these modules and still no luck... any thoughts?
Thanks for the response, @tptee, however, I continue to get the same warning:
warning.js:36Warning: Failed context type: Invalid context `_radiumStyleKeeper` of type `StyleKeeper` supplied to `Component`
I have a sample-ui-library that uses radium and here's a sample package.json:
"dependencies": {
"radium": "0.18.1",
"react": "~15.2.1",
"react-dom": "^15.3.1",
},
"peerDependencies": {
"radium": "0.18.1"
},
and my main project in a separate repo with the following sample package.json:
"dependencies": {
"sample-ui-library": "0.5",
"radium": "0.18.1"
},
Still getting the same warning, unless I'm missing something. Thanks in advance for your suggestions.
I'll join the choir here. Same problem
I second this!
The same problem pops up in our project which have a common npm linked component library which only specifies radium as a peer dependency. The main project specifies radium as a dependency and both projects contains the exact same version of radium (0.18.1).
I third this!
Also, using Radium 0.18.1, listed as a peerDependency in our UI library, and get the same error message when importing into a project:
Warning: Failed context type: Invalid undefined `_radiumStyleKeeper` of type `StyleKeeper` supplied to `PaginationWidget`, expected instance of `StyleKeeper`.
Fixed! Upon further inspection, I found that listing Radium as a peerDependency wasn't enough. Because I had Radium installed in my library project, for development purposes, even though it was only listed as a peerDependency, webpack was still bundling it, thus I still had two copies of Radium in projects that imported it (see earlier comments in the thread about that). If I removed Radium from my project's node_modules before building it, I got errors. I found this also to be true with React.
The fix: In addition to listing Radium and React as peerDependencies in package.json, I also had to list them both as externals in my webpack config: https://webpack.github.io/docs/library-and-externals.html
@seantcoyote Could you give an example of how to set that up please?
All the documentation I can find on Webpack externals is about injecting external globals into the webpack module loader cache
@Munter From https://webpack.github.io/docs/library-and-externals.html:
"externals allows you to specify dependencies for your library that are not resolved by webpack, but become dependencies of the output. This means they are imported from the environment during runtime."
So, if you do something like this in your library's Webpack config:
output: {
path: path.resolve(__dirname, 'lib'),
publicPath: '/',
filename: 'index.js',
library: "my-UI-library",
libraryTarget: "umd"
},
externals: {
'react': 'react',
'react-dom': 'react-dom',
'radium': 'radium'
},
Then, Webpack won't bundle react, react-dom or radium in you library build. Instead they become dependencies for whatever project consumes your library. Then you don't end up with multiple copies of react, react-dom or radium in your end product, and thus none of the ugly Failed context type errors.
@seantcoyote Ah. I don't do a webpack build of my library at all. I only babel transform the source files into browser compatible versions and consume those on my app. So externals only makes sense in a webpack build in the library itself?
Ok, I figured out how to fix this problem.
This bug happens because multiple instances of Radium get included in the webpack build, one from the parent and one from the library. Radium has a proptype check that compares instances instead of properties, which means that the proptype check fails when Radium instance 1 checks props for components that use Radium instance 2.
I solved it by adding new configuration on the parent projects webpack config:
resolve: {
alias: {
radium: path.join(__dirname, 'node_modules', 'radium')
}
}
The above configuration forces webpack to resolve any reference to the Radium module to the same instance, thus solving the instance comparison problem, but also reducing the bundle size, since you only ever need Radium in there once anyway.
I'm closing PR (#845), since I found a bug in it, and the manual deduplication configuration is preferable over bundling multiple Radium copies.
@Kikketer -- You're not actually wanting to use multiple style roots right? Assuming that, can you put up a minimal repository (or repositories) with install + error reproduction steps to expose the issue?
If the issue is just making sure your build selects a single radium in webpack, I'm pretty confident that's doable.
@ryan-roemer Thanks, it'll take me a few to get that setup. Right now we are building out the product which doesn't leave much time for such extra things. I'll post here again (hopefully soon) with a repeatable setup and if it works then we have something that can be shown as an example library.
@ryan-roemer
Most helpful comment
Ok, I figured out how to fix this problem.
This bug happens because multiple instances of Radium get included in the webpack build, one from the parent and one from the library. Radium has a proptype check that compares instances instead of properties, which means that the proptype check fails when Radium instance 1 checks props for components that use Radium instance 2.
I solved it by adding new configuration on the parent projects webpack config:
The above configuration forces webpack to resolve any reference to the Radium module to the same instance, thus solving the instance comparison problem, but also reducing the bundle size, since you only ever need Radium in there once anyway.
I'm closing PR (#845), since I found a bug in it, and the manual deduplication configuration is preferable over bundling multiple Radium copies.