Sebastien Lorber
Sebastien Lorber

Reputation: 92140

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

Upvotes: 4

Views: 984

Answers (2)

Nathan Braun
Nathan Braun

Reputation: 46

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.

Upvotes: 0

jolyonruss
jolyonruss

Reputation: 1840

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

Upvotes: 1

Related Questions