Create a TypeScript module within a subdirectory and link it with Webpack

Within this query, there are three distinct meanings for the term "module", so feel free to seek clarification if needed.

I am dealing with a TypeScript project that heavily relies on a node_module which I want to modify. To achieve this, I have replicated the source code of this dependency as a Git submodule. Notably, this dependency is also constructed using TypeScript.

The layout of my directories is structured as such:

root/
  - source/
    - app.tsx (my starting point)
    - ... 
  - vendor/
    - dependency/ (git submodule)
      - node_modules/
        - (dependencies of the dependency)
      - source/
        - index.ts
        - ... 
      - package.json
      - tsconfig.json
  - webpack.config.js
  - tsconfig.json
  - package.json

The file

root/source/vendor/dependency/source/index.ts
holds the exports of the dependency.

My objectives are:

  1. To be able to refer to my dependency in my .ts files as if it still were a node_module dependency (e.g.
    import { class1, class2 } from "dependency"
    .
  2. To configure webpack to bundle my dependency together with my project

I am encountering challenges primarily with the first objective. I am struggling to make tsc recognize the module name "dependency".

I suspect the issue lies within my tsconfig.json configuration – yet, the resolution eludes me. Despite setting baseUrl and paths to what I believed would suffice, the compiler continues to report being unable to locate the module.


Details of my current tsconfig.json

{
    "compileOnSave": false,
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "isolatedModules": false,
        "jsx": "react",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "declaration": false,
        "noImplicitAny": false,
        "sourceMap": true,
        "removeComments": true,
        "noLib": false,
        "preserveConstEnums": false,
        "suppressImplicitAnyIndexErrors": true,
        "outDir": "./lib",
        "types": [
            "es6-promise",
            "google.analytics"
        ],
        "baseUrl": ".",
        "paths": {
            "dependency": "vendor/dependency/source/index.ts"
        }
    },
    "exclude": [
        "**/node_modules",
        "vendor/dependency/node_modules/"
    ]
}

Information from my current webpack.config.js

var path = require("path");
var tsConfigPath = path.resolve("tsconfig.json");

module.exports = {
  devtool: "source-map",
  entry: {    
    web: path.resolve(path.join("source", "app.tsx"))
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".scss"],
    modules: [
      "node_modules",
      "vendor"
    ]
  },
  output: {
    path: path.resolve(path.join("proxy", "static")),
    filename: "[name]/[name].js",
    publicPath: "/"
  },
  module: {
    rules: [
        {
          test: /\.tsx?$/,
          loader: "awesome-typescript-loader"
        },
        {
          test: /\.scss$/,
          loaders: ["style-loader", "css-loader", "sass-loader"]
        },
        { // Re-process any sourcemaps for all '.js' files.
          enforce: "pre",
          test: /\.js$/,
          loader: "source-map-loader"
        }
    ]
  },
  plugins: [
    require("webpack-fail-plugin")
  ],
  externals: {
    "react": "React",
    "react-dom": "ReactDOM"
  }
};

If I'm approaching this incorrectly, kindly inform me...all I desire is to amend my local dependency without necessitating its release on npm.

Answer №1

If you're facing a tricky situation, try this solution: first, create a node_modules folder in your project root (if it doesn't already exist). Within that folder, create a file called dependency.ts and add the following line of code:

export * from './../vendor/dependency/source/index.ts'

Now, whenever you use

import { class1, class2 } from 'dependency'
in your application, it will reference the file at root/node_modules/dependency.ts.

For more information, check out this article in the official TypeScript documentation.

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

What is the proper way to assign the return value of a function within a class as the value of an attribute in TypeScript?

Imagine having a Class Factory that accepts another class Product (or its subclass) as an argument and has methods to return instantiated Products with additional modifications. Here is an example: abstract class Product {} class Wheel extends Product {} ...

Error: Please note that the loading of the style/types.scss file in the dist build

I am facing an issue with including a general style/types.scss file in the dist folder. Despite having what seems to be correct rules, I cannot locate the content of the file in the build output. What steps can I take to debug this problem and investigate ...

A step-by-step guide to setting up OpenLayers with NPM

It appears that there are two different OpenLayers packages available via NPM: Option 1 npm install ol After installation, you can use it like this: import OlMap from 'ol/map'; import OlView from 'ol/view'; import OlTile from ' ...

Event-Propagation in Angular 5 with mat-expansion-panel within another component

