节点内部错误 MODULE_NOT_FOUND 全局安装但不是本地安装

问题描述 投票:0回答:2

我的目标是获得一个我可以在任何地方执行的 cli。
似乎更好的方法是全局安装。 但是当我尝试时,它会引发一个错误,就像缺少必需的模块一样。

npm install -g <missing_module>

后也无法解决这个问题

我正在使用具有多个节点版本的 nvm,所以我认为这可能是根本原因。 但是当我检查当前使用的节点版本的 node_modules 时,我发现缺少模块。

我不明白。

我把重现的步骤放在这里,用一个小例子 test2 项目。 请注意,我的问题来自另一个大项目,我在 dotenv-safe/config 上也遇到了问题。

如果我解决这个给定的例子,我想我将能够解决其他缺失的模块。

$ mkdir -p test2
$ cd test2
$ npm init -y
$ echo '[{"key": "1"}]' > jsonFile.json
$ touch index.js
$ chmod +x index.js

在 package.json 中添加:

  "type": "module",
  "bin": {
    "test2-cli": "./index.js"
  },
$ cat index.js
#!/usr/bin/env node

import jsonContent from './jsonFile.json' assert { type: "json"}
console.log(jsonContent)

$ ./index.js 
[ { key: '1' } ]
(node:5362) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)

按照 João Pimentel 的建议,我添加了

--experimental-modules
标签。 而且我不想要警告,所以我添加了
--require=suppress-experimental-warnings
选项。

所以我换成

index.js

#!/usr/bin/env node

by

#!/usr/bin/env -S node --experimental-modules --require=suppress-experimental-warnings
$ ./index.js 
node:internal/modules/cjs/loader:1042
  throw err;
  ^

Error: Cannot find module 'suppress-experimental-warnings'
Require stack:
- internal/preload
    at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
    at Module._load (node:internal/modules/cjs/loader:885:27)
    at Module.require (node:internal/modules/cjs/loader:1105:19)
    at Module._preloadModules (node:internal/modules/cjs/loader:1395:12)
    at loadPreloadModules (node:internal/process/pre_execution:621:5)
    at setupUserModules (node:internal/process/pre_execution:125:3)
    at prepareExecution (node:internal/process/pre_execution:116:5)
    at prepareMainThreadExecution (node:internal/process/pre_execution:36:3)
    at node:internal/main/run_main_module:10:1 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ 'internal/preload' ]
}

Node.js v18.13.0
$ npm install suppress-experimental-warnings

added 1 package in 536ms

1 package is looking for funding
  run `npm fund` for details
$ ./index.js 
[ { key: '1' } ]

好的,现在我想在终端的任何地方访问这个 cli。

$ npm install -g .

added 2 packages in 1s

1 package is looking for funding
  run `npm fund` for details
$ cd ../
$ test2-cli
node:internal/modules/cjs/loader:1042
  throw err;
  ^

Error: Cannot find module 'suppress-experimental-warnings'
Require stack:
- internal/preload
    at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
    at Module._load (node:internal/modules/cjs/loader:885:27)
    at Module.require (node:internal/modules/cjs/loader:1105:19)
    at Module._preloadModules (node:internal/modules/cjs/loader:1395:12)
    at loadPreloadModules (node:internal/process/pre_execution:621:5)
    at setupUserModules (node:internal/process/pre_execution:125:3)
    at prepareExecution (node:internal/process/pre_execution:116:5)
    at prepareMainThreadExecution (node:internal/process/pre_execution:36:3)
    at node:internal/main/run_main_module:10:1 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ 'internal/preload' ]
}

Node.js v18.13.0
$ npm install -g suppress-experimental-warnings

added 1 package in 534ms

1 package is looking for funding
  run `npm fund` for details
$ test2-cli
node:internal/modules/cjs/loader:1042
  throw err;
  ^

Error: Cannot find module 'suppress-experimental-warnings'
Require stack:
- internal/preload
    at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
    at Module._load (node:internal/modules/cjs/loader:885:27)
    at Module.require (node:internal/modules/cjs/loader:1105:19)
    at Module._preloadModules (node:internal/modules/cjs/loader:1395:12)
    at loadPreloadModules (node:internal/process/pre_execution:621:5)
    at setupUserModules (node:internal/process/pre_execution:125:3)
    at prepareExecution (node:internal/process/pre_execution:116:5)
    at prepareMainThreadExecution (node:internal/process/pre_execution:36:3)
    at node:internal/main/run_main_module:10:1 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ 'internal/preload' ]
}

Node.js v18.13.0
$ nvm ls
        v6.14.4
       v14.15.5
       v16.10.0
       v16.17.0
->     v18.13.0
        v19.5.0
default -> lts/* (-> v18.13.0)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v19.5.0) (default)
stable -> 19.5 (-> v19.5.0) (default)
lts/* -> lts/hydrogen (-> v18.13.0)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.21.2 (-> N/A)
lts/gallium -> v16.19.0 (-> N/A)
lts/hydrogen -> v18.13.0
$ npm prefix -g
/home/bjam/.nvm/versions/node/v18.13.0
$ ls -la /home/bjam/.nvm/versions/node/v18.13.0/lib/node_modules/ | grep suppress-
drwxr-xr-x  3 bjam bjam 4096 Mar 17 11:00 suppress-experimental-warnings
node.js npm-install suppress-warnings
2个回答
0
投票

使用

require
代替,因为不完全支持
import
,除非你使用
--experimental-modules
标签,例如:
node --experimental-modules index.js

require

#!/usr/bin/env node

const fs = require('fs')
const jsonContent = JSON.parse(fs.readFileSync('./jsonFile.json'))
console.log(jsonContent)

0
投票

我找到了一种解决方法,通过将

readFileSync
替换为实验性 json 导入,结合
URL
import.meta.url
来解析项目的相对路径。

#!/usr/bin/env -S node 

import { readFileSync } from 'fs'

const filePath = new URL('jsonFile.json', import.meta.url)
const jsonContent = JSON.parse(readFileSync(filePath, 'utf-8'))
console.log(jsonContent)

对于

readFileSync
,必须考虑相对路径是相对于当前工作目录(调用脚本的位置)而不是相对于项目(存储
package.json
的位置)。

当前工作目录的相对路径:

readFileSync('jsonFile.json', 'utf-8')

当前文件的相对路径:

new URL('jsonFile.json', import.meta.url)
© www.soinside.com 2019 - 2024. All rights reserved.