Home > other >  Node.js unable to find module(s) outside of an interactive session
Node.js unable to find module(s) outside of an interactive session

Time:06-24

I am running a node:latest container, with the local disk mapped into it, where my project-specific files reside. I want the server to auto-detect changes in these files as I edit them from outside the container - this is powered by the nodemon module.

This used to work fine the last time I did it, about 2 years ago. I took that old project, updated it (as was apparently necessary to get it to even run now, on top of resolving critical security vulnerabilities), but it claims it can't find the nodemon module when running node from the command-line (either initiated by the container or manually). If I start an interactive node session, after shelling into the container, it can find the module(s).

The modules are freshly installed when the container starts up. At least for the time being, this will change once the issues are sorted out.

The short version:

# node nodemon version
internal/modules/cjs/loader.js:1032
  throw err;
  ^

Error: Cannot find module '/app/nodemon'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1029:15)
    at Function.Module._load (internal/modules/cjs/loader.js:898:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

# node
Welcome to Node.js v14.4.0.
Type ".help" for more information.
> nm = require("nodemon")
[Function: nodemon] {
  restart: [Function (anonymous)],
  on: [Function (anonymous)],
  addListener: [Function (anonymous)],
  once: [Function (anonymous)],
  emit: [Function (anonymous)],
  removeAllListeners: [Function (anonymous)],
  reset: [Function (anonymous)],
  config: {
    run: false,
    system: { cwd: '/app' },
    required: true,
    dirs: [],
    timeout: 1000,
    options: {},
    load: [Function (anonymous)],
    reset: [Function: reset]
  }
}
> .exit

The long version, with sanity checks... All commands were run from inside the container, in the local directory that has been mounted via the docker-compose.yml:

# pwd
/app

# ls
bin  data  node_modules  package-lock.json  package.json  public  routes  server.js  startScript.sh  views

# cat package.json
{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.0",
    "cookie-parser": "^1.4.6",
    "debug": "^4.3.4",
    "express": "^4.18.1",
    "http-errors": "^2.0.0",
    "jQuery": "^1.7.4",
    "morgan": "^1.10.0",
    "multer": "^1.4.5-lts.1",
    "nodemon": "^2.0.16",
    "pug": "^3.0.2"
  }
}

# export NODE_PATH=/app/node_modules

# echo $NODE_PATH
/app/node_modules

# ls $NODE_PATH
@babel          binary-extensions  color-convert         depd           function-bind         imurmurhash              is-regex           mime-db         on-headers            pug-filters          registry-url    strip-json-comments              url-parse-lax
@sindresorhus   body-parser        color-name            destroy        get-intrinsic         inherits                 is-typedarray      mime-types      once                  pug-lexer            resolve         supports-color                   util-deprecate
@szmarczak      boxen              concat-map            doctypes       get-stream            ini                      is-yarn-global     mimic-response  p-cancelable          pug-linker           responselike    supports-preserve-symlinks-flag  utils-merge
abbrev          brace-expansion    concat-stream         dot-prop       glob-parent           ipaddr.js                isarray            minimatch       package-json          pug-load             safe-buffer     to-fast-properties               vary
accepts         braces             configstore           duplexer3      global-dirs           is-binary-path           jQuery             minimist        parseurl              pug-parser           safer-buffer    to-readable-stream               void-elements
acorn           buffer-from        constantinople        ee-first       got                   is-ci                    js-stringify       mkdirp          path-parse            pug-runtime          semver          to-regex-range                   widest-line
ansi-align      busboy             content-disposition   emoji-regex    graceful-fs           is-core-module           json-buffer        morgan          path-to-regexp        pug-strip-comments   semver-diff     toidentifier                     with
ansi-regex      bytes              content-type          encodeurl      has                   is-expression            jstransformer      ms              picomatch             pug-walk             send            token-stream                     wrap-ansi
ansi-styles     cacheable-request  cookie                end-of-stream  has-flag              is-extglob               keyv               multer          prepend-http          pump                 serve-static    touch                            wrappy
anymatch        call-bind          cookie-parser         escape-goat    has-symbols           is-fullwidth-code-point  latest-version     negotiator      process-nextick-args  pupa                 setprototypeof  type-fest                        write-file-atomic
append-field    camelcase          cookie-signature      escape-html    has-tostringtag       is-glob                  lowercase-keys     nodemon         promise               qs                   side-channel    type-is                          xdg-basedir
array-flatten   chalk              core-util-is          etag           has-yarn              is-installed-globally    lru-cache          nopt            proxy-addr            range-parser         signal-exit     typedarray                       xtend
asap            character-parser   crypto-random-string  express        http-cache-semantics  is-npm                   make-dir           normalize-path  pstree.remy           raw-body             statuses        typedarray-to-buffer             yallist
assert-never    chokidar           debug                 fill-range     http-errors           is-number                media-typer        normalize-url   pug                   rc                   streamsearch    undefsafe
babel-walk      ci-info            decompress-response   finalhandler   iconv-lite            is-obj                   merge-descriptors  object-assign   pug-attrs             readable-stream      string-width    unique-string
balanced-match  cli-boxes          deep-extend           forwarded      ignore-by-default     is-path-inside           methods            object-inspect  pug-code-gen          readdirp             string_decoder  unpipe
basic-auth      clone-response     defer-to-connect      fresh          import-lazy           is-promise               mime               on-finished     pug-error             registry-auth-token  strip-ansi      update-notifier

