GithubHelp home page GithubHelp logo

ranyitz / qnm Goto Github PK

View Code? Open in Web Editor NEW
1.9K 13.0 34.0 2.42 MB

:mag: cli utility for querying the node_modules directory

License: MIT License

JavaScript 0.62% TypeScript 99.29% Shell 0.08%
npm javascript cli nodejs typescript yarn

qnm's Introduction

qnm-logo

πŸ” A simple cli utility for querying the node_modules directory

Build Status NPM version License

qnm-help

Why?

most bugs are caused by the assumptions we didn't realize we were making.

I often need to quickly check the versions of the modules installed in the node_modules directory. Current solutions like running npm list are slow and produce a lot of irrelevant output. Checking the version in the package.json file of the specific module requires more effort and doesn’t provide information about other instances of the same module.

qnm is a tool that solves this problem by providing fast and focused information about the installed modules. It supports both npm and yarn and allows you to quickly identify the versions of the modules you are interested in.

Features

  • ✨ Interactive fuzzy-search
  • πŸ”€ Match all packages with a specific string
  • ⁉️ Explain why a package was installed
  • πŸ“š Supports monorepos
  • πŸ•› Show when a version was release and what is the latest version

Usage

You can use bunx/npx to run qnm, the docs use bunx because it's the fastest way

bunx qnm [module]

For example, if you want to see the installed versions of lodash:

bunx qnm lodash

And you'll see something like that:

lodash 4.17.21 β†° 2 days ago
β”œβ”€β”€ 4.17.21 βœ“
β”œβ”€β”¬ cli-table2
β”‚ └── 3.10.1 ⇑ 1 year ago
└─┬ karma
  └── 3.10.1 ⇑ 1 year ago

Which means you have 3 occurrences of lodash in your node_modules:

  1. ./node_module/lodash
  2. ./node_module/cli-table2/node_modules/lodash
  3. ./node_module/karma/node_modules/lodash
  • The latest version of lodash is 4.17.21, it was published 2 days ago.
  • The other 2 occurrences of lodash (3.10.1) were released a year ago.

Fuzzy-search

fuzzy-search

Use qnm command without arguments to trigger an fzf like fuzzy search.

  • Start typing to filter the matches from your node_modules
  • Use arrows to move cursor up and down
  • Enter key to select the item, CTRL-C / ESC to exit
  • TAB and Shift-TAB to mark multiple items

Options

--no-remote

do not fetch remote data from npm, use this if you want qnm to run faster. qnm will show limited view.

-o , --open

Open the module's package.json file with the default editor.

-d, --debug

See full error messages, mostly for debugging.

--disable-colors

Disables the most of colors and styling. E.g. version colors.

Commands

doctor

experimental

Shows the heaviest modules in your node_modules. Helpful if you want to understand what's taking the most space on your node_modules directory.

bunx qnm doctor

sort the modules based on the amount of duplications they have in your node_modules.

bunx qnm doctor --sort duplicates

image

list

alias: ls

Returns a list of all modules in node_modules directory.

bunx qnm list
Optional arguments Description
--deps List the versions of direct dependencies and devDependencies.
--remote Fetch remote data, this may be very slow for many packages due to many network requests

match

Works like grep, and match's any module that includes the supplied string.

For example, i want to see which eslint plugins i have installed:

> bunx qnm match eslint-plug

eslint-plugin-babel
└── 3.3.0

eslint-plugin-lodash
└── 2.6.1

eslint-plugin-mocha
└── 4.12.1

eslint-plugin-react
└── 6.10.3
Optional arguments Description
--remote Fetch remote data, this may be very slow for many packages due to many network requests

homepage

Opens package "homepage" property in your browser.

Contributing

Help is always welcome! Please head to the CONTRIBUTING.md file to see how to get started.

License

The MIT License

Installation

while qnm used to be installed globally, it's recommended to use npx/bunx to run it, it's just much faster.

If you prefer the global installation, you can do it with:

npm i --global qnm

qnm's People

Contributors

ajitzero avatar dependabot[bot] avatar dvakatsiienko avatar ealush avatar lavgl avatar nelson6e65 avatar peetwriter avatar ranyitz avatar ronami avatar rulsky avatar sidoruk-sv avatar sleepwalker avatar sukkaw avatar vsashyn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qnm's Issues

Show a warning that explain why the "why info" is not presented

When you use yarn without generating a lock file qnm has no way to understand why a package was installed (I mean, fast...)

We can show to the user a warning message that why information is missing and they can generate a yarn lockfile to see this information.

Recently changed dependencies

Not sure if this awesome package is suitable for this usecase, but time to time we need to know which packages were changed in a given period of time. For example:

