借助 Typescript 路径映射轻松重构

2025-05-26

借助 Typescript 路径映射轻松重构

重构 Typescript 项目最难的部分是更新所有导入路径。虽然我们常用的许多编辑器都能帮上忙,但 Typescript 编译器选项中隐藏着一个强大的选项,可以彻底解决这个问题。

导入路径

导入是任何 Typescript 项目的关键部分,它使我们能够包含来自不同文件的代码。一个典型的 Angular 组件会有这样的导入。

// Imports from node_modules
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
// Import from relative paths
import { UserComponent } from './user.component';
import { SharedAppCode } from '../../../common/sharedCode';
Enter fullscreen mode Exit fullscreen mode

无论你在应用中的哪个位置,从 node_modules 导入代码始终相同。这是因为默认情况下,任何不以“.”或“/”开头的导入都会被默认为在 node_modules 下找到。

对于应用程序中的任何共享代码,根据当前文件所在的位置,您可能有'../common','../../common','../../../common'甚至'../../../../common'!

这些不一致的相对路径非常难看,而且重构代码也非常麻烦。移动包含这些路径的文件时,导入的代码也必须相应地更改。虽然这看起来是个小问题,但在大型应用中很快就会失控。虽然代码编辑器会尽力更新路径,但有时它们还是会失效……

别担心!Typescript 可以让我们完全避免这个问题。

tsconfig 编译器选项:{ 路径:{ ... } }

有一个编译器选项调用路径,它使我们能够设置可以在导入中使用的路径映射。

鉴于以下文件结构,我们将设置两个路径映射。一个用于允许我们在每个模块中导入 sharedCode,而无需相对路径;另一个用于导入环境文件。

src/
├── app/
│   ├── common/
|   |   └── sharedCode.ts
│   ├── feature/
|   |   └── user/
|   |       └── user.module.ts
│   ├── feature2/
|   |   └── account.module.ts      
├── environments/
|   └── environments.ts
tsconfig.json
Enter fullscreen mode Exit fullscreen mode

在 tsconfig.json 文件中,我们首先需要设置一个baseUrl来告诉编译器路径的起始位置。在本例中,这个起始位置是src文件夹。

"compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "~app/*": ["app/*"],
      "~environments": ["environments/environment"],
    }
  }
Enter fullscreen mode Exit fullscreen mode

我们先看一下应用程序的第一个路径映射。

  "~app/*": ["app/*"]
Enter fullscreen mode Exit fullscreen mode

这告诉 Typescript 编译器,每当它看到以~app/开头的导入时,它就应该在src/app/文件夹下查找代码。这使我们能够将导入路径更新为'~app/common/sharedCode'。结尾的 /* 表示我们可以包含该点之后的任何文件夹路径。在我们的例子中,这是common/sharedCode

// BEFORE: user.module.ts
import {...} from '../../common/sharedCode';
// BEFORE: account.module.ts
import {...} from '../common/sharedCode';

// AFTER: user.module.ts, account.module.ts
import {...} from '~app/common/sharedCode';
Enter fullscreen mode Exit fullscreen mode

因此,尽管相对路径不同,两个模块现在共享完全相同的导入路径。希望您能明白为什么这使得重构变得更容易。现在,如果我们更改文件夹结构,导入内容不再需要更改。

您还可以使用显式路径映射。这里我们直接指向环境文件。注意,这次没有使用 * 通配符。这样我们可以缩短导入到该文件的路径。

  "~environments": ["environments/environment"]
Enter fullscreen mode Exit fullscreen mode
// BEFORE: user.module.ts
import {...} from '../../../environments/environment';
// BEFORE: account.module.ts
import {...} from '../../environments/environment';

// AFTER: user.module.ts, account.module.ts
import {...} from '~environments';
Enter fullscreen mode Exit fullscreen mode

合理的导入分组

你可能注意到,我的两个路径映射都以 ~ 开头。这样做是为了在使用 Visual Studio Code 组织导入时能够进行合理的分组。如果没有 ~,那么你的app/common导入将与你的外部导入分组。

// EXTERNAL: From node_modules
import { Component } from '@angular/core';
import { Observable } from 'rxjs';

// LOCAL: Path mapped 
import { SharedAppCode } from '~app/common/sharedCode';
// LOCAL: Relative path
import { UserComponent } from './user.component';
Enter fullscreen mode Exit fullscreen mode

我非常喜欢使用路径映射来清理我的导入路径。这也意味着,如果我需要重构代码,这将变得轻而易举。你甚至可以根据需要,通过简单的查找和替换来更新导入路径。


Stephen Cooper - AG Grid
高级开发人员 在 Twitter 上关注我@ScooperDev发布有关此帖子的推文。

文章来源:https://dev.to/scooperdev/restruct-with-ease-thanks-to-typescript-path-mappings-4b0e
PREV
构建第一个开源通知基础设施
NEXT
Kubernetes 教程:学习基础知识并开始使用