with lerna monorepo, how to reference different versions of a shared package? - versioning

New to lerna and monorepo, my understanding is with lerna, we put all shared packages and all consumer packages in a single repo. Then after 'lerna bootstrap', consumer1 and consumer2 will both have a local link to shared1 (symllink). So whenever I make changes in shared1, both consumer1 and consumer2 are affected.
Is there a way to make consumer1 and consumer2 point to different versions of shared1? so that when I make changes in shared1, only consumer1 is affected and consumer2 is not.

One of the big benefits of using lerna is the fact that your code within the monorepo is always building and testing with the latest versions of their child dependencies. If your consumers need to use different versions of shared code, then those consumers probably do not belong within this monorepo and should be installing the shared code independently. Here is a closed github thread covering this also.

Related

several instances of `#material-ui/styles` initialized in this application

We're using Material UI in our project, but there're many components that's shared between a few projects, se I'm creating a React components library to share them.
But when I import the component from library, I got the warning about #material-ui/styles:
It looks like there are several instances of `#material-ui/styles` initialized in this application.
This may cause theme propagation issues, broken class names, specificity issues, and makes your application bigger without a good reason.
I've checked by npm ls #material-ui/styles that there're only a single version.
But this problem is still happening even I added #material-ui/core, #material-ui/styles to the peerDependencies.
How can I fix this?
From the Materal UI docs:
Possible reasons
There are several common reasons for this to happen:
You have another #material-ui/styles library somewhere in your dependencies.
You have a monorepo structure for your project (e.g, lerna, yarn workspaces) and #material-ui/styles module is a dependency in more than one package (this one is more or less the same as the previous one).
You have several applications that are using #material-ui/styles running on the same page (e.g., several entry points in webpack are loaded on the same page).
As said by #Code-Apprentice one or more libraries are using #material-ui/styles (I bet it's react bootstrap). It doesn't really seem to be harmful but one way of fixing it is removing dependencies that use the #material-ui/styles.

How to share node modules folder between different react applications

I have a few react applications, for each application, I am installing dependencies which I mentioned in package.json(node_modules) and for all applications, these dependencies are the same.
If in this case, why do I maintain the same duplicate files in multiple places, and also it is a waste of memory.
Is there any way to install all my package.json dependencies at one location and to share it between the components?
I think it is reasonable to keep duplicating different package.json files for different applications.
However I think it is possible to create an npm package that would include all your dependencies and then make your project just to use this one npm package.

ReactJs Library that installs globally

I'm wanting to create a React library that I can build locally and that deploys into the NPM global area. I want to be able to use my other React project that also sits on my machine and picks up changes as I modify the library. I have found plenty of tutorials that either deploy to NPM (which I don't want) or that I have no idea how to get it updating automatically to my project. I tried one with rollup.js that seemed to work for a while but then stopped for some reason.
Ideally looking for tutorial or source code that I can look at.
Do's: build locally, automatically update changes to my project
Don'ts: deploy to NPM or another external repository, cause problems when setup on another machine
Want: One library, one project, easy update to the project when the library is changed, be able to create an entry in the global install with the library version
Thanks
Paul

Reusing react components across projects

I want to split my web project into three: front-end, back-end and super-admin.
What is the best way to re-use the components across code bases? Npm packages? That seems hard to maintain:
Open component dev package
Make changes
Push changes
Tag version
Update all projects
Seems complex and prone to errors. Is there a better way?
Depends on if you need to use different versions of the shared components from different projects. If so, you probably need to make a versioned npm package. However, if you just want to share the packages and use the same version everywhere, you have other options. For one, you don't have to actually build and publish an npm packge, you can just use npm link. This will basically create a symlink to your shared code in node_modules of the other projects.
Alternatively, you can do it without any npm package at all, just have the shared components in a separate project (directory) and import them in javascript through an alias, using a bundling system (webpack alias / browserify aliasify).

how to manage a big React/Redux project with many independent widgets

I want to have a project structure like that:
./app/package.json
./app/src/index.js
./widget1/package.json
./widget1/src/index.js
./widget2/package.json
./widget2/src/index.js
./widget3/package.json
./widget3/src/index.js
As you can guess, this project is like an aggregation of NPM widget subprojects, and the app src folder is the real app, that uses the different widget subprojects.
I want a clear and strict separation between the widgets because my current experience shows me that developers tend to introduce unwanted cyclic dependencies between widgets even if I tell them not too.
In practice, all these widgets will be ReactJS widgets that have for most of them 3 common JS libs: React, JQuery and Lodash. Some will not need these 3 libs, some will need an additional lib like packery, react-slick or react-date-picker All these widgets should also share common test libraries like mocha.
They absolutly need to share the exact same common library versions (because obviously I don't want different versions of React in my project nor to increase my bundle size).
For example,
- widget1 could be a DatePicker widget, that depends on React + Lodash + react-date-picker (npm lib, not mine)
- The app project could depend on React + Redux + Normalizr + all the widgets and their transitive dependencies like react-date-picker
All the widgets will be Presentational components and do not need much more fancy dependencies. Some will only depend on React. Some may have a Redux reducer but as it is plain old JS code, there's no dependency needed.
The number of widgets can be quite big and I don't want to edit 200 package.json files on each library update (however I could eventually use some code to handle that).
When inside widget1/src, it should be forbidden to require code from widget2. If a widget had to be able to depend on another widget, this dependency must be set explicitly in package.json of the client widget.
I should be able to build with Webpack and test all the widgets independently. I should also be able to build and test at once the whole project, including all the subprojects, and having a single aggregated global test and code coverage report.
I don't want it to have a bad developer experience. React and Webpack permits to have Hot code reloading. If I have the real app in my browser and I modify code of a widget, I should be able to see the change live with react-hot-loader and not have to run npm commands nor hit F5.
What I look for is the equivalent of Java Maven's dependencyManagement system where you usually set versions for all your subprojects in parent POM, and versions are somehow inherited to all child projects. All child projects cannot see each others (unless explicit dependency is added), but they can say they depend on a library declared in parent project. All the lib version numbers can be set in the parent project.
Is it possible to do so with NPM and Webpack?
Or at least something close to it?
Thanks
You could put each widget in it's own git repo and install them with NPM via the repo URL. As long as each widget defines the libraries they use in their own NPM package, when they're used in the main project NPM will handle all of the dependencies for you.
Depending on the size of your team you could also sign up for NPM's private packages and host them there https://www.npmjs.com/npm/private-packages
You might want to try https://github.com/n8tz/layer-pack,
as it meets many of the needs mentioned
It allows to:
inherit several npm packages in 1 source tree
manage module inheritance ( drive node & webpack to resolve them well )
put all Webpack conf & profiles in a shared, inheritable and versioned package
etc...
Note that hot reloading with too many inherited packages can be slow.
Alternative is to use precompiled versions of your widgets & externalize theirs deps.

Resources