Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly configure NPM package which depends on local packages

I have this three local npm packages: C:\projects\A, C:\projects\B and C:\projects\main. Main is React app which is built with Webpack. Main depends on A and B, also A depends on B. We have our own "global" package manager which guarantees that packages will be located in same parent folder.

I want to suit these:

  1. Node's (and webpack's) require will resolve local packages

  2. I don't need to npm install in Main every time I change A or B

I did this in Main's package.json:

....
"dependencies": {
    "A": "file:../A",
    "B": "file:../B",
    "react": ...
    .........

But ran into strange problem: npm doesn't install all packages in A's and B's node_modules, so Webpack build fails. And I need to run npm install each time.

I googled and found linklocal, which replaces all local packages as symlinks. But ran into another problem:

linklocal does not install dependencies of linked dependencies, as such you typically end up installing dependencies of linked dependencies twice: once during npm install, then again after linklocal

So I ran linklocal and then npm install again in postinstall script. But npm@3 didn't do anything with symlinked folders:

npm WARN update-linked node_modules/A needs updating to 1.0.0 from 1.0.0 but we can't, as it's a symlink

Then I decided to modify postinstall to go to every symlinked module and run npm install from there. And it worked at first sight: installing ran well, as well as webpack bunding. But Webpack started bundling two copies of React (which is prohibited).

How to configure my packages properly?

like image 418
michaeluskov Avatar asked Oct 20 '16 18:10

michaeluskov


2 Answers

In package A and package B you can have a preinstall script that execute webpack. This should resolve all the dependencies.
On your main package you should link to the dist(build) folder of package A and B.
Also check this library wml, it can help you to keep in sync your local dependencies.

package.json:

"scripts": { "preinstall": "webpack" }

like image 161
Hosar Avatar answered Oct 31 '22 23:10

Hosar


If you do not need to build Main in other machines you could just do something like that in your project/Main

let C = require('C:\projects\A\index.js')

Or you could have a branch with

require('C:\projects\A\index.js')

And another with:

require('C')
like image 31
Fi3 Avatar answered Oct 31 '22 23:10

Fi3