In my project, I am facing a challenge where I need to create multiple mat-expansion-panels within one mat-expansion-panel. Everything works fine except for the issue that when I try to open a child-panel, it triggers the close-event of the parent-panel. ...

Unraveling a discriminated union

I'm currently working on writing code that can handle generic discriminated unions with a type property. Imagine I have multiple discriminated unions defined as follows: interface IFoo { type: "foo"; foo: number; } interface IBar { type: "bar ...

Using Angular 5+ to fetch information from an ASP.NET Core Web API

Having trouble retrieving data from an ASP.NET Core 2.0 Web API with Angular 5+. The steps taken so far are as follows: An ASP.NET Core 2.0 Web API was created and deployed on a server. Data can be successfully retrieved using Postman or Swagger. Using ...

Determine if a variable contains only one digit in Angular 6 using Typescript

I have a specific value that I want to discuss: this.value.day It gives me a numerical output ranging from 1 to 31. My requirement is to add a leading zero if the number is less than 10. Can anyone guide me on achieving this? ...

Locate and retrieve the item that appears most often in a given array

In order to determine the mode of an array consisting of integer numbers only, I must create a function named findMode. If the array is empty, the function should return 0. Otherwise, it should return the element that occurs most frequently in the array. I ...

Having trouble applying CSS styles to the root element despite using a CSS file

My reactjs entry component setup looks like this: import React from "react" import ReactDOM from 'react-dom'; import App from "./js/components/App.js" import './index.css'; ReactDOM.render(<App />, document.getElementById(' ...

The ngx-daterangepicker-material is throwing an error: "A declaration of an accessor is not allowed in an

I'm experiencing an error in my package.json file and could use some assistance. The specific error message I keep encountering is: ERROR in node_modules/ngx-daterangepicker-material/daterangepicker.component.d.ts(59,9): error TS1086: An accessor can ...

Attempted to access a variable prior to giving it a value (TypeScript)

I am struggling to extract the ImgString from an array retrieved from an API and assign it to the base64 property of a photo object, but I keep encountering an error. As someone new to react, typescript, and javascript, I'm unsure where my code is goi ...

JavaScript Karma Automatic Tests Failing and Angular Generated

I'm struggling to comprehend the behavior of the automatically generated .spec.ts tests in Angular. Each test contains expect(component).toBeTruthy();, which should be a straightforward check to verify if the component was created successfully. Howeve ...

Is there a method to load any remaining chunks after the main chunk is loaded or to manually select which chunk to load in Webpack?

I have a unique section that needs to be loaded separately from the main content. Is there a way to delay loading this section until after the main content has been fully loaded, without triggering the component associated with that section? Currently, I ...

Tips for finalizing a subscriber after a for loop finishes?

When you send a GET request to , you will receive the repositories owned by the user benawad. However, GitHub limits the number of repositories returned to 30. The user benawad currently has 246 repositories as of today (14/08/2021). In order to workarou ...

What are the steps to launching a yarn app on a dev server?

I've always stuck with npm and never ventured into using yarn or webpack explicitly. The code from this repository needs to be executed: https://github.com/looker-open-source/custom_visualizations_v2 I'm looking for a way to run it like a develo ...

What is the process of compiling TypeScript code?

When attempting to use tsc, I encountered issues. Even when having typescript but lacking tsc, the problem persisted. What steps should I take next? https://i.sstatic.net/Djgqb.png ...

Experimenting with PIXI.js and Jest within a React Single Page Application

I am currently working on a react application that utilizes PIXI.js and @inlet/react-pixi for animations. During testing with Jest, I encountered the following errors: Error: Uncaught [TypeError: Cannot read properties of null (reading 'stage' ...

Struggling to populate a table with data

I've previously sought help on this project and I'm still facing challenges. The code is messy with duplicate functions, making it hard to manage. Currently, my main issue is fetching data from Firebase and updating a table with it. <div cla ...

Using the useContext hook in a TypeScript class component: a step-by-step guide

I am working with a TypeScript class component and have successfully created a context that can be accessed globally. I am interested in learning how to implement this context in a .ts class component and if it is possible to use it in a pure TypeScript ...

Error message shows explicit Typescript type instead of using generic type name

I am looking to use a more explicit name such as userId instead of the type number in my error message for error types. export const primaryKey: PrimaryKey = `CONSUMPTION#123a4`; // The error 'Type ""CONSUMPTION#123a4"" is not assignable to ...