Webpack 2 Module Resolution with Typescript rootDirs

1k Views Asked by At

For the following directory structure:

..src/frontend/...
..src/frontend/src/...
..src/frontend/config/webpack.common.js
..src/shared/src/models/User.ts

I've got my Typescript setup using rootDirs. This is quite handy because I can have a shared folder for front- and back-end.

This allows me to rewrite an long ugly import statement

import {User} from "../../../shared/src/models/User";

to this

import {User} from "../models/User";

This works well and my TypeScript service is happy and able to resolve all modules etc. The problem comes in with Webpack.

It doesn't seem to look at the tsconfig file for module resolution. So going to the Webpack 2 documentation. I found the following for resolve.modules.

Tell webpack what directories should be searched when resolving modules.

Absolute and relative paths can both be used, but be aware that they will behave a bit differently.

I have tried configuring the modules :

 modules: [helpers.root('src'), helpers.root('node_modules') , helpers.root( '../shared/src')]

This allows me to use an import statement:

 import {User} from "models/User"; //Note the missing ../

But now TypeScript doesn't know what type it is any longer, since it breaks away from the rootDirs config. Ideally I would want Webpack and Typescript to be in sync. If I use the long relative import path then webpack and typescript are both happy.

See my gist of my config files.

Error I get when using '../models/User'

ERROR in ./src/app/environment.ts Module not found: Error: Can't resolve '../models/User' in '.../src/frontend/src/app' @ ./src/app/environment.ts 4:0-38 @ ./src/main.browser.ts

1

There are 1 best solutions below

1
On

You can use "alias" property in webpack and "paths" property in tsconfig.json.

in tsconfig.json:

{
  "compilerOptions": {
     ....
     "baseUrl": ".",
     "paths": {
       "shared/*": "src/shared/src/*"
     }
  }
}

in webpack.config.js:

module.exports = {
  ...
  resolve: {
    ...
    alias: {
        "shared": path.resolve(__dirname, 'src/shared/src')
    }
  }
}

in your .ts file you can import like so:

import {User} from "shared/models/User";