Typescript/节点错误 [ERR_MODULE_NOT_FOUND]:找不到模块

gui*_*dev 15 node.js typescript

将项目从CJS转换为ESM

我正在尝试将当前的 TypeScript-Node 项目从 ESM 转换为 CJS,但是,我不断收到以下错误

Error [ERR_MODULE_NOT_FOUND]: Cannot find module` 'redacted/dist/config/datadog' 
imported from /redacted/dist/app.js
Run Code Online (Sandbox Code Playgroud)
这是导入的样子app.ts
    import './config/datadog';
Run Code Online (Sandbox Code Playgroud)
这就是它的样子app.js
  import './config/datadog';
Run Code Online (Sandbox Code Playgroud)
这是我的 datadog.ts 文档

数据狗.ts

import tracer from 'dd-trace';
tracer.init({
    logInjection: true,
    profiling: true,
    appsec: true
});

export default tracer;
Run Code Online (Sandbox Code Playgroud)

这是我通过 执行应用程序时收到的错误的完整打印输出~/$ node dist/app.js

> node dist/app.js

node:internal/errors:465
    ErrorCaptureStackTrace(err);
    ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'redacted/dist/config/datadog' imported from /redacted/dist/app.js
    at new NodeError (node:internal/errors:372:5)
    at finalizeResolution (node:internal/modules/esm/resolve:405:11)
    at moduleResolve (node:internal/modules/esm/resolve:966:10)
    at defaultResolve (node:internal/modules/esm/resolve:1176:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:605:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:318:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:80:40)
    at link (node:internal/modules/esm/module_job:78:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Node.js v18.0.0

Process finished with exit code 1
Run Code Online (Sandbox Code Playgroud)

使用 ts-node 运行时工作正常

node --experimental-specifier-resolution=node --loader ts-node/esm app.ts --project tsconfig.json
Run Code Online (Sandbox Code Playgroud)
我的文件配置tsconfig.json如下:
    {
      "compilerOptions": {
        "target": "ES2020",
        "module": "ES2020",
        "lib": ["ES2020"],
        "moduleResolution": "node",
        "esModuleInterop": true,
        "rootDir": "./src",
        "outDir": "./dist",
        "forceConsistentCasingInFileNames": true,
        "strict": true,
      }
    }

Run Code Online (Sandbox Code Playgroud)

JΛY*_*ÐΞV 12

您需要使用 TypeScript v4.7,目前是 TS-Next 版本


一旦升级到typescript@next可以通过执行命令来完成的版本~/$ npm install -D typescript@next,您将需要对文件进行以下更改tsconfig.json

  {
    "compilerOptions": {
    "lib": [
      "ESNext" /* ESNext includes new Level-4 features that were
               recently added to the ECMA-262 JS spec */
     ],

    "module": "NodeNext",/* (1 of 2) TS v4.7 settings you need 
                            to change */

    "moduleResolution": "NodeNext", /* This is the one that will 
                                    specifically solve the error you're 
                                    getting. Without the internal changes
                                    made by this, your project will not
                                    resolve modules correctly. */

    "esModuleInterop": true, /* This is properly configured. FYI you cannot 
                                change this, it must be set to true. */
                                

    /* 
      THE REST OF THE SETTINGS DO NOT AFFECT THE MODULE TYPE OR HOW TSC 
      RESOLVES OTHER MODULES */

    "target": "ES2021",
    "rootDir": "./src",
    "outDir": "./dist",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
  }
}

Run Code Online (Sandbox Code Playgroud)

总结一下

您必须设置tsconfig.json按键module和 ,moduleResolution如下所示。

  1. `moduleResolution:“NodeNext”
  2. module: "NodeNext"

您将需要 TypeScript v4.7


就我个人而言,我保留了一个全局属性,因此下面我显示了全局安装的命令,但您真正需要的只是将其添加到您的node_modules目录中作为当前项目的依赖项。

  1. ~$ sudo npm i -g typescript@next // Global Install

  2. ~$ npm i -D typescript@next // Add as a Project Dependency


我无法帮助现有的 IDE,但如果您使用 VSCode,请使用以下配置,以便您的项目使用 v4.7 版本。

然后需要设置如下配置

"typescript.tsdk": "./node_modules/typescript/lib",
Run Code Online (Sandbox Code Playgroud)

package.json

您还需要为 Node 启用 ESM。。为此,您需要将以下内容添加到您的package.json

/** @file "package.json" */

{
    "type": "module"
}
Run Code Online (Sandbox Code Playgroud)

...或者您可以对所有文件使用点 MTS ( .mts)文件扩展名。两者都有优点,但讨论优点超出了本答案的范围。

应该是这样。这听起来很难,但一旦你以前做过,它实际上很容易。


另一个有用的来源:

此链接的答案涵盖了同一主题,但更详细一些。 我真的建议你检查一下。

  • 谢谢 - "moduleResolution": "nodenext" 是我所需要的。你是一位绅士和一位学者 (3认同)
  • 使用 typescript 5.0.3 这些设置似乎没有帮助。我的猜测是有些事情发生了变化。您能更新一下答案吗? (2认同)