Aliasing with Webpack 4 and Awesome-Typescript Loader Not Working

I'm currently having issue getting aliasing to work properly. From my understanding, to get aliasing to work properly with webpack you have to:

Versions

  "typescript": "2.8.3",
  "webpack": "4.16.2",
  "webpack-cli": "3.1.0",
  "awesome-typescript-loader": "5.2.0",
  "html-webpack-plugin": "3.2.0",
  "source-map-loader": "^0.2.3",
  1. define the alias in tsconfig as paths. I verified that my tsconfig and paths/aliasing is correct by building it. If it wasn't configured correctly, it would have failed the build.

Here is the sample file

Sample.tsx

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Footer from '@common/Footer';

export default class Sample{

    public static page(): void {
        ReactDOM.render(<Footer/>,
            document.getElementById('footer')
        );
    }
}

With webpack, it's configured to use awesome-typescript-loader. As I understand it, it leverages off the TsConfigPathsPlugin to examine the tsconfig for all the alias and then resolve it. So by the time it gets to webpack, the alias are already resolved. However, that isn't the case. In the bundle.js I would expect to not see any @common or any aliasing and that it would have been converted.

I also added tried to resolve the alias directly within webpack as well with the alias/aliasFields in the resolve. But still no luck.

webpack.js

 const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const webpack = require('webpack');
    const fs = require('fs');
    const TsConfigPathsPlugin = require('awesome-typescript-loader').TsConfigPathsPlugin;
    const ROOT_DIR = path.resolve(__dirname, ".","..");

    const config = {
        context: path.resolve(__dirname, '.',".."),
        mode: "development",
        resolve: {
            modules: [

            ],
            extensions: ['.ts', '.tsx', '.js', '.jsx'],
            plugins: [
                new TsConfigPathsPlugin({
                    configFileName: path.resolve(ROOT_DIR,'tsconfig.json')
                })
            ],
            aliasFields: ["@entry", "@common"],
            alias: {
                "@entry": "entry/",
                "@common": "common/"
            }
        },
        entry: {
            entryPoint: path.resolve(ROOT_DIR,'entry, 'index.tsx')
        },
        optimization: {
            minimize: false, // debugging purpose
            runtimeChunk: 'single',
            splitChunks: {
                cacheGroups: {
                    vendors: {
                        test: /[\\/]node_modules[\\/]/,
                        name: 'vendors',
                        chunks: 'all'
                    }
                }
            }
        },
        output: {
            filename: "[name]_bundle.js",
            path: path.join(ROOT_DIR, 'dist_w'),
        },

        // Enable sourcemaps for debugging webpack's output.
        devtool: "eval-source-map",

        resolve: {
            // Add '.ts' and '.tsx' as resolvable extensions.
            extensions: [".ts", ".tsx", ".js", ".json"]
        },

        module: {
            rules: [
                // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
                { test: /\.(ts|tsx)$/, loader: "awesome-typescript-loader" },

                // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
                { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
            ]
        },
        plugins: [
            //Generate index.html in /dist => 
            new HtmlWebpackPlugin({
                filename: 'index.html', //Name of file in ./dist/
                template:  path.resolve(ROOT_DIR,'entry-point', 'index.html'),
                hash: true,
            })
        ],
        stats: { //object
            assets: true,
            colors: true,
            errors: true,
            errorDetails: true,
            hash: true
            // ...
        }
    };

    module.exports = config;

The error message I get from web pack is:

Module not found: Error: Can't resolve '@common\Footer' in 'entry\src'
resolve '@common\Footer' in 'entry\src'
  Parsed request is a module
  using description file: <root>\package.json (relative path: ./entry/)
    Field 'browser' doesn't contain a valid alias configuration
    resolve as module
      entry\node_modules doesn't exist or is not a directory
      <root>\..\..\node_modules doesn't exist or is not a directory
      <root>\..\node_modules doesn't exist or is not a directory
      <root>\node_modules doesn't exist or is not a directory
      looking for modules in <root>\node_modules
        using description file: <root>\package.json (relative path: ./node_modules)
          Field 'browser' doesn't contain a valid alias configuration
      looking for modules in entry\node_modules
        using description file: <root>\package.json (relative path: ./entry-point/node_modules)
          Field 'browser' doesn't contain a valid alias configuration
          using description file: <root>\package.json (relative path: ./node_modules/@common//Footer)
            no extension
              Field 'browser' doesn't contain a valid alias configuration
          using description file: <root>\package.json (relative path: ./entry-point/node_modules/@common/Footer)
            no extension
              Field 'browser' doesn't contain a valid alias configuration
              <root>\node_modules\@common\Footer doesn't exist
            .ts
          …

Any advice appreciated, Thanks, D

2

2 Answers

This is what I used in one of my projects, you'll have to configure it in both tsconfig and webpack.config, but the values are different:

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

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

For those who came here looking for a simpler solution, please use tsconfig-webpack-plugin. This picks the config path directly from tsconfig.json and also obeys splat(*) operator in path aliases.

Sample webpack config using tsconfig-webpack-plugin will look like below:

  module.exports = {
    ...
    resolve: {
      plugins: [new TsconfigPathsPlugin({/* options: see below */})]
    }
    ...
  }

Please note unlike normal plugins, this should NOT be injected into root plugins, but rather into resolve.plugins options.

Post this config your path alias would work like expected 🙂

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Maya Lin-Takahashi

Maya Lin-Takahashi

Consumer Tech & Gadget Reviewer

Maya is a hardware enthusiast who tests and reviews smart home devices, smartphones, wearables, and audio gear. She focuses on practical consumer value and build quality.

Share this article
Twitter Facebook Pinterest