Leverage Webpack to bundle ES Modules with TypeScript module aliases

Hello there, I recently created an npm module using Typescript and ES-modules.

Inside the /source folder, you can find my tsconfig.json file which includes a path alias.

{
    "compilerOptions": {
        "moduleResolution": "Node16",
        "module": "Node16",
        "target": "ES2015",
        "lib": [
            "ES2022"
        ],
        "resolveJsonModule": true,
        "strictNullChecks": true,
        "sourceMap": true,
        "declaration": false,
        "downlevelIteration": true,
        "skipDefaultLibCheck": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "baseUrl": ".",
        "paths": {
            "@/*": [
                "./source/*"
            ],
            "@": [
                "./source"
            ],
            "@src/*": [
                "./source/*"
            ],
            "@src": [
                "./source"
            ],
            "@test/*": [
                "./test/*"
            ],
            "@test": [
                "./test"
            ]
        },
        "outDir": "./dist"
    },
    "include": [
        "source",
        "test"
    ]
}

In the root directory /, you will find my esmodule webpack.config.mjs.

import { fileURLToPath } from 'node:url';
import path from 'node:path';

import nodeExternals from 'webpack-node-externals';
import BundleDeclarationsWebpackPlugin from 'bundle-declarations-webpack-plugin';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
import ResolveTypescriptPlugin from 'resolve-typescript-plugin';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(fileURLToPath(import.meta.url));

export default {
    target: 'node',
    mode: 'production',
    // devtool: 'source-map',
    // experiments: {
    //     outputModule: true
    // },
    entry: {
        index: './source/index.ts',
    },
    resolve: {
        fullySpecified: true,
        extensions: ['.ts', '.js'],
        plugins: [new TsconfigPathsPlugin({
            configFile: './source/tsconfig.json',
            extensions: ['.ts', '.js']
        }), new ResolveTypescriptPlugin()]
    },
    module: {
        rules: [
            {
                test: /\.ts?$/,
                include: path.resolve(__dirname, 'source'),
                use: [
                    {
                        loader: 'ts-loader'
                    }
                ]
            }
        ]
    },
    plugins: [
        new BundleDeclarationsWebpackPlugin({
            entry: "./source/index.ts",
            outFile: "./index.d.ts"
        })
    ],
    externals: [nodeExternals()],
    output: {
        path: path.resolve(__dirname, './bundled'),
        filename: 'index.js',
        chunkFormat: 'module'
    }
}

I am facing issues because of the path aliases (@/xxx/yyy) as shown below:

assets by status 9.18 KiB [cached] 22 assets
./source/index.ts 433 bytes [built] [code generated]

ERROR in ./source/index.ts 1:0-363
Module not found: Error: Can't resolve '@/modules/index.js' in '/home/euber/Github/lifeware-java-mangler/source'

ERROR in ./source/index.ts 2:0-34
Module not found: Error: Can't resolve '@/errors/index.js' in '/home/euber/Github/lifeware-java-mangler/source'

ERROR in ./source/index.ts 3:0-33
Module not found: Error: Can't resolve '@/types/index.js' in '/home/euber/Github/lifeware-java-mangler/source'

3 errors have detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.

webpack 5.73.0 compiled with 3 errors in 8500 ms

Even with the usage of TsconfigPathsPlugin, the problem persists when working with esmodules.

You can access the branch module-alias of this repository here

EDIT: After investigating further, the error seems to stem from using tsconfig-paths-webpack plugin with the specific extension .js. Refer to this log screenshot I created after adding some debug statements inside the plugin:

https://i.sstatic.net/BCIox.png

Answer №1

