3

I am developing in two repos, one a dependency of the other. I am on npm v5. I specify the dependency in package.json of main-repo as ../dependent-repo. When I do npm install, this creates a symlink for dependent-repo in main-repo/node_modules, pointing to ../../dependent-repo.

The problem is that dependent-repo has its own node_modules underneath it, so when I refer to (require or import) something in one of its dependencies, the default resolution procedure resolves to the dependency in dependent-repo/node_modules, rather than the dependency in main-repo/node_modules.

This turns out to be a problem with TypeScript, since apparently it believes that main-repo/node_modules/@angular/core is distinct from dependent-repo/node_modules/@angular/core, even if they are the same version, and byte-for-byte identical. This gives rise to TS errors of the form

Argument of type 'ViewContainerRef' is not assignable to parameter of type 'ViewContainerRef'.

I am familiar with this problem because it also occurred with npm v3 when I used npm link. That problem has been discussed extensively on the TS issues list, but with no resolution as far as I can tell. I was hoping that npm v5 would somehow magically solve this issue, but no luck so far.

I tried specifying the dependency as file://../dependent-repo, but this also merely creates the same symlink (as least in npm5; I seem to recall that in earlier versions if may have copied the directory lock, stock and barrel).

At the moment the only workaround I can see is leaving the dependency to point to the github server, then committing and pushing every single change I make, and re-running npm install on the main repo to bring in the latest changes. This was exactly what I was trying to avoid.

I thought of temporarily renaming dependent-repo/node_modules before testing main-repo, so it is omitted from the resolution process. However, this obviously requires all dependencies of dependent-repo to be present on main-repo.

I tried playing a bit with the paths option to tsconfig.json (in main-repo), and had some luck with things like paths: {"*": ["node_modules"]}, but couldn't get this to work completely.

I understand that angular-cli may have made some changes to its internal webpack configuration to make this work better, but unfortunately my main-repo uses an older webpack build process, and I could not make some of the suggested changes such as resolve: {fallback: [path.join(__dirname, 'node_modules')]} or resolve: { modules: [ path.join(__dirname, "node_modules") ] } work for me.

  • 1
    I know you were trying to avoid the Git-based dependency style, but it is the safest way to handle NodeJS sub dependencies, specially if your project grows and uses stuff as containers and CI. I would start by doing some automation using git-hooks and NPM scripts. – Luís Brito Jul 09 '17 at 02:04

1 Answers1

0

You can add a new remote to git in the dependent repo, but the new "remote" will be somewhere on your local box. This way, you can do git push <remote-name> <branch> and point the repo url in your main repo to pull from your remote. [git how to add a local repo and treat it as a remote one it's a hacky solution but should alleviate some pain when used with a couple of makefiles.

Hrishi
  • 7,110
  • 5
  • 27
  • 26