使用baseUrl导入模块时如何让tsc解析绝对路径?

46

考虑一个简单的TypeScript项目,其目录结构如下:

|   package.json
|   tsconfig.json
|               
\---src
    |   app.ts
    |   
    \---foobar
            Foo.ts
            Bar.ts

tsconfig.json已被配置为将./src/作为baseUrl

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": true,
        "removeComments": true,
        "preserveConstEnums": true,
        "outDir": "./dist/",
        "baseUrl": "./src/"
    },
    "include": [
        "./src/**/*"
    ],
    "exclude": [
        "node_modules"
    ]
}

现在假设我们想在Bar.ts中导入Foo。我的理解是,通过设置baseUrl,我们现在可以使用绝对路径导入模块。

import { Foo } from 'foobar/Foo'

与相对路径相反

import { Foo } from './Foo'

如果我理解得正确,TypeScript编译器在编译Bar.ts时应该能够自动将foobar/Foo解析为./Foo

import { Foo } from 'foobar/Foo';

export class Bar {
  foo: Foo;

  constructor(num: number) {
    this.foo = new Foo(num);
  }
}

使用tsc编译时没有错误。 但是,当我们实际查看编译的Bar.js文件时,会发现路径没有正确解析,如果运行它,就会出现找不到模块错误。

"use strict";
const Foo_1 = require("foobar/Foo");
class Bar {
    constructor(num) {
        this.foo = new Foo_1.Foo(num);
    }
}
exports.Bar = Bar;

所以我的问题是:当使用 baseUrl 导入模块时,如何让 tsc 正确解析绝对路径?如果无法做到这一点,那么 baseUrl 的目的是什么呢?

5个回答

21

@DenisPshenov的评论中提供了答案。它埋得很深,因此我将在此处提供它...

使用NODE_PATH环境变量告诉Node基础URL在哪里,以便它可以解析绝对路径:

Linux / macOS

NODE_PATH=dist/ node ./dist/index.js

Windows PowerShell

$env:NODE_PATH="dist/"
node ./dist/index.js

6
问题在于您的模块加载器不知道如何找到给定绝对路径foobar/Foo的模块。
TypeScript编译器(tsc)正确解析模块路径,否则您将得到编译错误。但是它信任您适当地配置模块加载器。
例如,从RequireJS文档中:
支持的配置选项: baseUrl:用于所有模块查找的根路径。
TypeScript文档讨论了为什么您可能需要baseUrl
使用baseUrl是使用AMD模块加载器的应用程序中的常见做法,其中模块在运行时“部署”到单个文件夹中。这些模块的源可以位于不同的目录中,但是构建脚本会将它们全部放在一起。

1
谢谢!换句话说,tsc 并不负责将绝对路径转换为相对路径,我们需要配置模块加载器来解决这个问题?如果是这样的话,有没有办法让 tsc 直接转换为相对路径呢? - Zsw
不,据我所知,tsc 不会为您转换路径。如果可能的话,最好在您的 import 语句中使用符合您的模块加载器规范/配置的路径,然后使用各种编译器选项告诉 tsc 如何相应地解析模块名称。 - Seamus
1
作为替代方案,请查看“outFile”编译器选项。它将把模块连接成单个输出:https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#concatenate-amd-and-system-modules-with---outfile - Seamus
9
你可以使用 NODE_PATH=dist/ node dist/app.js 命令,这样 Node 就能够解析绝对路径了。 - Denis Pshenov
@DenisPshenov 谢谢!我简直不敢相信答案埋在评论中。 - Johnny Oshika
显示剩余2条评论

3
对于仍然在这个问题上苦苦挣扎的人来说。
npm i -D tsc-alias
# pacakage.json#scripts
tsc && tsc-alias

2

tsc 无法将路径转换为相对路径,即使您配置了 baseUrlpathspaths 只在您在编辑器中编写代码以进行代码检查时有用。 如果您想让它工作,可以使用 ts-node 和 tsconfig-paths 模块:

$ yarn add ts-node tsconfig-paths --dev

然后运行这个脚本

"start": "ts-node -r tsconfig-paths/register app.ts"

然后你就可以获得正确的性能。


-1
你可以使用 tsconfig 的 path 来实现这个功能:
{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
        "app/*": ["app/*"],
        "config/*": ["app/_config/*"],
        "environment/*": ["environments/*"],
        "shared/*": ["app/_shared/*"],
        "helpers/*": ["helpers/*"],
        "tests/*": ["tests/*"]
    },
}

In this case, you can tell the TypeScript file resolver to support a number of custom prefixes to find code. This pattern can be used to avoid long relative paths within your codebase.

https://www.typescriptlang.org/tsconfig


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