为什么这些tsconfig路径不起作用?

113

我试图做与文档中jquery路径示例非常相似的事情,但TypeScript一直报错TS2307(webpack编译正常):

"compilerOptions": {
    "baseUrl": "./src",
    "paths": {
        "@client": [
            "client",
        ],
        "@suir": [
            "../node_modules/semantic-ui-react/dist/commonjs", // not working
        ],
    },
    // …
},
"include": [
    "*.d.ts",
    "client/**/*",
    "../node_modules/semantic-ui-react", // is this necessary?
],
改变 baseUrl"." 并更新 includespaths 不会有任何影响(@client 继续工作,@suir 仍然无法工作)。
"@suir" 改为 "@suir/""@suir/*" (并在其值后添加 /*)也没有任何影响。
我这么做的原因是为了简化我的导入(我正在明确指定它们,而不是从包中拉出命名的导出,以减少我的供应商捆绑包大小 - 节省约1 MB)。
import Button from 'semantic-ui-react/dist/commonjs/elements/Button'; // works

import Button from '@suir/elements/Button'; // not found

只是想补充一下。对我来说,当我在tsconfig.json中使用files属性时,paths就不起作用了。有什么解决办法吗? - Yashas
24个回答

115

我不知道为什么这第十一次尝试才成功了(前十次都没有),但是/*似乎是关键,文档中的示例显然指向一个特定的文件(并且省略了文件扩展名)。

{
    "compilerOptions": {
        "baseUrl": "./src", // setting a value for baseUrl is required
        "moduleResolution": "node", // was not set before, but is the default
        "paths": {
            "@client/*": [
                "client/*",
            ],
            "@suir/*": [ // notice the `/*` at the end
                "../node_modules/semantic-ui-react/dist/commonjs/*", // notice the `/*`
            ],
        },
        // …
    },
    "include": [
        "./src/client/**/*",
    ],
}

60
对于仍然在遇到问题的其他人,即使有 /* ,请确保您的 baseUrl 已设置,因为我刚刚花了数小时来解决这个问题。 - ErraticFox
1
请编辑此帖并添加@ErraticFox关于baseUrl的内容。谢谢! - Ionel Lupu
110
如果有人在使用VSCode时遇到了无法使/*解决方案起作用的问题,请尝试使用Cmd+Shift+P > Typescript: Restart TS Server。 - Emily Zhai
3
@ErraticFox仍然无法使用基本URL为"./"。 - Yousaf Raza
谢谢@EmilyZhai,这对我很有帮助! - Fabienne P
显示剩余3条评论

83

正如 Emily Zhai 在评论中提到的那样,有时候这只需要重新启动语言服务器。

在VSCode中,您可以按下 Cmd/Ctrl + Shift + P 并搜索 Typescript: Restart TS Server

重启后,一切都开始正常工作了。


6
请注意,您可能需要在.ts文件中才能看到该选项。(我必须聚焦于一个.ts文件。) - James
1
重启Webstorm对我有用 - 谢谢! - Scott
1
非常感谢!!没有这个答案,我不知道还要花多少时间在网上解决这个问题! - DarkCrazy
@DarkCrazy :) 它已经咬了我多次。浪费了那么多时间,只是因为一个简单的重启。 - Mitch Talmadge
1
TypeScript:重启 TS 服务器 - Whichmann

74

我也遇到了一个问题,.tsconfig没有识别我的别名(而在另一个应该有相同配置的项目中,它完美地工作了)。

事实证明,这是一个新手错误:我把paths属性放在了JSON对象的末尾,但它必须是compilerOptions部分的嵌套属性:

// This does't work ❌
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
     //...
    "baseUrl": ".",
  },
  "include": ["next-env.d.ts", "twin.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"],
  "paths": {
      "@components/*": ["components/*"],
      "@lib/*": ["lib/*"]
    }
}

// This should work ✅
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
     //...
    "baseUrl": ".",
    "paths": {
      "@components/*": ["components/*"],
      "@lib/*": ["lib/*"]
    }
  },
  "include": ["next-env.d.ts", "twin.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"],
}

12
哇!你真是个救命恩人!我为了这个小错误竟然浪费了两天时间! - shamaseen
很高兴能够帮忙。我认为这相当违反直觉,因为“include”和“exclude”(它们也是相对路径)被放置在对象根目录中。 - HynekS
3
天啊,我已经找了3个小时了,我都快疯了。 - Luka Samkharadze
1
这个与 /* 魔法结合起来,对于 ALIAS ( @components /* )本身和路径的末尾都要加上,这样就可以让事情正常工作了,除了图片 - 对于那些我不得不添加自定义类型文件,如此描述 - https://dev59.com/W1MI5IYBdhLWcg3wFXSg#57129153 基本上你需要在项目根目录下创建一个特殊的文件 typings/custom/import-yourextension.d.ts - jave.web
谢谢,对我有用。 - Fahd Allebdi
显示剩余5条评论

39

默认情况下,它不能与tsc或ts-node一起使用。但是通过一些软件包(tsc-alias&module-alias),它可以工作。不需要babel或webpack设置。

// tsconfig.json

{
  "compilerOptions": {
    ...
    "baseUrl": "./src",
    "paths": {
      "@common/*": ["common/*"],
      "@services/*": ["services/*"],
    },
    ...
  },
}

使用TSC

tsc-aliashttps://www.npmjs.com/package/tsc-alias)添加为开发依赖项。

yarn add --dev tsc-alias

将其添加到您的构建命令中

"build": "tsc && tsc-alias",

使用TS-NODE

添加module-alias (https://www.npmjs.com/package/module-alias) 依赖项。

yarn add module-alias

创建一个引用所有别名的文件。
// src/paths.ts

import 'module-alias/register';
import { addAliases } from 'module-alias';

addAliases({
  '@common': `${__dirname}/common`,
  '@services': `${__dirname}/services`,
});

将它作为第一个导入项导入到您的入口脚本中

// src/server.ts

import './paths';
import express, { Request, Response, NextFunction } from 'express';
...

const app = express();
...
app.listen(port, onListen(port));

仅提及,对于 module-alias 可能需要安装类型:npm i --save-dev @types/module-alias - eXception
3
哇!我本以为tsc可以直接使用!谢谢您的澄清。 - Steve Moretz
node start之前,您还可以添加NODE_PATH=outDir - Claus Jørgensen
非常感谢。我差点要把头发都拔光了。 - AlePouroullis
谢谢!这个答案需要被顶高一些! - seth

34
这可能会对某些人有所帮助 - 如果您使用tsc或其他工具将TS代码编译到单独的文件夹中,例如dist,则tsconfig-paths注册表默认无法正常工作。我的tsconfig.json如下:
{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "lib": ["dom", "esnext"],
        "baseUrl": ".",
        "jsx": "react",
        "removeComments": true,
        "sourceMap": true,
        "outDir": "dist"
        "rootDir": ".",
        "paths": {
            "shared/*": ["./shared/*"],
        }
    },
    "include": ["./client/**/*", "./server/**/*"]
}

