Jakob Jingleheimer
Jakob Jingleheimer

Reputation: 31590

Why are these tsconfig paths not working?

I'm trying to do something very similar to the jquery path example in the documentation, but TS keeps throwing TS2307 (webpack compiles fine):

"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?
],

Changing baseUrl to "." and updating includes and paths makes no difference (@client continues to work and @suir continues to not work).

Changing "@suir" to "@suir/" or "@suir/*" (and appending /* to its value) also makes no difference.


The reason I'm doing this is to simplify my imports (I'm specifying them explicitly instead of pulling named exports from the bundle in order to reduce my vendor bundle size—saves about 1 MB):

import Button from 'semantic-ui-react/dist/commonjs/elements/Button'; // works

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

Upvotes: 130

Views: 234222

Answers (25)

dgzornoza
dgzornoza

Reputation: 658

Make sure that there is no 'tsconfig.app.json', 'tsconfig.spec.json' file that is overwriting the 'paths' property

Upvotes: 0

HynekS
HynekS

Reputation: 3317

I did also struggle with .tsconfig not recognizing my aliases (while in another project that supposed to have the save config it worked perfectly).

As it turned out, it was a rookie mistake: I put the paths prop to the end of the JSON object, but it has to be a nested property of the compilerOptions part:

// This does't work ❌
{
  "compilerOptions": {
     //...
    "baseUrl": ".",
  },
  //...
  "paths": {
      "@components/*": ["components/*"],
      "@lib/*": ["lib/*"]
    }
}
// This should work ✅
{
  "compilerOptions": {
     //...
    "baseUrl": ".",
    "paths": {
      "@components/*": ["components/*"],
      "@lib/*": ["lib/*"]
    }
  },
  //...
}

Upvotes: 94

Kik Dim
Kik Dim

Reputation: 1

In case this helps somebody else:

I had "skipLibCheck": true in my tsconfig.json file which prevented the imported library files from an upstream project to compile properly and read the paths {} object in my tsconfig.json.

Upvotes: 0

aztack
aztack

Reputation: 4594

In my case, even though I set baseUrl in the parent config, I had to set baseUrl again in the derived config to make VSCode happy and successfully resolve the configured paths enter image description here

Upvotes: 6

George Suntres
George Suntres

Reputation: 141

While trying to make tsconfig work, the following command proved very helpful:

npx tsc --showConfig

This will output some json with the files field showing the actual recognized files by your configuration.

Upvotes: 9

Aurasphere
Aurasphere

Reputation: 4011

If you have Javascript files, also check that in your tsconfig.json you have

 "allowJs": true

otherwise TypeScript will ignore .js and .jsx files imports

Upvotes: 1

pradeexsu
pradeexsu

Reputation: 1145

for parcel with react add compilerOptions.paths and add parcel-resolver-tspaths to resolvers for .parcelrc(create if not present) file. or checkout Offical: https://parceljs.org/plugin-browser/?type=%22resolver%22&page=0&filter=%22resolver-path%22&includeOfficial=true

npm install --save-dev parcel-resolver-tspaths

package.json

{
  "compilerOptions": {
    "paths": {
      "@app/*": ["./src/app/*"],
      "@utils/*": ["./src/utils/*"]
    },
  }
  ...
}

.parcelrc

{
  "extends": "@parcel/config-default",
  "resolvers": [
    "...",
    "parcel-resolver-tspaths"
  ],
  ...
}

Upvotes: 0

Gon82
Gon82

Reputation: 509

Check your workspace

Check how you have opened your workspace in VScode.

In my case, I have this structure:

├── my-proyect
│   ├── client* (this is my react folder)
│   └── server

To make it work, I have o open the client folder. If I open the whole project it doesn't work.

Other things to check:

  1. tsconfig.json should be something like this
{
  "compilerOptions": {
   ...
    "baseUrl": "./src",
    "paths": {
      "~/*": ["./*"],
    }
  },
}
  1. vite.config.ts should be something like this (if you use vite)
import react from '@vitejs/plugin-react'
import path from 'path'
import { defineConfig } from 'vite'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '~': path.resolve(__dirname, 'src'),
    },
  },
})

Restart TS Server.

In VSCode, you can press **Cmd/Ctrl + Shift + P** and search for Typescript: 

Upvotes: 1

Neo Tan
Neo Tan

Reputation: 301

On top of Emily Zhai's comment, if someone wants to Restart TypeScript/ESLint Servers Automatically when configs changed on VS Code, my extension may help

Auto Restart TypeScript / ESLint Servers - Visual Studio Marketplace

Upvotes: 0

bhushan217
bhushan217

Reputation: 16

I will recommend, do not change tsconfig.json rather create tconfig.app.json and add following content If already exists then simply add paths, you can reuse your shortPath

Note: its json file so check comma (,) and don't miss or keep extras like in *.ts files


{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [],
    "paths": {
      "@app/*": ["src/app/*"],
      "@chat/*": ["@app/chat/*"],
      "@shared/*": ["@app/shared/*"],
      "@auth/*": ["@app/auth/*"]
    }
  },
  "files": [
    "src/main.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

Upvotes: 0

Ummer Zaman
Ummer Zaman

Reputation: 364

Make sure the path provided is correct. It will throw error "module and its decrations not found".

Upvotes: -2

Try add in tsConfig.json the follow property inside CompileOptions:

"baseUrl": "."

In my case working.

Upvotes: 1

sebtheiler
sebtheiler

Reputation: 2557

If you are using Vite, you should install vite-tsconfig-paths.

npm i vite-tsconfig-paths --save-dev

Then, inject vite-tsconfig-paths using the vite.config.ts module

import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'

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

You may need to restart Vite and/or your TS server after making these changes.

Upvotes: 14

Dhiraj Arun
Dhiraj Arun

Reputation: 121

After some trial and error, I got to know that, it works differently than we think.

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

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

to make the second import line work you need to put *

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

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

To make both 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

Upvotes: 12

Naser Nikzad
Naser Nikzad

Reputation: 951

In my case the issue was that I was adding path to the wrong file. If you are working on a big project where you are not sure of it's configurations, chances are that the config file be extended by other files. In my project there was another file called tsconfig.app.json, notice the extend attribute in the very first row:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "paths": {
      "@angular/*": [
        "../node_modules/@angular/*",
      ],
      "@app/*": ["app/*"]
    }
}

Upvotes: 1

Jamie Hutber
Jamie Hutber

Reputation: 28106

For myself, after much trial and error the solution was simple. Remove this line from my tsconfig and it worked.

"extends": [
    "plugin:import/recommended",
]

and

"rules": {
    "import/no-unresolved": "error",,
}

Upvotes: -4

Tobbin2
Tobbin2

Reputation: 105

If someone still has this issue even after doing everything mentioned. Try close down VS code and reopen again, that worked for me 2 hours after looking around..

Upvotes: 4

VyTor BrB
VyTor BrB

Reputation: 111

I had to use babel to compile the code

npm i -D @babel/cli @babel/core @babel/node @babel/preset-env @babel/preset-typescript babel-plugin-module-resolver

Then on the build command

"build": "babel src --extensions \".js,.ts\" --out-dir dist --copy-files --no-copy-ignored"

And the babel.config.js

module.exports = {
presets: [
    [
        '@babel/preset-env',
        {
            targets: {
                node: 'current'
            }
        }
    ],
    '@babel/preset-typescript'
],
plugins: [
    ['module-resolver', {
        alias: {
            '@config': './src/config',
            '@modules': './src/modules',
            '@shared': './src/shared'
        }
    }]
],
ignore: [
    '**/*.spec.ts'
]

}

