使用 baseUrl 导入模块时如何让 tsc 解析绝对路径?
How to get tsc to Resolve Absolute Paths when Importing Modules using baseUrl?
考虑一个具有以下目录结构的简单打字稿项目:
| 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'
如果我的理解是正确的,打字稿编译器在编译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
时,我们会发现路径没有被正确解析,如果我们要这样做,这会给我们一个 Cannot find module 错误运行它。
"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
的目的是什么?
问题是你的模块加载器不知道如何找到给定绝对路径的模块 foobar/Foo
。
TypeScript 编译器 (tsc) 正在正确解析模块路径,否则您会遇到编译错误。但它相信你会适当地配置你的模块加载器。
例如,来自 documentation for RequireJS:
Supported configuration options:
baseUrl: the root path to use for all module lookups.
TypeScript documentation 稍微解释了为什么您可能需要 baseUrl
:
Using a baseUrl is a common practice in applications using AMD module loaders where modules are “deployed” to a single folder at run-time. The sources of these modules can live in different directories, but a build script will put them all together.
tsc
无法将路径转换为相对路径,尽管您配置了 baseUrl
和 paths
,paths
仅在您在编辑器中编码以检查代码时有用。
如果你想让它工作,你可以使用 ts-node 和 tsconfig-paths 模块:
$ yarn add ts-node tsconfig-paths --dev
和运行这个脚本
"start": "ts-node -r tsconfig-paths/register app.ts"
然后你就可以得到正确的表现。
答案来自@DenisPshenov 在其中一个答案中的评论。它被埋没了,所以我会在这里提供...
使用 NODE_PATH
环境变量告诉 Node 基础 url 在哪里,以便它可以解析绝对路径:
Linux / macOS
NODE_PATH=dist/ node ./dist/index.js
Windows Powershell
$env:NODE_PATH="dist/"
node ./dist/index.js
您可以使用 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.
考虑一个具有以下目录结构的简单打字稿项目:
| 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'
如果我的理解是正确的,打字稿编译器在编译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
时,我们会发现路径没有被正确解析,如果我们要这样做,这会给我们一个 Cannot find module 错误运行它。
"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
的目的是什么?
问题是你的模块加载器不知道如何找到给定绝对路径的模块 foobar/Foo
。
TypeScript 编译器 (tsc) 正在正确解析模块路径,否则您会遇到编译错误。但它相信你会适当地配置你的模块加载器。
例如,来自 documentation for RequireJS:
Supported configuration options:
baseUrl: the root path to use for all module lookups.
TypeScript documentation 稍微解释了为什么您可能需要 baseUrl
:
Using a baseUrl is a common practice in applications using AMD module loaders where modules are “deployed” to a single folder at run-time. The sources of these modules can live in different directories, but a build script will put them all together.
tsc
无法将路径转换为相对路径,尽管您配置了 baseUrl
和 paths
,paths
仅在您在编辑器中编码以检查代码时有用。
如果你想让它工作,你可以使用 ts-node 和 tsconfig-paths 模块:
$ yarn add ts-node tsconfig-paths --dev
和运行这个脚本
"start": "ts-node -r tsconfig-paths/register app.ts"
然后你就可以得到正确的表现。
答案来自@DenisPshenov 在其中一个答案中的评论。它被埋没了,所以我会在这里提供...
使用 NODE_PATH
环境变量告诉 Node 基础 url 在哪里,以便它可以解析绝对路径:
Linux / macOS
NODE_PATH=dist/ node ./dist/index.js
Windows Powershell
$env:NODE_PATH="dist/"
node ./dist/index.js
您可以使用 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.