你可以看到这样的路径 shared/someFolder/someScript 会正确解析到我的项目中的 shared 文件夹,这比很多相对路径 ../../../../ 更加简洁明了。
然而,这给我抛出了错误:
  game git:(game-dev)  node --inspect -r tsconfig-paths/register dist/server/runProd.js
Debugger listening on ws://127.0.0.1:9229/f69956aa-d8d6-4f39-8be1-9c3e8383d4be
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
internal/modules/cjs/loader.js:584
    throw err;
    ^

Error: Cannot find module 'shared/types/UserTypes'

我进行了一些调查,发现由tsconfig-paths生成的tryPaths数组具有相对于project/cwd基础的绝对URL,而不是构建dist文件夹。{{p}}

inspect screengrab

回过头来看,这似乎是显而易见的。在库中似乎没有明显的处理方法,因此我通过将tsconfig.json复制到dist文件夹中并运行node -r tsconfig-paths/register main.js来解决了这个问题。


2
很好的解释!相关的Github问题:https://github.com/dividab/tsconfig-paths/issues/75 - MegaCookie

10

经过一些尝试和错误,我知道它的工作方式与我们所想的不同。

//tsconfig.json
"baseUrl": ".",
"paths": {
  "@components/": ["src/components/"],
}

//SomeCompomonent.tsx
import { Button } from "@components/" // will work
import Button from "@components/Button" // will not work

为了让第二个导入行正常工作,您需要加上*
//tsconfig.json
"baseUrl": ".",
"paths": {
  "@components/*": ["src/components/*"],
}

//SomeCompomonent.tsx
import { Button } from "@components/" // will not work
import Button from "@components/Button" // will work

为了使两者兼容。
//tsconfig.json
"baseUrl": ".",
"paths": {
  "@components/": ["src/components/"],
  "@components/*": ["src/components/*"],
}

//SomeCompomonent.tsx
import { Button } from "@components/" // will work
import Button from "@components/Button" // will work

1
谢谢!这对我有用,因为我使用了命名导入:D - Ezequiel Guitler
这帮了大忙啊!谢谢! - undefined

9

就像pkestikar所说的那样,tsconfig-paths-webpack-plugin 可以帮助你解决这个问题。使用 yarn add --dev tsconfig-paths-webpack-plugin 将其保存在 devDependencies 中,在 next.config.js 中添加以下配置:

const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')

module.exports = {
  resolve: {
    plugins: [new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })]
  }
}

我的路径开始生效了。这是我的tsconfig.json文件:

"compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@components/*": ["components/*"]
    },
}

下面是组件的引入方式。

import { Button } from '@/components/Button/Button'

仅使用 import { Button } from 'components/Button/Button' 也可以正常工作。


7
如果你正在使用 Vite,应该安装vite-tsconfig-paths
npm i vite-tsconfig-paths --save-dev

然后,在vite.config.ts模块中使用vite-tsconfig-paths进行注入。
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
  plugins: [tsconfigPaths()],
})

您可能需要在进行这些更改后重新启动 Vite 和/或您的 TS 服务器。

如果这不起作用,请查看 https://dev59.com/XsTra4cB1Zd3GeqP6Wjb#74719153。`v4.0.0`存在一个错误。`v4.0.1`修复了它。使用`npm install vite-tsconfig-paths@latest`进行安装。 - Mohamed Allal
在上述的所有解决方案中,这个是对我在Vite上起作用的一个。 - undefined

5
如果有人即使做了以上所有步骤仍然存在这个问题,尝试关闭VS Code并重新打开,这对我而言在搜索了2个小时后起作用了。

我之前已经让它工作了,多次重新加载都不行。只有完全关闭并重新打开才可以! - ps2goat

4
即使设置了基本URL,也要检查它是否设置为默认值“./”,如果是,则应将其更改为“src”,只有这种方式对我有效。

奇怪,但它有效。我可以确认这一点。这个建议为我节省了很多时间。 - AndreyTalanin

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