Upvotes: 0

Cam CHN
Cam CHN

Reputation: 3716

Out of the box, it doesn't work with tsc or ts-node. But with some packages (tsc-alias & module-alias), it works. No babel or webpack setup are required.

// tsconfig.json

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

Working with TSC

Add tsc-alias (https://www.npmjs.com/package/tsc-alias) as dev dependency

yarn add --dev tsc-alias

And add it to your build command

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

Working with TS-NODE

Add module-alias (https://www.npmjs.com/package/module-alias) dependency

yarn add module-alias

Create a file referencing all aliases

// src/paths.ts

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

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

And import it in your entry script as first import

// src/server.ts

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

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

Upvotes: 49

Matheus Bolognini
Matheus Bolognini

Reputation: 91

Like, pkestikar said, tsconfig-paths-webpack-plugin can help with that. Save it on devDependencies with yarn add --dev tsconfig-paths-webpack-plugin , add the following configuration on next.config.js

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

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

My paths started to work with that. Here's my tsconfig.json

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

And here is the import of a component.

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

It works with just import { Button } from 'components/Button/Button' as well.

Upvotes: 9

pkestikar
pkestikar

Reputation: 21

If you are using Webpack with ts-loader and it's still not working after trying all of the answers above, you might need to use a plugin in the resolve section of your Webpack config file - tsconfig-paths-webpack-plugin; so it follows the paths you've put in in your tsconfig.json file while compiling.

Source - https://github.com/TypeStrong/ts-loader#baseurl--paths-module-resolution

Upvotes: 2

Mitch Talmadge
Mitch Talmadge

Reputation: 4755

As mentioned in the comments by Emily Zhai, this can sometimes just require a language server restart.

In VSCode, you can press Cmd/Ctrl + Shift + P and search for Typescript: Restart TS Server.

After restarting, everything started working for me.

Upvotes: 86

Poly Hamza
Poly Hamza

Reputation: 159

Even if the base url is set check if it's on the default value "./" then should be changed to "src", only that way worked for me.

Upvotes: 4

Jakob Jingleheimer
Jakob Jingleheimer

Reputation: 31590

I have no idea why this is now working on the eleventh time I tried (yet didn't the first 10), but the /* seems to be the secret sauce, and the example in the docs is apparently pointing to a specific file (and the file extension is omitted).

{
    "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/**/*",
    ],
}

Upvotes: 134

Hugheth
Hugheth

Reputation: 1922

This might help someone - if you use tsc or a tool to compile your TS code to a separate folder such as dist, tsconfig-paths register does NOT work out the box. I have a tsconfig.json like this:

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "lib": ["dom", "esnext"],
        "baseUrl": ".",
        "jsx": "react",
        "removeComments": true,
        "sourceMap": true,
        "outDir": "dist"
        "rootDir": ".",
        "paths": {
            "shared/*": ["./shared/*"],
        }
    },
    "include": ["./client/**/*", "./server/**/*"]
}

You can see that a path such as shared/someFolder/someScript will resolve correctly to the shared folder in my project, which is a load cleaner than lots of relative ../../../../ paths.

However, this was throwing me the error:

➜  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'

I did a bit of digging and found that the tryPaths array produced by tsconfig-paths has absolute URLs relative to the project/cwd base, rather than the build dist folder.

inspect screengrab

This seems obvious in retrospect. There doesn't seem to be an obvious way to handle this with the library, so I have solved this by copying the tsconfig.json into the dist folder and running node -r tsconfig-paths/register main.js.

Upvotes: 36

Related Questions