qnm --changes=day|10|month|...`

What do you think ?

Mark symlinks with a special sign

When a dependency in node_modules is actually a directory which is a symlink to another directory (happens when you yarn link or npm link) it something that we usually want to know when running qnm.

I think we can add a πŸ”— symbol to the output or maybe show the original location via

my-module -> ../../original/location/of/my-module
└── 1.2.3

Should this work in Windows Anaconda?

(base) PS C:\Users\loren> npm i --global qnm

added 1 package in 1s
(base) PS C:\Users\loren> qnm lodash
could not identify package directory

I moved to:
d----- 1/12/2020 6:27 PM node_modules

(base) PS C:\Users\loren> cd node_modules
(base) PS C:\Users\loren\node_modules> qnm core-js
could not identify package directory
(base) PS C:\Users\loren\node_modules> qnm list
could not identify package directory
(base) PS C:\Users\loren\node_modules> which qnm
which : The term 'which' is not recognized as the name of a cmdlet, function, script file, or operable program. Check
the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1

  • which qnm
  •   + CategoryInfo          : ObjectNotFound: (which:String) [], CommandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException
    

(base) PS C:\Users\loren\node_modules>

Maybe just not going to work? But it seemed to install...

Use Ellipsis when there are more than 3 reasons for having a module

Even after the optimization of #106 we're still going to see some module that are required by many other modules. If we take lodash as an example, you'll see that the user doesn't need to know the reason it's installed.

The "why" info is helpful when there is 1 or 2 modules that cause the inspected module to be installed. If we have 3 we can just use ...

In the future we should create a dedicated qnm why command. The output as it is today is not readable at all.

image

--why shows first level/depth dependents

Say I have the following graph:

a -> b -> c -> d (a depends on b and so on).

When I do qnm --why d, I'm getting c, which is fine - but I'd like to get the entire path until the direct dependency itself in some manner.

Windows: Unable to use on scoped packages

qnm '@angular/fire'

# Error:
Could not find any module by the name: "@angular/fire". Did you mean "@angular\fire"?
qnm '@angular\fire'

# Error:
Command failed with exit code 4294963238: npm view @angular\fire --json
0 verbose cli C:\laragon\bin\nodejs\node-v16\node.exe C:\laragon\bin\nodejs\node-v16\node_modules\npm\bin\npm-cli.js
1 info using [email protected]
2 info using [email protected]
3 timing npm:load:whichnode Completed in 0ms
4 timing config:load:defaults Completed in 2ms
5 timing config:load:file:C:\laragon\bin\nodejs\node-v16\node_modules\npm\npmrc Completed in 1ms
6 timing config:load:builtin Completed in 1ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 1ms
9 timing config:load:file:C:\Users\Nelson Martell\Documents\GitHub\alazes\buen-cemento\.npmrc Completed in 2ms
10 timing config:load:project Completed in 5ms
11 timing config:load:file:C:\Users\Nelson Martell\.npmrc Completed in 1ms
12 timing config:load:user Completed in 1ms
13 timing config:load:file:C:\laragon\bin\nodejs\node-v16\etc\npmrc Completed in 0ms
14 timing config:load:global Completed in 0ms
15 timing config:load:validate Completed in 1ms
16 timing config:load:credentials Completed in 0ms
17 timing config:load:setEnvs Completed in 1ms
18 timing config:load Completed in 15ms
19 timing npm:load:configload Completed in 15ms
20 timing npm:load:mkdirpcache Completed in 1ms
21 timing npm:load:mkdirplogs Completed in 0ms
22 verbose title npm view @angular\fire
23 verbose argv "view" "@angular\\fire" "--json"
24 timing npm:load:setTitle Completed in 1ms
25 timing config:load:flatten Completed in 2ms
26 timing npm:load:display Completed in 4ms
27 verbose logfile logs-max:10 dir:C:\Users\Nelson Martell\AppData\Local\npm-cache\_logs
28 verbose logfile C:\Users\Nelson Martell\AppData\Local\npm-cache\_logs\2022-06-02T15_45_20_975Z-debug-0.log
29 timing npm:load:logFile Completed in 10ms
30 timing npm:load:timers Completed in 0ms
31 timing npm:load:configScope Completed in 0ms
32 timing npm:load Completed in 33ms
33 silly logfile start cleaning logs, removing 3 files
34 timing command:view Completed in 6ms
35 verbose stack Error: ENOENT: no such file or directory, open 'C:\Users\Nelson Martell\Documents\GitHub\alazes\buen-cemento\@angular\fire\package.json'
36 verbose cwd C:\Users\Nelson Martell\Documents\GitHub\alazes\buen-cemento
37 verbose Windows_NT 10.0.22000
38 verbose node v16.14.0
39 verbose npm  v8.6.0
40 error code ENOENT
41 error syscall open
42 error path C:\Users\Nelson Martell\Documents\GitHub\alazes\buen-cemento\@angular\fire/package.json
43 error errno -4058
44 error enoent ENOENT: no such file or directory, open 'C:\Users\Nelson Martell\Documents\GitHub\alazes\buen-cemento\@angular\fire\package.json'
45 error enoent This is related to npm not being able to find a file.
45 error enoent
46 verbose exit -4058
47 timing npm Completed in 60ms
48 verbose code -4058
49 error A complete log of this run can be found in:

Fuzzy finder seems to located it:

> @angul
16/1562
 @angular\cli
> @angular\fire
 @angular\core
 @angular\forms
# ...

But I get the same error when I press enter on @angular\fire.

options should be passed to fuzzy-search mode.

Today, when calling qnm --why the fuzzy-search mode is open, but the result doesn't show the "why" information.

CLI options should be passed to the fuzzy-search, so it would call the getAction while preserving user options.

Add a way to include bundled dependencies

Hey, 10x for this great tool.

I encountered a case where when installing packages that uses bundledDependencies running qnm does not report about these dependencies.

It would be nice to have support for this as one of the functionalities that qnm is providing is to figure out what version is actually running.

Show deprecated modules

If a module has deprecate: true we can show it under a different color, maybe even show a message next to it.

This makes it easy to see and replace those packages.

Option `--disable-colors` seems not to be working

Disable colors option has no effect. This can also be seen looking at snapshot files:

https://github.com/ranyitz/qnm/blob/master/src/__tests__/actions/__snapshots__/match.spec.ts.snap#L3-L7

btw. we can also rename --disable-colors to --no-color because it looks more standard way to disable color output in other cli tools. Moreover, because the old option was not working, I think, that the new option can be added without incrementing a major version

-- homepage option

Open the homepage of a certain module.

usage:

qnm [module] --homepage

Add an option to output as JSON

It could be nice to have an option (--json) to output the result as JSON, so it would be easier for other programs to parse the data.

Show --why information by default

I find myself running qnm -w every time. The added output of --why is quite important and should not interfere for understanding.

It makes me think that we should remove the --why option and just run it by default.

--open option

When calling qnm [module] --open it should open the user's $EDITOR at the module's directory.

If there are multiple occurrences, we can open a list and let the user choose a module from the list, using Inquirer for example.

qnm list --deps

Sometimes we only want to list the dependencies that we install directly.

qnm list --deps

Should provide the user with a list of modules that got installed because they were in package.json's dependencies/devDependencies

Return the paths of a specific package (--path/-p)

It would be nice to show that paths of the packages found, for example, when you run qnm @types/express --path it would be nice to return the absolute paths of the found packages:

.../my-project/node_modules/@types/express

It would be valuable in monorepos, when the paths can be a bit more complex to reason about.

enhance fuzzy-search with multi-select feature

fzf has this nice feature that enables multi-selection.

By pressing tab you mark a selection and go down, shift+tab mark a selection and go up.

fzf-multi-select

keep in mind that the selection is based on the value rather than the location (unlike the cursor) so when the query is changing you won't mess up the already selected values.

Dedupe the reasons for a module to be installed

When using yarn 3, qnm gets many "reasons" for each module, a specific module is installed because of many different versions. This is not very interesting to the user. We can dedupe them by removing the @npm:^7.1.0 suffix and leave only the unique ones.

image

The work should be done on the requiredByInfo:

return requiredByInfo.map((modulePath) => {

Add pnpm support?

This looks like a nice tool but it doesn't seem to work with pnpm installations (we, specifically, use Yarn 3 & its pnpm linker but I guess using the pnpm CLI itself would have the same problem).

The output is just this:

$ npx qnm
node_modules directory is empty

Scoped packages should be displayed using `/` separator, regardless of OS

On Windows, qnm displays scoped packages using \ separator instead of the name of the package on npm register. It should use @scope/name instead of @scope\name regardless of directory separator used by the operating system.

Example:

$ qnm doctor
size    count  module
------  -----  ----------
107.7mb   2 😠 typescript
59.42mb   1 βœ“  @firebase\firestore
49.97mb   1 βœ“  cordova-plugin-ionic
41.68mb  55 πŸ˜– source-map
20.78mb   1 βœ“  @angular\core
20.31mb   2 😠 @schematics\angular
18.74mb   1 βœ“  @angular\compiler
18.57mb  37 πŸ˜– postcss
18.16mb   1 βœ“  firebase
16.83mb   1 βœ“  prettier
15.65mb   1 βœ“  @ionic\core
15.47mb   1 βœ“  @stencil\core
13.46mb   3 😠 rxjs
12.86mb   1 βœ“  @firebase\database
12.44mb   1 βœ“  @angular\common
12.16mb   1 βœ“  @ionic\angular-toolkit
11.71mb  13 😑 ajv
9.36mb    1 βœ“  @angular\compiler-cli
8.79mb    1 βœ“  esbuild-wasm
8.54mb    1 βœ“  npm

Bring back shell autocompletions

The most frequent workflow for me, is to either retrieve a package version that I already retrieved in the past (When working on a specific problem/package) and of course trying to get a version of a package from within the repo.

Shell autocompletions are perfect for that use-case.

  1. We'll show the user autocompletions based on the list of modules exists in the node_modules.
  2. We can save the last "qnm queries" and sort them to be first.
  3. We can use levenshtein distance to still give good completions even if there are typos.

Better experience with npx

When I do, for instance, npx qnm --why x - there's a post-install script that installs smth (with tabtab). I've not checked why, but it's a bit frustrating to install it every time I use npx (and wait for npm install under the hood).

Bug: qnm spawns check.js which eats CPU

Hello everyone,

I've updated from 1.6 to 2.4. And now, when I issue any command (even qnm -v), qnm spawns multiple check.js processes that are hanging around and eating lots of CPU. The only way I've managed to kill it is by using pkill node.

Here is the script that is spammed: https://github.com/datacrafts-io/update-notifier-webpack/blob/master/check.js

But looks like the issue is not with that script but with current startup logic and ncc. There are actually two issues

Issue 1

ncc produces two files index.js and check.js. When index.js is required, it immediately calls updateNotifier({ pkg }).notify(); which behind the scenes spawns check.js:

image

and here is how check.js is looks like:

image

Looks like updateNotifier({ pkg }).notify(); should be called at the later stage. Somewhere after parsing the args.

Issue 2

updateNotifier({ pkg }).notify(); is not the only thing, that runs on require('.') from check.js. There is also command line parsing that is running too.

If you change stdio in spawn call from ignore, to inherit:

image

you'll see the following error:

image

this is qnm cli trying to find module when check.js runs

FR: Support for monorepos within subdirectory?

I'm not usually in my monorepo root. It would be great if qnm looked for the nearest node_modules dir, even if it required a flag. Maybe -n, --nearest? This seems like a sensible solution as many monorepo setups have multiple node_modules directories, though most seem to be moving away from that.

Anyway, great tool! Thanks!

What does count actually mean?

Hey, I tried going through the readme but I cannot figure out what the count is? It's not obvious or at least not obvious enough for my small brain?

ENAMETOOLONG: name too long, scandir xxx

qnm react

ENAMETOOLONG: name too long, scandir '/Users/Desktop/workspace/xxxx/node_modules/xxx/node_modules/webpack/node_modules/@webassemblyjs/ast/node_modules/@webassemblyjs/helper-module-context/node_modules/@webassemblyjs/ast/node_modules/@webassemblyjs/helper-module-context/node_modules/@webassemblyjs/ast/node_modules/@webassemblyjs/helper-module-context/node_modules/@webassemblyjs/ast/node_modules/@webassemblyjs/helper-module-context/node_modules/@webassemblyjs/ast/node_modules...

Show which modules have non-opensource licenses

Hey πŸ‘‹,

What if we have a separate command that will check the entire tree and show which modules don't have opensource licenses.

This can be useful to make sure every package in your project has an opensource license.

Wdyt?

--why should also work with node_modules that installed using yarn

Currently when using the --why feature we rely on _requiredBy field, provided only by npm.

We should be able to detect if the node_modules were installed by yarn/npm and act accordingly to give a similar experience for both.

We could parse the yarn.lock file, the --why data is being stored there, in a reverse manner, but that should be possible to extract it with some transformations.

Each version should have the same color

Hey! Thanks for the awesome tool! πŸ‘

I want to propose an enhancement. What if each version will have the same color?

For example, my project has 2 versions of @babel/core 7.0.0 and one 6.0.0. It will be easier to determine exact versions with a cursory glance.

fish completions command error

I tried getting the fish completions from this package and go the following result:

> qnm install-completions
could not identify package directory
[I]  ~/G/fish (master) [1]> oh oh Error: setRawMode EIO
    at ReadStream.setRawMode (tty.js:77:31)
    at Interface._setRawMode (readline.js:298:16)
    at new Interface (readline.js:258:10)
    at Object.createInterface (readline.js:95:10)
    at module.exports (/usr/local/lib/node_modules/qnm/node_modules/inquirer/lib/ui/baseUI.js:14:24)
    at new module.exports (/usr/local/lib/node_modules/qnm/node_modules/inquirer/lib/ui/prompt.js:15:8)
    at Object.promptModule [as prompt] (/usr/local/lib/node_modules/qnm/node_modules/inquirer/lib/inquirer.js:26:14)
    at /usr/local/lib/node_modules/qnm/node_modules/tabtab/src/installer.js:222:35
[I]  ~/G/fish (master) [1]> which qnm
which qnm
/usr/local/bin/qnm

I'm not sure what is going on here. Any help would be greatly appreciated. Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.