Having trouble locating a module using Webpack and Typescript in a custom module directory

My Objective

I created a dummy module called my-component that exports a single class named Something. The module is located in the app/modules/ directory. Currently, I am attempting to access it from app/app.js using the import syntax:

import { Something } from 'my-component';

Expectation: Given my current Webpack configuration (shown below), I expected this import statement to work as intended.

Actual Outcome: Instead, I encountered the following error message:

ERROR in [default] /<project_dir>/app/app.ts:1:26
Cannot find module 'my-component/Something'.

Attempted Solutions

I can confirm that the module itself is correctly defined because:

  1. I was able to import it using a relative path:
    import { Something } from './my-component'
  2. It imported successfully when moved to node_modules/my-component.

The issue only arises when trying to import the module without a relative path from the modules/ directory. This leads me to believe that the problem lies within my Webpack configuration.

Configuration Details

As illustrated below, I have listed two directories under resolve.root:

  • project_dir/app
  • project_dir/node_modules

Interestingly, while it manages to resolve from node_modules, it fails to do so from app.

Project Structure

                               Webpack
project_dir/
 ├── app/                      context, resolve.root
 │    ├── app.ts
 │    └── my-component/
 │         ├── index.ts
 │         └── Something.ts
 ├── webpack.config.js
 ├── node_modules/             resolve.root
 │    ├── ...
 │    ├── ...
 │    └── ...
 └── dist/
      └── ...

app/app.ts

import { Something } from 'my-component/Something';

app/my-component/index.ts

export { Something } from './Something'

app/my-component/Something.ts

class Something {
}

export { Something };

webpack.config.js

var path = require('path'),
  ROOT = path.resolve(__dirname, '.');

module.exports = {
  context: path.resolve(ROOT, 'app'),
  entry: 'app.ts',
  output: {
    path: path.resolve(ROOT, 'dist'),
    filename: '[name]-[hash].js'
  },
  module: {
    loaders: [
      { test: /\.ts$/, loader: 'awesome-typescript' }
    ]
  },
  resolve: {
    root: [
      path.resolve(__dirname, 'app'),
      path.resolve(__dirname, 'node_modules')
    ],
    extensions: [
      '', '.ts', '.js'
    ]
  }
};

EDIT Corrected the project layout.

Answer №1

Module Not Found

If you encounter a problem with loading modules dynamically in your ESNEXT code,

You will need to include "moduleResolution": "node" in your tsconfig.json.

Answer №2

I have discovered a more streamlined solution in comparison to the previously approved one:

To simplify your typescript setup, adjust the baseUrl within the compilerOptions:

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "./src",
    ...
  },
  ...
}

Breakdown:

By default, Webpack and Typescript utilize node module resolution which is effective. However, when incorporating custom module directories, it is essential to configure them in both the Webpack and Typescript configurations. Any modifications made to the Webpack module resolution configuration do not automatically transfer to the Typescript compiler.

Answer №3

Alright, I have replicated the structure of your project and identified the issue. It appears that the behavior of the import statement differs from that of the require statement in this case. Interestingly, the webpack resolve.root configuration functions correctly with the require statement.

To resolve this issue with the modules, you can update your import statements to use require instead, as demonstrated below:

app.ts

// Ensure TypeScript recognizes the require function
declare function require(name:string);
// Use require to import your module
var Something = require('my-component/Something');
// var myComponent = require('my-component');

my-component/Something.ts

// Export a function (in this case, used for testing)
export function Something() {
    console.log("Hello");
}

my-component/index.ts

// Declare the require function as seen earlier
declare function require(name:string);
// Include other modules using require
var exportedModules = {
    Something: require("my-component/Something")
};
export default exportedModules;

By following these steps, you should be able to resolve any issues and have the modules resolve correctly according to their names defined in Webpack. Unfortunately, achieving the same with the import statement proved challenging in this scenario.

I have uploaded the solution to a repository. Feel free to take a look if needed!

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

Utilizing JQuery to extract information from a JSON response

