Correctly configure NPM package, which depends on local packages

I have three local npm packages: C:\projects\A , C:\projects\B and C:\projects\main . Main is a React application built with Webpack. Main depends on A and B , also A depends on B We have our own β€œglobal” package manager, which ensures that packages are located in the same parent folder.

I want to take this into account:

  • Node (and webpack's) require allow local packages

  • I don't need npm install in Main every time A or B changes

I did this in Main package.json :

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

But I ran into an incomprehensible problem: npm does not install all packages in A and B node_modules, so Webpack build fails. And I need to run npm install every time.

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

linklocal does not set dependency dependencies, so you usually set dependency dependencies twice: once during npm installation, then again after linklocal

So, I ran linklocal and then npm install again in the postinstall script. But npm @ 3 did nothing with symbolic folders:

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

Then I decided to change postinstall to go to each symbolically connected module and run npm install from there. And it worked at first glance: the installation went well, and also bundled with webpack. But Webpack started linking two copies of React (which is forbidden).

How to configure my packages?

+6
source share
4 answers

In package A and package B, you can create preinstall scripts that execute webpack . This should eliminate all dependencies.
In the main package, you must refer to the dist folder (assembly) of packages A and B.
Also check out this wml library, this will help you synchronize your local dependencies.

package.json:

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

+1
source

If you don’t need to create Main on other machines, you can just do something similar in your project / Main

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

Or you may have a branch with

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

And one more:

 require('C') 
+1
source

You can use npm link locally to support symbolic links in local versions of development.

So, reset package.json in Main to indicate where published packages will actually be published:

  "dependencies": { "A": "<PUBLISHED_PACKAGE_REPO>", "B": "<PUBLISHED_PACKAGE_LOCATION>", "react": ... 

This ensures that your project will always be based on CI / other machines, etc.

Then go to the "Project A" directory and create a link:

 cd projects\A npm link 

This will create a special npm symbolic link that points to C:\projects\A

Then do the same for project B:

 cd projects\B npm link 

Now you have both project links, and you just need to link them to your Main project:

 cd projects\Main npm link A npm link B 

If A also depends on B , you just need to link these projects:

 cd projects\A npm link B 

When you finish development and want to use everything that is specified in package.json , just disconnect and install:

 cd projects\Main npm unlink A npm unlink B npm install 
0
source

I personally use npm pack to pack my dependencies and then install them in my main project using `npm install./path/to/pack/result.tgz as detailed here

It avoids posting all changes made to A and B, but does not bother you

npm install in Main every time I change A or B

0
source

Source: https://habr.com/ru/post/1011524/


All Articles