# npm view nodemon

[email protected] | MIT | deps: 10 | versions: 237
Simple monitor script for use during development of a Node.js app.
https://nodemon.io

keywords: cli, monitor, monitor, development, restart, autoload, reload, terminal

bin: nodemon

dist
.tarball: https://registry.npmjs.org/nodemon/-/nodemon-2.0.16.tgz
.shasum: d71b31bfdb226c25de34afea53486c8ef225fdef
.integrity: sha512-zsrcaOfTWRuUzBn3P44RDliLlp263Z/76FPoHFr3cFFkOz0lTPAcIw8dCzfdVIx/t3AtDYCZRCDkoCojJqaG3w==
.unpackedSize: 196.5 kB

dependencies:
chokidar: ^3.5.2          debug: ^3.2.7             ignore-by-default: ^1.0.1 minimatch: ^3.0.4         pstree.remy: ^1.1.8       semver: ^5.7.1            supports-color: ^5.5.0    touch: ^3.1.0             undefsafe: ^2.0.5         update-notifier: ^5.1.0   

maintainers:
- remy <[email protected]>

dist-tags:
debug-1268: 1.15.2-alpha.2  debug: 2.0.14-alpha.1       latest: 2.0.16              

published a month ago by remy <[email protected]>

# node nodemon version
internal/modules/cjs/loader.js:1032
  throw err;
  ^

Error: Cannot find module '/app/nodemon'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1029:15)
    at Function.Module._load (internal/modules/cjs/loader.js:898:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

# node
Welcome to Node.js v14.4.0.
Type ".help" for more information.
> nm = require("nodemon")
[Function: nodemon] {
  restart: [Function (anonymous)],
  on: [Function (anonymous)],
  addListener: [Function (anonymous)],
  once: [Function (anonymous)],
  emit: [Function (anonymous)],
  removeAllListeners: [Function (anonymous)],
  reset: [Function (anonymous)],
  config: {
    run: false,
    system: { cwd: '/app' },
    required: true,
    dirs: [],
    timeout: 1000,
    options: {},
    load: [Function (anonymous)],
    reset: [Function: reset]
  }
}
> .exit
# export NODE_PATH=/app

# echo $NODE_PATH
/app

# node nodemon
internal/modules/cjs/loader.js:1032
  throw err;
  ^

Error: Cannot find module '/app/nodemon'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1029:15)
    at Function.Module._load (internal/modules/cjs/loader.js:898:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

# 

Because I expect someone will ask, despite the seeming irrelevance, here is the script that installs the modules:

#!/bin/sh

rm /app/package.json
rm /app/package-lock.json
rm -rf /app/node_modules

npm init -y

npm install express
npm install http-errors
npm install pug
npm install morgan
npm install cookie-parser
npm install debug
npm install jQuery
npm install body-parser
npm install multer

npm install nodemon

npm audit
npm audit fix

That script is run on a fresh node:latest container, with no other quirks beyond mapping in the directory shown above, so this should be reproducible. It ideally won't remove the node_modules and whatnot, to speed start-up, but I have it doing it in this case, just to be sure everything is clean.

And, again, in case someone asks, here's the docker-compose.yml:

#redis:
#  image: redis
#  volumes:
#    - ./webapp/data/redis:/data

#mysql:
#  image: mysql:latest
#  environment:
#    MYSQL_ROOT_PASSWORD: StackOverflowsdfj87ey2,238n
#    MYSQL_DATABASE: StackOverflowDB
#    MYSQL_USER: StackOverflow  
#    MYSQL_PASSWORD: StackOverflowmcxhdie73.6xm
#  volumes:
#    - ./webapp/data/mysql:/var/lib/mysql

application:
  image: node:latest
  working_dir: /app
  command: /app/startScript.sh
  volumes:
    - ./webapp:/app
  ports:
    - 80:3000
#  links:
#    - redis
#    - mysql

That's about all I can think of that might be relevant here... Like I said, this used to work reliably - using the exact same docker-compose.yml and start-up script, with full database support.

CodePudding user response:

Nodemon isn't a module. Normally it's installed globally and used as a command from the command line.

Since it isn't installed globally, a way to run it is to start it like this

./node_modules/nodemon/bin/nodemon.js -h
  • Related