即使tsc成功设法解决它,也找不到Typescript模块

edu*_*du_ 4 command-line-interface node.js typescript ts-node oclif

我有一个用Typescript编写的Node.js项目,它应该作为CLI运行,并且无法node_modules使用绝对路径导入位于目录外的模块(相对路径工作正常).可能很重要的是,我正在使用oclif框架来构建我的CLI.

我的项目安排如下:

cli
 |--node_modules
 |--src
     |--my-module.ts
     |--subdir
          |--index.ts
Run Code Online (Sandbox Code Playgroud)

my-module.ts我有:

 export class MyClass {
     myClassFcn(s: string) {
         return 'result'
     }
 }
Run Code Online (Sandbox Code Playgroud)

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

 import {MyClass} = require('my-module')
Run Code Online (Sandbox Code Playgroud)

当我尝试用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
Run Code Online (Sandbox Code Playgroud)

我无法理解的是,当我运行tsc --traceResolution模块时,正确解决了:

======== Module name 'my-module' was successfully resolved to '/home/eschmidt/Workspace/cli/src/my-module.ts'. ========
Run Code Online (Sandbox Code Playgroud)

我的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/**/*"
  ]
}
Run Code Online (Sandbox Code Playgroud)

如果有人能对这个问题有所了解,或者至少建议在哪里寻求进一步的帮助,我将不胜感激.如果需要更多详细信息,请告知我们.

提前致谢!

edu*_*du_ 13

事实证明,问题是由于尽管tsc和ts-node都baseUrl用于绝对路径解析,但它们都不会在生成的Javascript代码中执行从绝对路径到相对路径的任何类型的实际映射.换句话说,转换后的JS文件和ts-node内部生成的代码最终都具有:

import  {MyClass} = require('my-module')
Run Code Online (Sandbox Code Playgroud)

而我期待它们包含类似的东西:

import  {MyClass} = require('../my-module')
Run Code Online (Sandbox Code Playgroud)

这阻止了节点的模块加载器找到模块.我相信ts-node也没有用,因为根本没有tsconfig.json文件来指示路径映射.

虽然IMO混乱,并没有适当的记录,这是预期的行为,但是,作为讨论在这里.截至目前,Typescript不支持绝对到相对路径映射(请参阅https://github.com/Microsoft/TypeScript/issues/15479).

为了避免称为路径地狱的情况,这意味着具有非常深的相对导入路径,我发现模块别名tsmodule-alias非常有用.这些模块会改变模块加载器的行为,以便自动将别名映射到相对路径.

有关该问题的更多信息,请参阅Github 上的此问题.