I've been struggling with accessing a specific piece of content within a JSON object. This is the code I'm using to fetch the data: function retrieveData(keyword){ $.ajax({ url: "https://openlibrary.org/api/books?bibkeys=ISBN ...

The type '0 | Element | undefined' cannot be assigned to the type 'Element'

I encountered the following error: An error occurred when trying to render: Type '0 | Element | undefined' is not assignable to type 'Element'. Type 'undefined' is not assignable to type 'ReactElement<any, any>&apo ...

How can you display directions while using the Google Maps app in a React Native application?

I need assistance with rendering directions between two points (current location and a passed location). Currently, I am using Linking to open the Google Maps App. However, when clicking the button passing the (latitude, longitude), I want the map to disp ...

Exploring the complexities of cyclic dependencies and deserialization in Angular

I have encountered an issue with deserializing JSON objects in my Angular project. After receiving data through httpClient, I realized that I need to deserialize it properly in order to work with it effectively. I came across a valuable resource on Stack O ...

Access + authentication code

After successfully using my login script in Postman, I ran into issues when attempting to integrate it with React.js for posting to the server. The problem lies in the fact that when the script checks for the user, it fails to return the return result. It ...

Can you explain the distinction between using call and apply?

Can you explain the distinction between utilizing Function.prototype.apply() and Function.prototype.call() to execute a function? const func = function() { alert("Hello world!"); }; func.apply() compared to func.call() Do performance dispar ...

Bootstrap 4 collapse is experiencing some issues as it is not collapsing smoothly. It seems to pause halfway before

Why is this collapse stopping in half before collapsing completely? I have 5 divs collapsing at once, could that be the issue? The example on W3 schools works fine... Should I consider changing the collapse to a panel instead? Visit W3 Schools for more i ...

Animate with Jquery sliding technique

Allow me to explain a situation that may seem unclear at first glance. I have implemented a jQuery script that animates a sliding box upon hover. $(function() { $('.toggler').hover(function() { $(this).find('div').slideTog ...

Sending a form from an iPhone device to a PHP backend server

It seems like I'm overlooking a simple aspect... Here is a basic form that I want to submit to a PHP script. It works perfectly on PC and Mac, but it doesn't function properly in Safari on iPad, iPhone, etc. Do you think there's some mobile ...

Managing enum types with json2typescript

After receiving a JSON response from the back-end that includes an Enum type, I need to deserialize it. The JSON looks like this: { ..., pst:['SMS','EMAIL'], ... } In Typescript, I have defined my enum class as follows: export enum Pos ...

Tips for conducting performance analysis in React 16

In the React documentation, it is mentioned that react-addons-perf does not function with React 16 and suggests using Chrome's built-in tools for equivalent functionality. However, in my experience, I have not found this to be true. For example, let& ...

++first it must decrease before it increases

I'm attempting to create a basic counter feature, where clicking on a button labelled "+" should increase a variable named Score by 1, and the "-" button should decrease it by 1. However, I've encountered an issue where pressing the "+" button fo ...

Create a dynamic feature in Bootstrap4 where the navigation bar changes color as the user scrolls to different sections of the

Currently building my personal portfolio website with Bootstrap 4, I came up with a great idea: changing the navigation bar color based on different sections of the website. I attempted to achieve this using JQuery's offset and scrollTop functions, bu ...

Is there a way to retrieve just 6 documents with a "true" value in a specific field?

I am working with a controller that uses the following code snippet: Model.find().sort('date').limit(6).exec(function(error, result) { if (error) { console.log(error); } else { res.send(result); } }); In my databas ...

Simple Steps to Convert an HTML String Array into Dynamic HTML with AngularJS Using ng-repeat

Below is an array consisting of HTML strings as values. How can I convert these strings into executable HTML code to display them? [ {html:'<button>name</button>'}, {html:'<table > <thead> <tr> <th>#</ ...

Having trouble aligning my slider in the center

Despite trying various methods to center this slider, such as using align="center" and different margin styles on the images and slider div itself, I am still facing alignment issues. Any assistance would be greatly appreciated. This is my first time posti ...

How is it that the callback method in the subscribe function of the root component gets triggered every time I navigate between different pages within the application?

I am currently using Angular 10 and have developed a server that returns an observable: export class CountrySelectionService { private _activeCountry = new BehaviorSubject(this.getCountries()[0]); public getActiveCountryPush(): Observable<CountryS ...

What is the process for invoking an asynchronous cleanup function?

Is it possible to trigger an async cleanup function within useEffect? useEffect(() => { return () => Voice.destroy().then(Voice.removeAllListeners); }, []); Keep in mind that the EffectCallback requires a return of void, not Promise<void> ...

Should URL parameters be avoided as a method for retrieving data with React Router in a React application?

Within my application, there exists a main page labeled Home that contains a subpage named Posts. The routing structure is as follows: <Route path='/' element={<Home />} /> <Route path='/posts/popular' element={<Post ...