Straightforward npm package importing syntax

I am looking for a way to simplify the import statements when publishing a new TypeScript package on npm. Ideally, I would like to be able to use something like:

import { FirstClass, SecondClass } from "my-repo";

However, currently I have to use longer import statements such as:

import { FirstClass} from "my-repo/first-class";
import { SecondClass } from "my-repo/second-class";

Initially, I built the package using tsc -p . and then ran npm publish. Now I am exploring the use of pikapkg/pack to streamline the build process, but the issue of lengthy import statements remains.

Is there a tool available that can automatically generate a single file for importing (such as index.ts set as main in package.json), or do I need to manually create and update an index.ts file each time a new class is added?

Answer №1

There are two methods for achieving this goal.

Option 1: Installing in the node_modules directory

In this scenario, the library is installed in the consumer's node_modules folder and utilizes Node module resolution.

Node module resolution configuration involves the TypeScript compiler searching for the node_modules directory within your workspace. If there is an exported code that matches your import statement in this directory, the compiler can resolve it with a short import statement. More information on this configuration can be found here.

If the library is published and deployed to a registry such as https://registry.npmjs.org/ or an Artifactory repository, you can add the deployed library to the consumer's package.json as a dependency and install it using npm install. This will ensure that the library is placed in the node_modules directory. By configuring the compiler options in the tsconfig.json file with Node module resolution, the TypeScript compiler can effectively resolve the short import statement.

This approach assumes that the library has been deployed to a registry. If the library is only available locally, tools like the CLI of install-local can aid in installing the library in the local node_modules without requiring deployment. Alternatively, there is another method outlined in the next section.

Option 2: Referencing the published source directly from the dist directory

In the consumer project's tsconfig.json, you can specify locally published modules in the paths under the compilerOptions settings. This allows the TypeScript compiler to resolve dependencies from these configured paths. Therefore, there is no need to install the dependency in the node_modules directory to use the short import statement; the compiler will locate them based on the specified paths.

For example, if we have a library named my-lib, the structure of the dist folder would appear as follows:

dist
-->my-lib
---->{all the published files of my-lib}
-->my-app
---->{all the published files of my-app}

In this scenario, a sample tsconfig.json for the consumer would look like this:

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "paths": {
      "my-lib": [
        "dist/my-lib"
      ],
      "my-lib/*": [
        "dist/my-lib/*"
      ]
    }
  }
}

