即使tsc成功解析了Typescript模块,但仍找不到该模块

9
我有一个用Typescript编写的Node.js项目,期望作为CLI运行,但在使用绝对路径(相对路径可以正常工作)导入位于“node_modules”目录之外的模块时遇到了问题。值得一提的是,我正在使用 oclif框架构建我的CLI。
我的项目组织如下:
cli
 |--node_modules
 |--src
     |--my-module.ts
     |--subdir
          |--index.ts

my-module.ts 中,我有:

 export class MyClass {
     myClassFcn(s: string) {
         return 'result'
     }
 }

index.ts脚本包含如下内容:

 import {MyClass} = require('my-module')

当我尝试使用ts-node执行我的应用程序时,我得到了以下结果:
(node:10423) [MODULE_NOT_FOUND] Error Plugin: cli: Cannot find module 'my-module'
    module: @oclif/config@1.6.17
    task: toCached
    plugin: cli
    root: /home/eschmidt/Workspace/cli
    Error Plugin: cli: Cannot find module 'my-module'
        at Function.Module._resolveFilename (internal/modules/cjs/loader.js:571:15)
        at Function.Module._load (internal/modules/cjs/loader.js:497:25)
        at Module.require (internal/modules/cjs/loader.js:626:17)
        at require (internal/modules/cjs/helpers.js:20:18)
        at Object.<anonymous> (/home/eschmidt/Workspace/cli/src/commands/create/index.ts:5:1)
        at Module._compile (internal/modules/cjs/loader.js:678:30)
        at Module.m._compile (/home/eschmidt/Workspace/cli/node_modules/ts-node/src/index.ts:403:23)
        at Module._extensions..js (internal/modules/cjs/loader.js:689:10)
        at Object.require.extensions.(anonymous function) [as .ts] (/home/eschmidt/Workspace/cli/node_modules/ts-node/src/index.ts:406:12)
        at Module.load (internal/modules/cjs/loader.js:589:32)
    module: @oclif/config@1.6.17
    task: toCached
    plugin: my-plugin
    root: /home/eschmidt/Workspace/cli

我不能理解的是,当我运行tsc --traceResolution时,模块被正确地解析:

======== Module name 'my-module' was successfully resolved to '/home/eschmidt/Workspace/cli/src/my-module.ts'. ========

我的 tsconfig.json 文件包含:

{
  "compilerOptions": {
    "declaration": true,
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "importHelpers": true,
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./lib",
    "pretty": true,
    "rootDirs": [
      "./src/"
    ],
    "strict": true,
    "target": "es2017",
    "baseUrl": "src"
  },
  "include": [
    "./src/**/*"
  ]
}

如果有人能够解决这个问题,或者至少建议在哪里寻求进一步帮助,我将非常感激。如果需要更多细节,请告诉我。

提前致谢!


你是否正在subdir目录中运行ts-node,并且从你的根项目目录中运行tsc?使用'../my-module'导入是否管用? - Kewin Dousse
据我所了解,ts-node是在oclif框架中注册的,并且在我运行/bin目录下的sh脚本且lib目录中没有任何编译后的JS文件时会自动调用。我从项目根目录使用yarn运行tsc。像../my-module这样的相对路径导入可以正常工作,如预期所示。 - edu_
2个回答

16

事实证明,问题是由于尽管 tscts-node 都使用 baseUrl 进行绝对路径解析,但它们都没有在生成的 Javascript 代码中执行任何类型的实际从绝对路径到相对路径的映射。换句话说,经过转译的 JS 文件和由 ts-node 内部生成的代码最终都具有以下内容:

import  {MyClass} = require('my-module')

然而我预期它们应该包含像这样的内容:

import  {MyClass} = require('../my-module')

由于没有tsconfig.json文件指示路径映射,这导致了节点模块加载器无法找到该模块,我认为ts-node也无法工作。

虽然我认为这很混乱且未得到适当记录,但正如在此处所讨论的那样,这是预期的行为。目前,TypeScript不支持绝对到相对路径映射(请参见https://github.com/Microsoft/TypeScript/issues/15479)。

为了避免路径混乱问题,即具有非常深的相对导入路径,我发现module-aliastsmodule-alias很有用。这些模块改变了模块加载器的行为,使其自动将别名映射到相对路径。

要了解更多信息,请参阅Github上此问题


2

另一个可能相关的解决方案是使用 NODE_PATH=dist node dist/index.js 运行节点。这实质上告诉 node 每个绝对导入(相对于 baseUrl)应该使用哪个路径。


我已经苦思冥想了两天。由于“找不到模块”(我的自定义模块),即使“tsc --traceResolution”顺利通过,我仍然无法运行我的应用程序。我的设置如下:myproj/src/...。我在tsconfig.json中设置了"outDir": "dist""rootDir": "."。只需将以下内容添加到package.json/Scripts中即可解决问题:"start": "NODE_PATH=dist/src node dist/src/app.js"。感谢您的提示!!! - titusmagnus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接