iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🔏

How to list package versions from yarn.lock

に公開

Introduction

Have you ever wanted to list the exact versions of the packages used in your project(?)
Since I had such a situation, I'm writing this article as a memorandum.

It's easy to assume that the versions listed in package.json are the actual package versions, but the versions in package.json only indicate a range and differ from the versions actually being used.
The exact versions are recorded in yarn.lock or package-lock.json, so you need to refer to those. However, dependencies are also listed, making it difficult to check each one individually.
I found that I could list them relatively easily using license-checker-rseidelsohn, which is a tool for checking package licenses.

Results First

Install license-checker-rseidelsohn
(I'm adding it globally here, but for Yarn 2+, I'd prefer using dlx.)

yarn global add license-checker-rseidelsohn

Install jq if it's not already installed.

brew install jq

Run the command.

yarn license-checker-rseidelsohn --production --direct 0 --json | awk '/^{/,/^}/' | jq 'keys'

Output result.

[
  "-@0.0.1",
  "D@1.0.0",
  "O@0.0.9",
  "exact@0.8.0",
  "g@2.0.1",
  "i@0.3.7",
  "optional@0.1.4",
  "tag@0.4.17",
  "tilde@0.1.1",
  "version@0.1.2",
  "zenn-cli@0.1.150"
]

What's Happening Inside the Command

The options are described in the license-checker-rseidelsohn README, but I'll briefly explain them here.

--production

--production is an option that excludes packages listed in devDependencies.
If you don't specify --production, packages in devDependencies will also be included in the list.
Conversely, if you want packages listed in devDependencies, specify --development.

--direct 0

The --direct [boolean|number] option specifies the depth of dependencies to include.

The README states that specifying --direct true outputs direct dependencies, but be careful because using this option actually includes sub-dependencies in the output.
Therefore, I'm using --direct 0 here to output only packages at depth 0 (essentially direct dependencies).

--json

As the name suggests, this is an option to output in JSON format.

awk '/^{/,/^}/'

I use the awk command with a regular expression to extract the part from { to } in the JSON output.
If your yarn configuration is set to output logs like yarn run, extra logs will be output as shown below. This is used to exclude them.

yarn run v1.22.19
$ {path}/node_modules/.bin/license-checker-rseidelsohn --production --direct 0 --json
{
  "hoge": {
    "fuga": "piyo"
  }
}

  Done in 0.64s.

Note that you can also configure Yarn itself not to output logs.
Reference: https://sunday-morning.app/posts/2021-05-11-yarn-run-silent

jq 'keys'

The jq 'keys' command gets the list of keys from the JSON output.
In this case, I only wanted the package-name@version information from the keys, so I used this to exclude other information.

    "zenn-cli@0.1.150": {
        "licenses": "MIT",
        "repository": "https://github.com/zenn-dev/zenn-editor",
        "path": "/Users/yamamotonaoyuki/private/zenn-docs/node_modules/zenn-cli",
        "licenseFile": "/Users/yamamotonaoyuki/private/zenn-docs/node_modules/zenn-cli/LICENSE"
    },

Side Note

Why I used license-checker-rseidelsohn instead of license-checker

I would have preferred to use license-checker, but there was an issue where the --direct option, which outputs only direct dependencies, does not work (it has been raised as an issue but remains unresolved).
Reference: https://github.com/davglass/license-checker/issues/191

Therefore, I used license-checker-rseidelsohn, which was created as a fork of license-checker, as a substitute.

For Yarn 2+, I'd like to run license-checker-rseidelsohn with yarn dlx

Since I only want to use license-checker-rseidelsohn to output package versions, I'd like to install it using yarn dlx so that it doesn't depend on the project.

In version 1, you can install it globally, but it seems that this will be discouraged in the future according to Yarn's philosophy.

Use yarn dlx instead of yarn global
Yarn focuses on project management, and managing system-wide packages was deemed to be outside of our scope. As a result, yarn global got removed and needs to be replaced by yarn dlx to run one off scripts.

Reference: https://yarnpkg.com/migration/guide#use-yarn-dlx-instead-of-yarn-global

Conclusion

I feel like there might be a simpler way to list them, but this time I used license-checker-rseidelsohn to create the list.
As long as I can output in JSON format, I can probably handle it, but I want to be able to do this kind of thing more effortlessly.

References

https://zenn.dev/luvmini511/articles/56bf98f0d398a5
https://qiita.com/ssc-ynakamura/items/90c6fe31b5f6fe0989ac

Discussion