'How can I get all node modules in an express project to use the same version of debug?

In a barebones express app, I have installed the following dependencies:

  "dependencies": {
    "debug": "^4.3.4",
    "express": "^4.17.3",
    "nodemon": "^2.0.15"
  }

Apparently this gives me 6 copies of the debug module, with 3 different versions:

npm list debug
[email protected] /Users/james/Documents/DCI/Repos/Solutions/5_be/EXTRA/be-e05-debug
├── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
└─┬ [email protected]
  └── [email protected]

I would like to create a route in express that allows me to switch on and off different namespaces. In its simplest form, my proof-of-concept app looks like this:

const debug = require('debug')
const express = require('express');
const app = express();

const debugOne = debug("app:one")
const debugTwo = debug("app:two")

app.get("/debug-set/:namespaces", (request, response, next) => {
  const { namespaces } = request.params
  debug.enable(namespaces)
  next()
})

app.get("*", (request, response) => {
  debugOne([request.headers.host, request.url].join(""))
  debugTwo(JSON.stringify(response.getHeaders()))

  response.send("Hello world!")
})

app.listen(3001, () => {
   debugOne("Listening on port 3001")
});

This works fine for the custom namespaces "app:one" and "app:two".

If I send a request from the browser for http://localhost:3001/debug-set/app:one, in the console I see

app:one localhost:3001/debug-set/app:one +XXs

If I send a request from the browser for http://localhost:3001/debug-set/app:two, in the console I see

app:two {"x-powered-by":"Express"} +YYs`

If I send a request from the browser for http://localhost:3001/debug-set/app:*, I see:

 app:one localhost:3001/debug-set/app:* +ZZs
 app:two {"x-powered-by":"Express"} +ZZs

So the basic idea works. However, my app fails to activate the debug instance used by express if I use a request like this:

http://localhost:3001/debug-set/app:*,express:*

I assume that this is because express is using an instance of [email protected] while my script is addressing an instance of [email protected].

I have tried running...

npm update
npm dedupe

... but npm list debug gives exactly the same output as before.

I am not even sure if removing duplicates is a solution. Perhaps, even if all the modules were using the same version of debug, they would still all be using the same instance of that version.

Thanks in advance for any insights that might help me get my proof-of-concept working... or which might prove that it can't be done.


Update

I have my proof of concept : )

I installed yarn and then ran yarn install --flat. This required me to choose versions manually for a dozen or so other dependencies that were also duplicated.

Now all modules use [email protected], and my express route can switch on and off namespaces like express:router:*.

Yay!

However, both yarn list debug and npm list debug print ominous "incompatible" and "invalid" warnings for a range of other modules, so I am not sure how safe this solution is in the long term.

So my question remains: what is the best way to get all dependencies to use the same version of debug (ignoring other duplicate modules)?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source