Aliasing with Webpack 4 and awesome-typescript loader not working
Asked Answered
O

2

14

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.

tsconfig.json

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 => https://github.com/ampedandwired/html-webpack-plugin
            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

Orms answered 1/8, 2018 at 1:25 Comment(2)
Your error messages indicate that it's only searching for modules inside a node_modules folder. The resolve.modules option defaults to [node_modules]. You might resolve the problem if you set the resolve.modules option to something like [path.resolve('./')]. Unsure about this though, so not adding this as an answer yet.Sanjuanitasank
i moved to ts-loader since I couldn't get it to work properly with the awesome-typescript loaderOrms
I
9

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/*"]
  },
Isotropic answered 15/10, 2018 at 23:16 Comment(0)
W
1

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 🙂

Witty answered 30/7, 2020 at 15:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.