In the paths section, both my-lib and my-lib/* entries are required. my-lib can be used in the short import statement, like so:

import { MyLibModule } from 'my-lib';

The paths defined in the tsconfig point to the published library in the dist directory.

Note that exports need to be manually structured in the index.ts file of the package.

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

How can I use Angular to dynamically open a video that corresponds to a clicked image?

I need assistance with a functionality where clicking on an image opens a corresponding video on the next page. The issue is that all images have the same ID, making it difficult to link each image to its respective video. Below is the data I am working ...

Encountering an issue with executing Google API Geocode in JavaScript

I'm having trouble printing an address on the console log. Every time I run the code, I encounter an error message that reads: { "error_message" : "Invalid request. Missing the 'address', 'components', 'latlng' or &ap ...

What sets apart Node Package from Bower Package?

Consider the Ember App as an example. When you run ember install ember-bootstrap-4, it adds a node package. However, executing bower install tether --save will add a bower package. Both packages are necessary for the app. But what is the reason behind on ...

Is manual linking necessary for AsyncStorage in React Native?

I'm currently following the steps outlined in this tutorial to integrate AsyncStorage into my React Native application. My setup involves using react native v0.63.4 on a Mac, which has led me to question whether the manual linking instructions provide ...

Utilize [markdown links](https://www.markdownguide.org/basic-syntax/#

I have a lengthy text saved in a string and I am looking to swap out certain words in the text with a highlighted version or a markdown link that directs to a glossary page explaining those specific words. The words needing replacement are contained within ...

Using TypeScript generics to constrain to either a number or a string

I am working on coding a react input component that accepts a defaultValue parameter of type string | number. This component has a state type matching the type of the received defaultValue; This is my code: type TypeName<T> = T extends number ? "nu ...

typescript - transforming text into numerical values

newbalance = (Number(this.balance)) + (Number(this.pastAmount)); The result for my newbalance calculation is coming back as undefined, even though this.balance is 34 and this.pastAmount is 23. I've set this up in the controller and I'm trying t ...

Issue with Angular 2 Custom Pipe not Refreshing Unless Object is Saved

I recently created a custom Angular 2 pipe that formats a phone number from a 10-digit string to 'XXX-XXX-XXXX'. The pipe is functioning perfectly, but the issue arises when it fails to update in real-time during keypress; instead, it updates onl ...

Guide to incorporating Bootstrap icons into an Angular application through programming techniques

Have you checked out the official bootstrap documentation for information on how to use their icons? https://i.stack.imgur.com/N4z2R.png I'm currently trying to understand the package and its usage. However, none of the options in the documentation ...

Each Tab in Ionic2 can have its own unique side menu that opens when selected

In my ionic2 app, I wanted to implement a unique side menu for each of my tabs. Here is what I attempted: I used the command ionic start appname tabs --v2 to create the initial structure. Next, I decided to turn both home.html and contact.html (generated ...

Setting environment variables with React and nwb can be accomplished by following these steps:

In my component library created with create-react-app, I am using nwb to serve a demo application for testing the components. Currently, I start the demo app by running nwb serve-react-demo without any issues. I wish to simulate different applications uti ...

"Enhancing User Experience: Implementing Internationalization and Nested Layouts in Next.js 13.x

In the midst of working on a cutting-edge Next.js 13 project that utilizes the new /app folder routing, I am delving into the realm of setting up internationalization. Within my project's structure, it is organized as follows: https://i.stack.imgur.c ...

ES7 Map JSON introduces a new feature by using square brackets

Currently, I am utilizing core-js for the Map collection because it appears that ES7 Map includes a Map to JSON feature that is absent in ES6 Map. (ES6): JSON.stringify(new Map().set('myKey1', 'val123').set('myKey2', 'va ...

Using React Native to dynamically change color based on API response

I'm currently working on a React Native project and I have a requirement to dynamically change the background color of a styled component based on the value retrieved from an API. However, I'm facing some challenges in implementing this feature. ...

Leverage the power of NPM Libraries in Angular using Angular-CLI

I am attempting to integrate the npm library progressbar.js into my Angular 2 application built using Angular-CLI. After installing it with npm install progressbar.js --save, I encountered an issue as the documentation suggests using var ProgressBar = req ...

Angular 4 - Automatically scroll to specific list item based on search query input

While I can achieve this with custom JavaScript, I'm curious if Angular 4 has any built-in features that could help. I have a list of checkboxes that are scrollable and a search input above them. My goal is to enable users to quickly jump to a section ...

The issue I'm facing with the change handler for the semantic-ui-react checkbox in a React+Typescript project

Hey there! I'm currently facing an issue with two semantic-ui-react checkboxes. Whenever I try to attach change handlers to them, I end up getting a value of 'undefined' when I console log it. My goal is to retrieve the values of both check ...

What is the process for executing "npm run start" in the Azure DevOps release pipeline to initiate a production build for NUXTJS?

I am in the process of setting up CI/CD for my Nuxt application to be deployed on a Windows server. I have completed all the necessary steps such as file copying, npm installation, and running npm build. However, I am facing an issue with the final step wh ...

The step-by-step guide to fixing a Gigwage client eslint error using nestJS

Whenever I utilize the gigwage client for my services, I encounter the following eslint error: TS2742: The inferred type of 'findAll' cannot be named without a reference to '@gigwage/client/node_modules/axios'. This is likely not porta ...

Monitoring a Typescript Class's Get() or Set() function using Jasmine Spy

While working with Jasmine 2.9, I have encountered no issues spying on both public and private functions, except for when trying to spy on a get or set function at the class level. private class RandomService { public dogsHealth = 0; private get pers ...