如何在tsconfig.json中使用路径?

390
我正在阅读关于文件path-mapping中的内容,我想使用它来避免使用以下丑陋的路径:

Enter image description here

项目组织有点奇怪,因为我们有一个包含项目和库的单一存储库。项目按公司和浏览器/服务器/通用进行分组。

Enter image description here

如何配置tsconfig.json文件中的路径,以便替换为:
import { Something } from "../../../../../lib/src/[browser/server/universal]/...";

我可以使用:
import { Something } from "lib/src/[browser/server/universal]/...";

Webpack配置中还需要其他东西吗?还是tsconfig.json文件就足够了?

1
请查看 https://www.npmjs.com/package/tspath。 - Patrik Forsberg
20个回答

566
这可以在你的tsconfig.json文件中设置,因为它是一个TypeScript的特性。
你可以这样做:
"compilerOptions": {
        "baseUrl": "src", // This must be specified if "paths" is.
         ...
        "paths": {
            "@app/*": ["app/*"],
            "@config/*": ["app/_config/*"],
            "@environment/*": ["environments/*"],
            "@shared/*": ["app/_shared/*"],
            "@helpers/*": ["helpers/*"]
        },
        ...

请记住,你想引用的路径以你的baseUrl作为指向路由的基础,并且根据文档的描述是必需的。 字符“@”不是必需的。 设置好后,你可以轻松地像这样使用它:
import { Yo } from '@config/index';

唯一可能注意到的是,智能感知在当前最新版本中无法工作,因此我建议遵循一种索引约定来导入/导出文件。
参考:模块解析

105
只是一个可能有助于其他人的评论...如果您正在使用node.js或某些不使用像webpack这样的模块捆绑器的环境,则还需要https://www.npmjs.com/package/module-alias模块。 - Remo H. Jansen
3
@Alejandro Lora,我在项目中使用了这个解决方案,它非常好用,但是当我运行ng test时,karma无法解析环境变量。可能是什么原因? - Gavishiddappa Gadagi
2
我无法让它工作。我有一个tsconfig.json文件,然后在我的src中我有一个tsconfig.app.json文件。我已经尝试将这些值添加到两个文件中,带或不带“*”和斜杠。我只是使用angular-cli。是否有任何特殊的事情必须完成,像webpack一样?谢谢! - emery.noel
5
请注意,jest-test不使用tsconfig-paths,您需要定义一个moduleNameMapper: tsjest#414 - TmTron
3
为了使路径与Node.js配合工作,您需要预加载tsconfig-paths/registerts-node/register/transpile-only - hanan hamza
显示剩余16条评论

44
你可以使用 baseUrlpaths 文档 的组合。
假设根目录位于最顶层的 src 目录(并且我正确读取了你的图像),使用以下内容:
// tsconfig.json
{
  "compilerOptions": {
    ...
    "baseUrl": ".",
    "paths": {
      "lib/*": [
        "src/org/global/lib/*"
      ]
    }
  }
}

对于Webpack,你可能还需要添加一个模块解析。对于Webpack 2,这可能是这样的:
// webpack.config.js
module.exports = {
    resolve: {
        ...
        modules: [
            ...
            './src/org/global'
        ]
    }
}

2
刚刚注意到 @mleko,@alejandro-lora 使用了 baseUrl,而你使用了 rootDir ... 这两者有什么区别? - Frank N

25

查看带星号的类似解决方案

  "baseUrl": ".",
  "paths": {
    "*": [
      "node_modules/*",
      "src/types/*"
    ]
  },

8
我不明白他在这里做了什么。这是用来干什么的? - Paul Razvan Berg
@PaulRazvanBerg 对于所有的导入(*),尝试在 node_modulessrc/types 中查找它们。 - weisk

17
这对我来说很有效:
yarn add --dev tsconfig-paths

ts-node -r tsconfig-paths/register <your-index-file>.ts

这将加载 tsconfig.json 中的所有路径。一个示例的 tsconfig.json
{
    "compilerOptions": {
        {}
        "baseUrl": "./src",
        "paths": {
            "assets/*": [ "assets/*" ],
            "styles/*": [ "styles/*" ]
        }
    },
}

确保你同时拥有baseUrl和paths才能使其正常工作。
然后你可以像这样导入:
import {AlarmIcon} from 'assets/icons'

15

如果您正在寻找使用 @ 引用根目录的最简示例,那么以下代码就是它:

{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "@/*": ["*"]
    }
  }
}
// Example usage: import * as logUtils from '@/utils/logUtils';

