网站搜索

node.js - 如何在 TypeScript 中正确解析路径别名?


我正在使用 Node.js 18 制作一个 TypeScript 应用程序。

这是我的 package.json:

{
  type: "module",
  types: "./@types/index.d.ts",
  exports: "./dist/main.js"
}

我正在使用 type: "module",这样我就可以使用 import/export 语法。

这是我的 tsconfig.json 文件:

{
  "compilerOptions": {
    "target": "es2016",
    "module": "ESNext",
    "moduleResolution": "ESNext",
    "rootDir": "./src",
    "baseUrl": "./",
    "paths": {
      "@tools/*": ["src/tools/*"]
    },
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "outDir": "./dist",
    "removeComments": true,
    "declarationDir": "./@types",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  },
  "exclude": ["./@types", "node_modules"],
  "include": ["./src/**/*"]
}

这是我的文件夹结构:

src/
├── tools/
│   └── log.ts
└── main.ts
tsconfig.json
package.json

这是我的 main.ts 文件,它是我程序的入口点:

import log from '@tools/log.js'
log("hello world")

这是我的 log.ts 文件:

export default function log(message: string){
  console.log(message)
}

现在,在我的控制台中,我想运行:

npx tsc
SUCCESS !
node ./dist/main.js
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@tools/log.js' imported from ~/dist/main.js

我哪里做错了?

我在开始我的项目时遇到了很大困难,我对 TypeScript 中的三个 x、y、z 路径感到困惑,这在任何项目中都会导致一切出错:

  1. package.json 的 "type" 字段。
  2. tsconfig.json module。
  3. tsconfig.json moduleResolution。

这三者可以有多种选择,我们根本不知道哪一个是最好的,而且它们总是相互冲突。

例如,现在我在我的 package.json 中使用 "type": "module",我就不能使用 ts-node。

如果我更改了 "module" 属性,我就无法使用 chalk。

现在,由于 TypeScript 在构建过程中不会解析路径别名,我在设置 tsconfig-paths 时遇到了很多问题,而且我根本不知道如何仅为这个简单任务配置 Babel 或 Webpack。

我在考虑最简单的构建工作流程:

  1. 编写使用路径别名功能的 TypeScript 代码。
  2. 使用 tsc 构建你的代码。
  3. 使用一些工具,例如 Babel,来解析 dist/ 目录中的路径别名。
  4. 使用 node ./dist/main.js 运行你的代码

这是我能想到的最简单的构建工作流程。

但现在我也有了开发工作流程,我必须以某种方式将以下内容整合在一起共同工作

  1. nodemon 或 node -w,或者 ts-node(由于 package.json 中的 "type": "module",无法工作)。
  2. tsc -w。
  3. 巴别塔。

答案#1

这是让你的别名路径在 TypeScript 中工作的方式。 :

首先,在 tsconfig.json 中配置 paths,这样 TypeScript 就不会在类似这样的别名路径上显示波浪线了:

import log from "@tools/log";

请注意,像 .js 或 .ts 这样的扩展名不应出现在导入路径中,因为在构建之后扩展名会发生变化。

接下来,安装这些包:ts-node 和 tsconfig-paths

> npm install --save-dev ts-node
> npm install --save-dev tsconfig-paths

包 ts-node 对工作流程有帮助,因为它可以像这样直接运行 TypeScript 文件:

> ts-node src/main.ts

不幸的是,ts-node 并不能自动处理别名路径。它需要 tsconfig-paths 来解析这些路径。要使用 tsconfig-paths,请像这样将 ts-node 添加到 tsconfig.json 中:

{
  "compilerOptions": {...},
  "exclude": [...],
  "ts-node": {
    "require": ["tsconfig-paths/register"]
  }
}

请注意,上面的 ts-node 与 compilerOptions 和 exclude 位于同一层级。现在 ts-node 可以运行带有别名路径的文件。此外,其他使用 ts-node 的包,例如 nodemon,也可以像这样运行 TypeScript 文件:

> nodemon src/main.ts

以下是如何在 TypeScript 构建期间解析别名路径的方法。 :

你将需要这些包:typescript-transform-paths 和 ts-patch。

> npm install --save-dev typescript-transform-paths
> npm install --save-dev ts-patch

在构建过程中,typescript-transform-paths 会将别名路径解析为类似这样的相对路径:

import log from "../tools/log";

要使用 typescript-transform-paths,请像这样在 tsconfig.json 中添加 plugins:

{
  "compilerOptions": {
    ...,
    "plugins": [{ "transform": "typescript-transform-paths" }] 
  }
}

请注意上面 plugins 位于 compilerOptions 中。现在像这样使用 tspc 而不是 tsc 来构建:

> tspc

编译器 tspc 来自 ts-patch,允许 TypeScript 在构建过程中使用 plugins。现在你可以像这样运行构建文件:

> node dist/main.js

请注意,如果 "type": "module" 在 package.json 中,该策略将不起作用,所以您可能需要删除这一行:

"type": "module"

你可能还想在 tsconfig.json 中像这样使用 NodeNext:

"module": "NodeNext",
"moduleResolution": "NodeNext"

欲了解更多信息,我在我的 LinkedIn 页面上写了一篇关于 TypeScript 别名路径的文章,但您必须登录 LinkedIn 才能查看。

相关文章