This issue appears to be related to webpack, but it has already been fixed in the most recent release version 5.74.0 (for more information, you can check out this link https://github.com/webpack/webpack/issues/13252). To resolve this issue, make sure to update your webpack to the latest version 5.74.0 and include the following code snippet in your webpack configuration file:

  resolve: {
    extensionAlias: {
      '.js': ['.ts', '.js'],
      '.mjs': ['.mts', '.mjs']
    }
  },

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The template is displaying the string as "[object Object]"

I've implemented code in my ngOnInit function to fetch the translation for a specific text. The following function is being called: async getEmailTranslation() { const email$ = this.translate.get('SUPPORT_TRANSLATE.EMAIL'); this.emai ...

Tips for leveraging stage 3 functionalities in TypeScript?

Array.prototype.at() is currently in the proposal stage 3. Even after adding "lib": ["ESNext"] to my tsconfig.json, I encountered the error: Property 'at' does not exist on type 'number[]'. Could you shed some light ...

Guide on incorporating Kendo UI typings into a TypeScript module

Currently, I am working with Kendo UI for React and TypeScript. My goal is to import the Kendo UI typings for TypeScript using a "typeof import". Following the guidance provided at https://docs.telerik.com/kendo-ui/third-party/typescript, I successfully i ...

Utilizing TypeScript to define React interfaces

How can I effectively utilize two interfaces for the same object? For instance: interface interfaceOne { id: string color: string } interface interfaceTwo { id: string numb: number } I have an Item component that is designed to receive an item ob ...

Unable to locate dependencies while testing the react package locally

Recently, I came across this npm package designed for React using Typescript. To debug it locally, I initiated npm link in a new React project but encountered an error: https://i.sstatic.net/nObH6.png I suspect it may not be reading the packages correct ...

Guide on transforming a tuple of random types into a nested type structure with the help of recursive conditional types

When I responded to the query on whether Typescript Interfaces can express co-occurrence constraints for properties, I shared the following code snippet: type None<T> = {[K in keyof T]?: never} type EitherOrBoth<T1, T2> = T1 & None<T2&g ...

How can an array be generated functionally using properties from an array of objects?

Here's the current implementation that is functioning as expected: let newList: any[] = []; for (let stuff of this.Stuff) { newList = newList.concat(stuff.food); } The "Stuff" array consists of objects where each ...

rxjs subscriptions in Angular

When setting up a subscription in Angular, I am declaring it as follows: counterSubscription: Subscription However, an error is being thrown stating: Property 'counterSubscription' has no initializer and is not definitely assigned in the const ...

Utilizing TypeScript for various return types with the same parameters

Exploring TypeScript Signatures In an effort to embrace TypeScript fully, I am implementing strongly typed signatures in my Components and Services, including custom validation functions for angular2 forms. I have discovered that while function overloadi ...

Input values that are true, or in other words, fulfill conditions for truthiness

Is there a specific data type in TypeScript to represent truthy values? Here's the method I'm working with: Object.keys(lck.lockholders).length; enqueue(k: any, obj?: any): void It seems like TypeScript allows checking for empty strings &ap ...

Utilize string generic limitations as dynamically generated key

I am looking to create a type that can accept a string value as a generic argument and use it to define a key on the type. For example: const foo: MyType<'hello'> = { hello: "Goodbye", // this key is required bar: 2 } I attempted to ...

Exploring the Relationship Between Redux and ImmutableJS in Managing Nested State and Understanding the Computational Complexity of Immutable

Trying to grasp the concept of Immutability for my debut Redux (NGRX/Store) endeavor has been quite the challenge. Avoiding state mutation has been a struggle, especially while dealing with Object.assign({}) and state mutation errors. Thankfully, I stumble ...

How to use TypeScript variables in React applications

In my current project, I am attempting to customize a Fabric JS component (Dropdown) using styled-components within a React component. The specific CSS class names are defined in a file located at office-ui-fabric-react/lib/components/Dropdown/Dropdown.sc ...

Testing the Child Component's EventEmitter Functionality

In my child component, there is an event emitter that sends a boolean value when the style changes in the parent component: export class ExampleComponent implements OnInit, OnChanges { @Output() statusEvent = new EventEmitter<boolean>(); getS ...

Troubleshooting Angular 2 Fallback Route Failure

My current project is using Angular 2 Webpack Starter but I am having trouble with the fallback route. In my app.routes.ts file, I have defined the routes as follows: import { Routes } from '@angular/router'; import { HomeComponent } from &apos ...

How can I seamlessly combine CoffeeScript and TypeScript files within a single Node.js project?

When working on a server-side node project utilizing the standard package.json structure, what is the best way to incorporate both Coffeescript and Typescript files? It's crucial that we maintain the availability of npm install, npm test, and npm sta ...

Creating a type definition for the createSelector function based on the useQuery result

Struggling to find the correct typings for the createSelector res parameter from redux-js, especially in TypeScript where there are no examples or explanations available. The only guidance is provided in JS. const selectFacts = React.useMemo(() => { ...

Troubleshooting VueJS, Electron, and Webpack integration with Hot Reload feature

I have been immersed in a new project that involves utilizing Electron, VueJS, and Webpack for HMR functionality. Unfortunately, I am encountering difficulties with the Hot Module Replacement feature not working as expected. Here is my current configurati ...

Using ES6 import declarations within a Node.js application enhanced with Babel and Typescript

Problem with using ES6 import syntax in TypeScript file: import express from "express" const app = express() app.listen(3000, () => console.log("Example app listening on port 3000!!")) Solution using .babelrc: { "presets": ["@babel/preset-typescr ...

Sort the array by the elements in a separate array

Here is a filters array with three values: serviceCode1, serviceCode2, and serviceCode3. ['serviceCode1', 'serviceCode2', 'serviceCode3'] I have another array with approximately 78 records that I want to filter based on the a ...