即使tsc成功设法解决它也找不到Typescript模块 [英] Cannot find Typescript module even though tsc successfully manages to resolve it

查看:523
本文介绍了即使tsc成功设法解决它也找不到Typescript模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Node.js project written in Typescript which is expected to run as a CLI, and am having trouble to import a module located out of the node_modules directory using an absolute path (relative paths work fine). It might be important to mention that I am using the oclif framework for building my CLI.

我的项目的组织方式如下:

My project is organized as follows:

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执行我的应用程序时,我得到

When I try to execute my app with ts-node, I get

(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时,模块已正确解析:

What I can't understand is that when I run tsc --traceResolution the module is correctly resolved:

======== 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/**/*"
  ]
}

如果有人可以阐明这个问题,或者至少建议在哪里寻求进一步的帮助,我将不胜感激.如果需要更多详细信息,请告诉我.

I would greatly appreciate it if anyone could shed some light on this issue, or at least suggest where to look for further help. In case more details are needed, please let me know.

提前谢谢!

推荐答案

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

It turns out that the problem was due to the fact that although both tsc and ts-node use baseUrl for absolute path resolution, neither of them perform any type of actual mapping from absolute to relative paths in the generated Javascript code. In other words, both the transpiled JS files and the code produced internally by ts-node end up having:

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

而我期望它们包含如下内容:

whereas I was expecting them to contain something like:

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

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

which prevented node's module loader from finding the module. ts-node also did not work, I believe, because there was simply no tsconfig.json file to indicate the path mappings.

尽管IMO令人困惑,并且没有正确记录,但这是预期的行为,如所讨论的这里.到目前为止,Typescript不支持绝对路径到相对路径的映射(请参见 https://github.com/Microsoft/TypeScript/issues/15479 ).

Although confusing IMO, and not properly documented, this is expected behavior, though, as discussed here. As of now, absolute to relative path mapping is not supported by Typescript (see https://github.com/Microsoft/TypeScript/issues/15479).

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

In order to avoid the situation known as path hell, which means having very deep relative import paths, I found module-alias and tsmodule-alias to be very useful. These modules alter the behavior of the module loader so that it automatically maps aliases to relative paths.

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

For more information about the problem, refer to this issue on Github.

这篇关于即使tsc成功设法解决它也找不到Typescript模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