或者,如果您甚至没有一个 src 文件夹或想要在导入时明确包含它,那么这种方法也可以使用:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["*"]
    }
  }
}
// Example usage: import * as logUtils from '@/src/utils/logUtils';

这会破坏导入,比如我有一个 axios.ts 文件,我有 import axios from 'axios';,它引用了自身并给我返回了 "any" 类型的结果,所以我将代码改为 "@/*": ["./src/*"] 并移除了 baseUrl - undefined

14
如果您使用路径,您需要将绝对路径更改为相对路径,以便在使用tsc将TypeScript代码编译为纯JavaScript代码后正常工作。
迄今为止,最流行的解决方案是tsconfig-paths
我尝试过它,但对于我复杂的设置来说并不起作用。 此外,它在运行时解析路径,这意味着会增加包的大小和解析性能。
因此,我自己写了一个解决方案tscpaths
总的来说,我认为它更好,因为它在编译时替换路径。这意味着没有运行时依赖或任何性能开销。使用起来非常简单,您只需要在package.json文件的构建脚本中添加一行代码。
该项目还比较年轻,如果您的设置非常复杂,可能会出现一些问题。 不过对于我的设置来说,它运行得非常顺畅,尽管我的设置相当复杂。

有第三种方法:使用 Vercel 的 ncc 工具,将您的 TypeScript 项目编译为单个文件。 - Paul Razvan Berg
看起来这个项目已经被放弃了 - Tyler Dane Hitzeman
请使用tsc-alias代替。 - Braden

10
如果你正在使用 tsconfig-paths 但它无法正常工作,可以尝试使用 tsconfig.json
{
  // ...
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src",
    "baseUrl": ".",
    "paths": {
      "@some-folder/*": ["./src/app/some-folder/*", "./dist/app/some-folder/*"],
      // ...
    }
  },
  // ...
}

如果编译器看到@some-folder/some-class,它会尝试在./src...或者./dist...中找到它。


9
Alejandro的回答对我有用,但是由于我正在使用webpack 4和awesome-typescript-loader,所以我还需要在我的webpack.config文件中添加tsconfig-paths-webpack-plugin以便正确解析。

6
{
  "compilerOptions": {
    "baseUrl": "src"
  },
  "include": ["src"]
}

我不确定我们是否必须定义路径。但是在将baseUrl写入src后,我可以像这样导入src文件夹下的所有文件夹。

import { Home } from "pages";
import { formatDate } from "utils";
import { Navbar } from "components";

在修改 tsconfig.json 后,不要忘记重启终端。


6

这是一种相对路径的写法 与下面的代码不同

import { Something } from "../../../../../lib/src/[browser/server/universal]/...";

我们可以避免使用“../../../../../../”这样看起来奇怪且不易读的路径。
因此,Typescript配置文件对此有答案。 只需指定baseUrl,配置即会处理您的相对路径。
配置方法:在tsconfig.json文件中添加以下属性。
"baseUrl": "src",
    "paths": {
      "@app/*": [ "app/*" ],
      "@env/*": [ "environments/*" ]
    }

所以最终它看起来像下面这样。
import { Something } from "@app/src/[browser/server/universal]/...";

它看起来简洁、棒极了,而且更易读。


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