[英]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.