|
| 1 | +- Start Date: (fill me in with today's date, 2018-08-01) |
| 2 | +- RFC PR: (leave this empty) |
| 3 | +- Yarn Issue: (leave this empty) |
| 4 | + |
| 5 | +# Summary |
| 6 | + |
| 7 | +The command `yarn why` gives me the direct dependencies of a given package. |
| 8 | +It would be much more useful to show the dependency chains leading to this package. |
| 9 | + |
| 10 | +# Motivation |
| 11 | + |
| 12 | +Knowing which direct dependencies cause a given package to be installed is |
| 13 | +useful in several cases. |
| 14 | + |
| 15 | +## Really understand why a dependency got installed |
| 16 | + |
| 17 | +The current version of `yarn why` does not really tells why a dependency is installed, |
| 18 | +you will need to run it recursively. |
| 19 | +The current version of the command is scoped to the package name. When two versions |
| 20 | +of the same package are installed, I would like to understand why a given version is installed. |
| 21 | + |
| 22 | +## Update vulnerable package |
| 23 | + |
| 24 | +A vulnerability in a package I use has been discovered, I need to upgrade this |
| 25 | +dependency to a later version. However this dependency is not a direct dependency listed |
| 26 | +in my package.json files. I would like to know ALL the direct dependencies that I |
| 27 | +need to update/remove to get rid of this vulnerable package. |
| 28 | + |
| 29 | +## Dedup packages |
| 30 | + |
| 31 | +A given package is installed with two different versions. I would like to find out |
| 32 | +why and what packages I need to upgrade to remove this duplication. I would like |
| 33 | +to do this so I don't ship to customers two versions of the same code. |
| 34 | + |
| 35 | +# Detailed design |
| 36 | + |
| 37 | +The implementation would be quite simple. We traverse up the dependency chains |
| 38 | +leading to the required package. While doing so, we print the packages to screen. |
| 39 | +If the package is a direct dependency (declared in one of our package.json) then mention |
| 40 | +it. This should work with yarn workspaces (it is even more useful there). |
| 41 | +Note that a dependency can be both direct and indirect at the same time, the tool should make this visible. |
| 42 | +For each package, both the requested version (eg. ^1.2.3) and the resolved version (eg. 1.2.5) |
| 43 | +should be displayed. The same resolved version can match several requested versions |
| 44 | +(eg. ^1.2.3 and ^1.2.4 can both resolve to 1.2.5), this fact should be clear when displaying |
| 45 | +the dependency chain. |
| 46 | + |
| 47 | +## Example |
| 48 | + |
| 49 | +### Repo structure |
| 50 | + |
| 51 | + root |
| 52 | + package.json |
| 53 | + packages |
| 54 | + package1 |
| 55 | + package.json |
| 56 | + package2 |
| 57 | + package.json |
| 58 | + |
| 59 | +### command line |
| 60 | + |
| 61 | +`>>> yarn why pseudomap 1.0.2` |
| 62 | + |
| 63 | +### outpout |
| 64 | + |
| 65 | +``` |
| 66 | +pseudomap@^1.0.1 (1.0.2) |
| 67 | + lru-cache@^3.2.0 (3.2.0) |
| 68 | + editorconfig@^0.13.2 (0.13.3) |
| 69 | + js-beautify@^1.5.1 (1.7.4) - devDependency of package1 |
| 70 | +pseudomap@^1.0.2 (1.0.2) |
| 71 | + lru-cache@^4.0.1 (4.1.1) |
| 72 | + cross-spawn@^3.0.0 (3.0.1) |
| 73 | + node-sass@^4.5.3 (4.6.1) - dependency of package1 |
| 74 | + cross-spawn@^5.0.1 (5.1.0) |
| 75 | + execa@^0.7.0 (0.7.0) |
| 76 | + os-locale@^2.0.0 (2.1.0) |
| 77 | + |
| 78 | + [email protected] (3.1.4) - devDependency of package1 and package2 |
| 79 | + yargs@^10.0.3 (10.0.3) |
| 80 | + jest-cli@^22.4.2 (22.4.4) |
| 81 | + [email protected] (22.4.2) - dependency of package1 and devDependency of package2 |
| 82 | + jest-runtime@^22.4.4 (22.4.4) |
| 83 | + jest-cli@^22.4.2 (22.4.4) |
| 84 | + [email protected] (22.4.2) - dependency of package1 and devDependency of package2 |
| 85 | + jest-runner@^22.4.4 (22.4.4) |
| 86 | + jest-cli@^22.4.2 (22.4.4) |
| 87 | + [email protected] (22.4.2) - dependency of package1 and devDependency of package2 |
| 88 | + execa@^0.8.0 (0.8.0) - dependency of package2 |
| 89 | + lerna@^2.2.0 (2.5.1) - dependency of the main package.json |
| 90 | + lint-staged@^4.2.1 (4.3.0) - dependency of the main package.json |
| 91 | +``` |
| 92 | + |
| 93 | +# How We Teach This |
| 94 | + |
| 95 | +The command `yarn why` is already known and I believe this design fits better the |
| 96 | +expectations than the current implementation. |
| 97 | + |
| 98 | +The documentation will of course be updated but will not need a reorganization. |
| 99 | + |
| 100 | +If the `yarn why` command is used to teach yarn to new users, then the |
| 101 | +teaching materials will need to be updated. |
| 102 | + |
| 103 | +If this design solves some problems better than current tools and the current solution |
| 104 | +is documented, then the documentation of this problem solution will need to be updated |
| 105 | +to use the new command. |
| 106 | + |
| 107 | +Advanced users will benefit from being introduced to this feature. |
| 108 | + |
| 109 | +# Drawbacks |
| 110 | + |
| 111 | +Some people may have implemented some scripts on top of `yarn why`, these scripts |
| 112 | +will be broken. |
| 113 | + |
| 114 | +The command `yarn why` will become more verbose and it may confuse people that are |
| 115 | +used to the current command. |
| 116 | + |
| 117 | +The tool will need to use both `yarn.lock` and `package.json` files, it will be buggy if |
| 118 | +these are out of sync because of manual changes. |
| 119 | + |
| 120 | +# Alternatives |
| 121 | + |
| 122 | +This tool could be implemented as a separate package. |
| 123 | + |
| 124 | +An alternative is to run recursively `yarn why`. |
| 125 | + |
| 126 | +Every users write their own script for their specific problem. |
| 127 | + |
| 128 | +# Unresolved questions |
| 129 | + |
| 130 | +Do we show ALL the dependency chains leading to the desired package? Do we merge certain |
| 131 | +paths together when they share most of their packages? If so how will this look like? |
| 132 | + |
| 133 | +Should we have an option to skip devDependencies? |
| 134 | + |
| 135 | +What happens if someone manually changes package.json and run the `yarn why` command without |
| 136 | +running `yarn` first? |
| 137 | + |
| 138 | +How does this command works when ran before a merge conflict in yarn.lock is resolved? |
| 139 | + |
| 140 | +What is the source of truth? The `yarn.lock` and `package.json` files or the actually installed packages? |
| 141 | + |
| 142 | +How to treat circular dependencies? |
0 commit comments