Recently, I was thinking about how the packaging results differ from the node_modules dependency structure when a project depends on multiple versions of packages. Is there a way to override a lower version of a higher version? Overwriting can lead to program bugs.

To try out the multi-version dependency problem, I have written two packages to test and have put them on NPM. They are @flypkg/ main@ flypkg/suba

The warehouse address is github.com/simonwong/f…

Verify the train of thought

The idea is this

The suba package exposes a runSubA method that prints out its current version.

export function runSubA () {
  logMessage('subA', pkg.version, 'Execute in subA')}Copy the code

The main package relies on its own version of suba and exposes an init put to perform runSubA.

export function init () {
  logMessage('main', pkg.version, 'Execute in main')
  runSubA()
}
Copy the code

You then rely on different versions of @flypkg/main and @flypkg/suba in your project, and execute both init and runSubA methods

import { init } from '@flypkg/main'
import { runSubA } from '@flypkg/suba'

init()
runSubA()
Copy the code

Different versions of YARN and NPM may have different results. The test version is [email protected] [email protected]

try

First try

Our version of package.json looks like this. Note: the suba version here does not add ^

"Dependencies" : {" @ flypkg/main ":" ^ "hundreds," @ flypkg/suba ":" 0.0.1, "},Copy the code

Executing yarn List looks like this

├ ─ @ flypkg/[email protected] │ ├ ─ @ flypkg/suba @ ^ hundreds │ └ ─ @ flypkg/[email protected] ├ ─ @ flypkg/[email protected]Copy the code

The output is as follows

Looking at the webpack results, there are two runSubA methods, in their respective execution blocks, corresponding to versions 0.0.1 and 0.0.2.

Second attempt

Considering whether it is affected by the ^ sign, I add the ^ sign in front of the suba package. The addition of ^ enables you to install to the latest version of 0.x.x when installing.

However, the actual dependency tree and execution result are the same as above.

Third attempt

Modify package.json as follows

"Dependencies" : {" @ flypkg/main ":" ^ "hundreds," @ flypkg/suba ":" ^ 0.0.3 "},Copy the code

The yarn list result is as follows

├ ─ @ flypkg/[email protected] │ ├ ─ @ flypkg/suba @ ^ hundreds │ └ ─ @ flypkg/[email protected] ├ ─ @ flypkg/[email protected]Copy the code

The result is as follows

It is still a method of executing different dependent versions.

conclusion

Well, satisfied with the results. This avoids what I was worried about in the first place. We can continue to use the new dependencies in our projects with confidence. (≧ del ≦) /

Wait a minute. We’re missing something here.

Problem a

Due to various versions of the method, we ended up packing a lot more! Yeah, we just have to keep our eyes open to get bigger.

What are the optimizations?

Use the ES Module specification as much as possible and the package that supports tree shaking. In package.json, the package says “sideEffects”: false.

It tells Webpack that if there are methods in this package that are not being used, you can shake them out as much as you like. Avoid code redundancy.

Question 2

If there is a bug in [email protected]’s dependency on [email protected], how can we solve it?

Use Resolutions to forcibly lock the version. Yarn support, NPM requires the nPm-froce-resolution library to implement.

/ * package. Json * / {" resolutions ": {" @ flypkg/suba" : "hundreds"}}Copy the code

Read the node_modules dilemma