Webpack resolve.alias does not work with typescript?

TypescriptWebpack

Typescript Problem Overview


I try to shorten my imports in typescript

from import {Hello} from "./components/Hello";

to import {Hello} from "Hello";

For that I found out you can use resolve.alias in webpack thus I configured that part as following

resolve: {
    root: path.resolve(__dirname),
    alias: {
        Hello: "src/components/Hello"
    },
    extensions: ["", ".ts", ".tsx", ".js"]
},

Webpack builds, and the output bundle.js works. However typescript's intellisense complain it cannot find the module

So my question is whether or not webpack's resolve.alias works with typescript?

I found following issue but there's no answer to it.

Typescript Solutions


Solution 1 - Typescript

If you're using ts-loader, you might have to synchronize your webpack alias/resolve settings with your paths setting in your tsconfig.json.

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

If you're using awesome-typescript-loader, then webpack can figure this out automatically from the paths setting in your tsconfig.json, as per the status on this issue from the repo. That way, you don't need to duplicate the same information in your Webpack alias field.

Solution 2 - Typescript

You are missing one very important point in tsconfig.json: The matching pattern!

It should be configured like this:

"baseUrl": ".",
"paths": {
    "appSrc/*": [
        "src/*"
    ]
 }

The "*" is the important part to tell TS to match anything on the right side.

I found that out from this article: Type-safe es2015 module import path aliasing with Webpack, Typescript and Jest

NOTE

  • Make sure all your webpack.config.js are updated (e.g. if you use storybook).
  • If you use Visual Studio Code you may need to restart it, in order for the squiggly lines to disappear.

Solution 3 - Typescript

As others have mentioned, you need to provide an alias in your webpack.config.js:

    resolve: { 
        
        extensions: [".ts", ".js"],
        alias: {
            forms: path.resolve(__dirname, "src/forms/")
        } 
    },

This needs to be in synch with your tsconfig.json file (baseUrl and paths are required).

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

Note: The wildcard pattern is necessary to match with your resolve alias configuration.

Then you can import any library using your alias:

import { FormsModule } from "forms/my-forms/my-forms.module";

Solution 4 - Typescript

If anyone still have this issue, don't forget to add your folder to the "include" option on tsconfig.json like this:

{
  "compilerOptions": {
    "sourceMap": true,
    "allowJs": true,
    "baseUrl": "./",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "lib": [
      "es2016",
      "dom"
    ]
  },
  "outDir": "./built/",
  "include": [
    "./src/**/*",
    "./tests/**/*"
  ]
}

Solution 5 - Typescript

I had to make a small adjustment to Caio Saldanha's solution to make it work in my environment.

I am using Babel 7 with babel-plugin-module-resolver to resolve aliases. No ts-loader or awesome-typescript-loader as Babel 7 supports TypeScript out of the box using @babel/preset-typescript. I had to add an extra path configuration for each alias to load the module root (e.g. index.ts) automagically:

"baseUrl": ".",
"paths": {  // this must be synchronized with .babelrc.js's module-resolver alias config
    "component": ["src/component/index.ts"],
    "component/*": ["src/component/*"],
    ...
}

Having an index.ts in the /component folder with the following content:

export { default as Logo } from './Logo';

Without the extra .../index.ts line this import didn't work for me:

import { Logo } from 'component';  

Alias config in .babelrc.js:

plugins: [
[
    'module-resolver',
    {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
        root: ['./src'],
        alias: {
        // this must be synchronized with tsconfig.json's path configuration
            component: './src/component',
        },
    },
],

Solution 6 - Typescript

You can also configure tsconfig-paths-webpack-plugin in order not to duplicate your aliases in several places. It will pick up aliases from tsconfig.json file and automatically add them to webpack.

Solution 7 - Typescript

There are 2 cases

  1. When you write custom webpack It works with typescript but not directly. To explain, there are 2 types of compilation happening in backstage. First tsx -> js for which tsconfig.json plays the role, but when you actually compile the js code then webpack comes into picture. So for aliases, resolve should be placed at both places i.e in tsconfig and webpack to successfully run the application
  2. when you use default(after create react app): You just need to add "baseUrl": "./src" in tsconfig and see the code work.

Solution 8 - Typescript

I think you can do this and have it work the way you describe:

resolve: {
    root: [
        path.resolve(__dirname),
        <path_to_components_directory> //e.g. path.resolve(__dirname, 'src', 'components')
    ], 
    extensions: ["", ".ts", ".tsx", ".js"]
},

Then you can do import {Hello} from "Hello";

I know I do this to resolve file paths in my src/js directory. I am not using typescript though, but I don't think it would affect the result.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionstarcornView Question on Stackoverflow
Solution 1 - TypescriptDaniel RosenwasserView Answer on Stackoverflow
Solution 2 - TypescriptCaio SaldanhaView Answer on Stackoverflow
Solution 3 - TypescriptpixelbitsView Answer on Stackoverflow
Solution 4 - TypescriptPatrick Stival ChaerkeView Answer on Stackoverflow
Solution 5 - TypescriptAMilassinView Answer on Stackoverflow
Solution 6 - TypescriptansavchencoView Answer on Stackoverflow
Solution 7 - TypescriptYash AgrawalView Answer on Stackoverflow
Solution 8 - TypescriptDimitris KaragiannisView Answer on Stackoverflow