Webpack resolve.alias does not work with typescript?
TypescriptWebpackTypescript 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
- 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
- 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.