简体   繁体   English

Node.js 无法在交互式会话之外找到模块

[英]Node.js unable to find module(s) outside of an interactive session

I am running a node:latest container, with the local disk mapped into it, where my project-specific files reside.我正在运行一个 node:latest 容器,本地磁盘映射到其中,我的项目特定文件所在的位置。 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.我希望服务器在我从容器外部编辑它们时自动检测这些文件中的更改 - 这由nodemon模块提供支持。

This used to work fine the last time I did it, about 2 years ago.大约 2 年前,我上次这样做时,这曾经工作得很好。 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).我采用了那个旧项目,对其进行了更新(除了解决严重的安全漏洞之外,让它现在运行显然是必要的),但它声称从命令行运行 node 时找不到nodemon模块(由容器启动或手动启动)。 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:长版本,带有完整性检查...所有命令都从容器内部运行,在通过 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

nodemon@2.0.16 | 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 <remy@leftlogic.com>

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 <remy@leftlogic.com>

# 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.该脚本在一个新的 node:latest 容器上运行,除了上面显示的目录中的映射之外没有其他怪癖,所以这应该是可重现的。 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.理想情况下,它不会删除 node_modules 和诸如此类的东西,以加快启动速度,但在这种情况下我已经这样做了,只是为了确保一切都是干净的。

And, again, in case someone asks, here's the docker-compose.yml:而且,如果有人问,这里是 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.这就是我能想到的可能与这里相关的所有内容......就像我说的那样,这曾经可靠地工作 - 使用完全相同的 docker-compose.yml 和启动脚本,并具有完整的数据库支持。

Nodemon isn't a module. Nodemon 不是一个模块。 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM