typescript - TypeScript 路径映射“找不到模块 a-mapped/a”
问题描述
我有一个具有以下结构的项目:
┌ tsconfig.json
│ {
│ "compilerOptions": {
│ "baseUrl": ".",
│ "paths": { "a-mapped/*": ["a/*"] }
│ }
│ }
│
├ a
│ └─ a.ts
│ export const a = 1;
└ b
└─ b.ts
import { a } from "a-mapped/a";
export const b = a + 1;
当我运行tsc
时,结果b.js
包含:
var a_1 = require("a-mapped/a");
exports.b = a_1.a + 1;
如果我尝试使用 运行它node
,我会收到错误“找不到模块a-mapped/a
”。
我希望tsc
从 生成导入../a/a
,而不是a-mapped/a
. 我错过了什么或做错了什么?
解决方案
不久前我自己也遇到了这个问题。有趣的是,typescript 将理解路径映射,但通过设计将它们保持在已编译的 javascript 中。
编译器不会重写模块名称。模块名称被视为资源标识符,并在源中出现时映射到输出
您编写的模块名称不会在输出中更改。“paths”和“baseURL”是用来告诉编译器它们在运行时的位置。 https://github.com/Microsoft/TypeScript/issues/9910#issuecomment-234729007
有几种方法可以解决这个问题。
ts节点
您可以使用 ts-node 代替 node 来运行您的项目。
优点:
- 易于使用,没有麻烦。
缺点:
- 您可能无法做到这一点,例如,如果您正在编写浏览器代码、库或不控制运行时环境。
- 性能可能是一个问题,尤其是启动时间。
变压器
或者,您可以使用typescript 转换器使编译器输出正确的 javascript 文件(例如@zerollup/ts-transform-paths和ttypescript)。
优点:
- 更快的编译时间,可以
ttsc --watch
可靠地使用。
注意:我已经测试过这个设置,并且在使用
--watch
.
缺点:
- 至少现在,您需要使用像 ttypescript 这样的 typescript 包装器。
- 设置起来有点困难。
工具
最后,您可以使用一个工具来修复您生成的 javascript 中的路径(ts-module-alias、module-alias、ef-tspm)。
优点:
- 使用纯正的打字稿。
- 易于设置(只需在编译后运行该工具!)
缺点:
- 可能会导致编译时间变慢。
- 手表操作更难设置。
我最终使用 ef-tspm 来修复文件,它通常可以工作,尽管我对构建时间并不完全满意,并且可能值得探索转换器和 ttypescript。如果有帮助,我创建了一个带有路径别名设置的打字稿/节点项目。
推荐阅读
- graphql - 将没有 ID 字段的表用于 GraphQL 服务器进行中继
- tarantool - tarantool Java 连接器和空间 ID
- c# - 如何从 WPF 应用程序提供 RESTful Web 服务?
- struts2 - 如果在相应的操作执行期间发生任何异常,如何防止拦截器在操作后调用
- cloud-foundry - 从托管的 Cloud Foundry 应用程序创建 Cloud Foundry 服务
- php - 如何结合名字和姓氏,然后在奏鸣曲管理中用全名列显示
- java - 如何从 web 表中读取空单元格
- php - 如何测试自定义 DQL 功能?
- c++ - 如何使用 emplace 在 C++ 中添加地图?
- ios - Xcode 模拟器替代方案