7

Scenario

  • I am using npm 5.8.0
  • I am having a ProjectA and a ProjectB
  • ProjectB is a dependency of ProjectA
  • Both project are being bundled and run via Webpack (I can provide my configuration if necessary).

For development purposes I am referencing ProjectB in ProjectA's package.json via "projectB": "file:../projectB". Basically the only files I need there are in the lib folder which is Webpack's output.

Problem

If I install this dependecy with the configuration above, npm will install the entire ProjectB-folder into node_modules. It will contain everything projectB's node_modules, configuration files, the src-folder etc.

Apart from the fact that this can't be the expected behaviour, this leads to errors. For example some of the installed @types will throw an error because they are considered duplicates. @types and other packages from ProjectA and ProjectB seem to "collide". Those packages are referenced as "dependencies" in both ProjectA and ProjectB mostly.

What I tried

npm link

If I use npm link the same (see above) behaviour appears. The entire folder will be installed into ProjectA's node_modules.

npm pack

It might be important that I actually do have a .npmignore-file in ProjectB. So when I use npm pack a projectB.tgz file is generated. If I then install ProjectB via "projectB": "file:../projectB.tgz" everything works fine. I assume that npm pack does take the .npmignore-file into account.

My problem with this solution is that I not only would have to build ProjectB every time a change is applied to it but also npm pack it.

Delete ProjectB's node_modules

I guess this is the silliest workaround. If I reference ProjectB via "projectB": "file:../projectB" again but delete its node_modules after building it, they do not appear after installation. Thus I do not get any more exceptions.

I guess this is not a valid solution either as still the entire ProjectB-folder is being installed.

Question

What is the best practice here? What is a reasonable constallation for ProjectA and ProjectB in order to install ProjectB from a local source?

チーズパン
  • 2,752
  • 8
  • 42
  • 63

3 Answers3

2

If projectA requires files from projectB/lib, you could configure webpack's resolver as follows (assuming webpack 4):

resolve {
  alias: "projectB": "projectB/lib"
}

If projectB is a module, it's package.json should include the corresponding entrypoint (see this page).

I would also suggest you try yarn instead of npm for package management. Yarn's workspaces feature is designed for working with multiple interdependent packages.

tomc
  • 1,458
  • 1
  • 10
  • 16
0

Can you try putting the following code into the package.json file of projectB?

"files": [
    "lib/*"
]

This should tell any npm install to only use the files specified in the Array. You can obviously expand these with more entries. See the documentation for more details

Wouter Coebergh
  • 804
  • 1
  • 6
  • 20
0

You could alias projectB/lib in the webpack configuration for projectA. That will tell webpack to look in projectB's lib folder when resolving projectB modules.

Example webpack.config:

{
    resolve: {
        alias: {
            "projectB": path.resolve(__dirname, '../projectB/lib')
        }
    }
}

Also, if projectA is utility library that will be installed in another project, make projectB just a peerDependency of projectA. That way when projectA is installed, the user will get a warning if projectB is not installed or if an incorrect version is installed.

Example package.json:

{
    "peerDependencies": {
        "projectB": "1.0.0"
    }
}
Derek
  • 967
  • 1
  • 9
  • 16