An alternative to the Yarn link and NPM link workflows, this tool packs a local NPM project and puts the packed contents into the given destination directories.
MIT License
19
stars
4
forks
source link
Should `useGlobalCache` be set to true by default? #11
Should we set useGlobalCache to true by default instead of setting destinations to ./local_modules?
The Problem
Today useGlobalCache is set to false by default and the destinations option is set to the relative working directory path ./local_modules. See the documentation describing this here. This works well for single level local dependencies but when multi-level local dependencies become involved, yarn/npm treat different path locations as different versions. So if someone spends the time to setup a multi local dependent situation where they want all levels to resolve to the same local version of a dependent package, they will see multiple of that dependency.
For example, given a classic diamond dependency
projectA depends on projectB and projectC
projectB depends on projectD
projectC depends on projectD
If someone wanted to setup a projectD to be locally developed they might do the following
In projectB run npm-pack-here --target <path-to-projectD> and the follow up yarn/npm commands
a. In projectB run yarn add file:local_modules/<name-of-projectD>
b. In projectB run yarn install --check-files
In projectC run npm-pack-here --target <path-to-projectD> and the follow up yarn/npm commands
a. In projectC run yarn add file:local_modules/<name-of-projectD>
b. In projectC run yarn install --check-files
In projectA run npm-pack-here --target <path-to-projectB> <path-to-projectC> and the follow up yarn/npm commands
a. In projectA run yarn add file:local_modules/<name-of-projectB> file:local_modules/<name-of-projectC>
b. In projectA run yarn install --check-files
At this point the expectation would be that locally in projectA both projectB and projectC depend on the same version of projectD but in reality they do not.
Instead they depend on two different versions of projectD,
One located in projectB, <path-to-projectB>/local_modules/<name-of-projectD>
One located in projectC, <path-to-projectC>/local_modules/<name-of-projectD>
The developer would have to know that they need to pass in the --useGlobalCache flag to all of the npm-pack-here commands to make this work.
Solution Idea
Make useGlobalCache the default (instead of destinations equal to [./local_modules]). Then npm-pack-here will always pack to the global cache location, which will make all multi-level dependency scenarios like the one described above just work.
For the most part this should also have little impact on existing single level dependency scenarios, as when people run npm-pack-here for the first time within some project it lists out the next step yarn commands with the path (which will now just be the global cache location).
Drawbacks to this approach are that changing the default would be a breaking change. This will in some ways make npm-pack-here much more tuned for use with yarn / npm projects. Kind of diverging from the idea that "there is some target/source", "there is a given destination", all npm-pack-here does is pack the content form the target to the destination. I wonder if we should split out the commands to make this more obvious.
Also another potential drawback, the global cache currently does not support multiple versions of a packed project within it. Its unknown currently if their are scenarios where people will desire having two (or more) versions of a local dependency all being packed and used within another set of projects. If they do, then defaulting to the global cache will introduce new issues. Will need to re-think how the global cache works for cases like that.
Alternative Ideas
In the multi-level local diamond dependency scenario described above, likely yarn resolutions (not sure if their is a npm equivalent) could be used to force resolution of the sub dependencies all to the same local version. This approach has the advantage (or possible disadvantage) that it could be likely setup from just the top level dependency (without having to locally clone all the intermediate dependencies). Either way probably want to document this approach as well.
Could also split out the existing cli command into two "pack content from this target/source location to this destination" from "pack content into this node project (with dependencies)." First command would still default to ./local_modules while the second would default to the global cache.
This could be a good idea as it might provide clarity to how npm-pack-here works for different workflows.
A third idea, instead of useGlobalCache we could pack into a sub folder of the target/source project. This might be even better to packing into the global cache as it would likely avoid the drawbacks listed above (could support multiple versions of a given local project, not diverging to far from the "source" to "destination" idea). Biggest issue of doing this is that this projects name kind of becomes a little misleading.
Example
Given the diamond dependency described above
projectA depends on projectB and projectC
projectB depends on projectD
projectC depends on projectD
If someone wanted to setup a projectD to be locally developed they would do the following
In projectB run npm-pack-here --target <path-to-projectD> and the follow up yarn/npm commands
a. In projectB run yarn add file:<path-to-npm-pack-here-global-cache>/<name-of-projectD>
b. In projectB run yarn install --check-files
In projectC run npm-pack-here --target <path-to-projectD> and the follow up yarn/npm commands
a. In projectC run yarn add file:<path-to-npm-pack-here-global-cache>/<name-of-projectD>
b. In projectC run yarn install --check-files
In projectA run npm-pack-here --target <path-to-projectB> <path-to-projectC> and the follow up yarn/npm commands
a. In projectA run yarn add file:<path-to-npm-pack-here-global-cache>/<name-of-projectB> file:<path-to-npm-pack-here-global-cache>/<name-of-projectC>
b. In projectA run yarn install --check-files
This will result in just a single version of projectD, the one in the global cache.
Feature Request Overview
Should we set
useGlobalCache
to true by default instead of settingdestinations
to./local_modules
?The Problem
Today
useGlobalCache
is set to false by default and thedestinations
option is set to the relative working directory path./local_modules
. See the documentation describing this here. This works well for single level local dependencies but when multi-level local dependencies become involved, yarn/npm treat different path locations as different versions. So if someone spends the time to setup a multi local dependent situation where they want all levels to resolve to the same local version of a dependent package, they will see multiple of that dependency.For example, given a classic diamond dependency
projectA
depends onprojectB
andprojectC
projectB
depends onprojectD
projectC
depends onprojectD
If someone wanted to setup a
projectD
to be locally developed they might do the followingprojectB
runnpm-pack-here --target <path-to-projectD>
and the follow up yarn/npm commands a. InprojectB
runyarn add file:local_modules/<name-of-projectD>
b. InprojectB
runyarn install --check-files
projectC
runnpm-pack-here --target <path-to-projectD>
and the follow up yarn/npm commands a. InprojectC
runyarn add file:local_modules/<name-of-projectD>
b. InprojectC
runyarn install --check-files
projectA
runnpm-pack-here --target <path-to-projectB> <path-to-projectC>
and the follow up yarn/npm commands a. InprojectA
runyarn add file:local_modules/<name-of-projectB> file:local_modules/<name-of-projectC>
b. InprojectA
runyarn install --check-files
At this point the expectation would be that locally in
projectA
bothprojectB
andprojectC
depend on the same version ofprojectD
but in reality they do not.Instead they depend on two different versions of
projectD
,projectB
,<path-to-projectB>/local_modules/<name-of-projectD>
projectC
,<path-to-projectC>/local_modules/<name-of-projectD>
The developer would have to know that they need to pass in the
--useGlobalCache
flag to all of thenpm-pack-here
commands to make this work.Solution Idea
Make
useGlobalCache
the default (instead ofdestinations
equal to[./local_modules]
). Then npm-pack-here will always pack to the global cache location, which will make all multi-level dependency scenarios like the one described above just work.For the most part this should also have little impact on existing single level dependency scenarios, as when people run
npm-pack-here
for the first time within some project it lists out the next step yarn commands with the path (which will now just be the global cache location).Drawbacks to this approach are that changing the default would be a breaking change. This will in some ways make
npm-pack-here
much more tuned for use with yarn / npm projects. Kind of diverging from the idea that "there is some target/source", "there is a given destination", all npm-pack-here does is pack the content form the target to the destination. I wonder if we should split out the commands to make this more obvious.Also another potential drawback, the global cache currently does not support multiple versions of a packed project within it. Its unknown currently if their are scenarios where people will desire having two (or more) versions of a local dependency all being packed and used within another set of projects. If they do, then defaulting to the global cache will introduce new issues. Will need to re-think how the global cache works for cases like that.
Alternative Ideas
In the multi-level local diamond dependency scenario described above, likely yarn resolutions (not sure if their is a npm equivalent) could be used to force resolution of the sub dependencies all to the same local version. This approach has the advantage (or possible disadvantage) that it could be likely setup from just the top level dependency (without having to locally clone all the intermediate dependencies). Either way probably want to document this approach as well.
Could also split out the existing cli command into two "pack content from this target/source location to this destination" from "pack content into this node project (with dependencies)." First command would still default to
./local_modules
while the second would default to the global cache. This could be a good idea as it might provide clarity to how npm-pack-here works for different workflows.A third idea, instead of
useGlobalCache
we could pack into a sub folder of the target/source project. This might be even better to packing into the global cache as it would likely avoid the drawbacks listed above (could support multiple versions of a given local project, not diverging to far from the "source" to "destination" idea). Biggest issue of doing this is that this projects name kind of becomes a little misleading.Example
Given the diamond dependency described above
projectA
depends onprojectB
andprojectC
projectB
depends onprojectD
projectC
depends onprojectD
If someone wanted to setup a
projectD
to be locally developed they would do the followingprojectB
runnpm-pack-here --target <path-to-projectD>
and the follow up yarn/npm commands a. InprojectB
runyarn add file:<path-to-npm-pack-here-global-cache>/<name-of-projectD>
b. InprojectB
runyarn install --check-files
projectC
runnpm-pack-here --target <path-to-projectD>
and the follow up yarn/npm commands a. InprojectC
runyarn add file:<path-to-npm-pack-here-global-cache>/<name-of-projectD>
b. InprojectC
runyarn install --check-files
projectA
runnpm-pack-here --target <path-to-projectB> <path-to-projectC>
and the follow up yarn/npm commands a. InprojectA
runyarn add file:<path-to-npm-pack-here-global-cache>/<name-of-projectB> file:<path-to-npm-pack-here-global-cache>/<name-of-projectC>
b. InprojectA
runyarn install --check-files
This will result in just a single version of
projectD
, the one in the global cache.Teachability, Documentation, Adoption, Migration Strategy
Would need to update documentation on the default options here.