Having trouble locating the module 'nizar-npm-publish-test/mult/multiply' or its corresponding type declarations when publishing a typescript NPM package with submodules

As I attempt to release a TS package to NPM with both CommonJs and esm, I encounter two issues. 1- The challenge of building the esm files as .mjs files persists. As a temporary solution, I manually edit the file extensions before publishing to npm. Feedback on this approach would be greatly appreciated. 2- Importing from the package raises an error when accessing any file other than the main one:

Cannot find module 'nizar-npm-publish-test/mult/multiply' or its corresponding type declarations.ts(2307)

The structure of my TS package is as follows:

  • root/index.ts // includes add function with export default
  • root/substract.ts // contains substract function with export default
  • root/package.json
  • root/tsconfig.json
  • root/tsconfig.types.prod.json
  • root/mult/multiply.ts // features multiply function with export default
  • root/mult/divide.ts // comprises divide function with export default This is how my build is organized:
  • build/@types/index.d.ts
  • build/@types/substract.d.ts
  • build/@types/mult/multiply.d.ts
  • build/@types/mult/divide.d.ts
  • build/cjs/index.js
  • build/cjs/substract.js
  • build/cjs/mult/multiply.js
  • build/cjs/mult/divide.js
  • build/esm/index.mjs
  • build/esm/substract.mjs
  • build/esm/mult/multiply.mjs
  • build/esm/mult/divide.mjs

This setup is used for the build: package.json:

 "main": "index.js",
  "files": [
    "build/cjs",
    "build/esm",
    "build/@types"
  ],
  "types": "build/@types",
  "exports": {
    ".": {
      "import": "./build/esm/index.mjs",
      "require": "./build/cjs/index.js"
    },
    "./*": {
      "import": "./build/esm/*.mjs",
      "require": "./build/cjs/*.js"
    },
    "./mult/*": {
      "import": "./build/esm/mult/*.mjs",
      "require": "./build/cjs/mult/*.js"
    },
    "./types":"./build/@types/index.d.ts",
    "./types/*": "./build/@types/*.d.ts",
    "./types/mult/*":"./build/@types/*.d.ts"
  },
  "scripts": {
    "clean": "rimraf build",
    "build": "yarn clean && yarn build:esm && yarn build:cjs && yarn build:types",
    "build:esm": "tsc -p tsconfig.prod.json --module ES2022 --outDir build/esm",
    "build:cjs": "tsc -p tsconfig.prod.json --module commonjs --outDir build/cjs",
    "build:types": "tsc --p tsconfig.types.prod.json -emitDeclarationOnly",
    "test": "echo \"Error: no test specified\" && exit 1",
    "launch": "npx ts-node src/index"
  },

tsconfig.json:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Default",
  "compilerOptions": {
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "incremental": true,
    "rootDir": ".",
    "outDir": "build",
    "sourceMap": false,
    "target": "ESNext",
    "noEmit": false,
    "module": "CommonJS",
    "moduleResolution": "node",
    "declaration": true
  },
  "ts-node": {
    "require": ["tsconfig-paths/register"]
  },
  "include": ["."],
  "exclude": ["build", "node_modules", ".turbo", "coverage", "dist"],
  "moduleResolution": ["node_modules", "node"]
}

And here's the tsconfig.types.prod.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "composite": false,
    "outDir" : "build/@types"
  },
  "exclude": [
    "build",
    "coverage",
    "node_modules",
    ".turbo",
    "coverage",
    "dist",
    "**/__test__",
    "__test__",
    "__mocks__",
    "**/__mocks__",
    "*.config.js",
    "*.config.ts",
    ".env",
    "src/**/*.test.ts"
  ]
}

You can view the importhere.

For reference, the initial issue with imports is displayedhere.

Note that both add and multiply functions are functional; the primary aim is resolving the TS error.

Answer №1

Latest Update: I managed to eliminate the need for the .mjs extension in my workaround, although it's not the most elegant solution. I would greatly appreciate any suggestions to enhance it:

To begin with, I made adjustments to the exports section as follows:

  "main": "build/cjs/index.js",
  "module": "build/esm/index.js",
  "types": "build/esm/index.d.ts",
  "files": [
    "build/cjs",
    "build/esm"
  ],
  "exports": {
    ".": {
      "import": "./build/esm/index.js",
      "require": "./build/cjs/index.js",
      "types": "./build/esm/index.d.ts"
    },
    "./*": {
      "import": "./build/esm/*.js",
      "require": "./build/cjs/*.js",
      "types": "./build/esm/*.d.ts"
    }

This led to the creation of a new directory structure:

  • substract/package.json
  • mult/multiply/package.json
  • mult/divide/package.json

Each of these newly added package.json files now includes a similar content.

{
  "name": "substract",
  "description": "This helps TypeScript compiler recognize it",
  "main": "../build/cjs/substract.js",
  "module": "../build/esm/substract.js",
  "types": "../build/esm/substract.d.ts"
}

The current challenge lies in having to create multiple package.json files if there are numerous files to be imported later on.

Answer №2

I successfully tackled the issue at hand by ensuring that the package is now suitable for use with various technologies including nodejs APIs, Reactjs Vite, and NextJS. For a detailed example, you can refer to this documented repository: https://github.com/nizar-zouaoui/npm-publish-example.

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

When checking the angular-cli.json file, it reported the error "moment is not defined."

I'm having some challenges with Angular2 development using angular-cli. One thing I'm unsure about is how to include external CSS and JavaScript libraries in my project. Below is my angular-cli configuration where I have loaded numerous librari ...

Angular II slash avoiding Pipe

I am working on developing a customized pipe in Angular 2 that will handle the replacement of the backslash ('\') character in a given string. This backslash is commonly used to escape special characters. What I have accomplished so far: T ...

Transforming a dynamic array into a new dynamic array (with a different data type) based on a property that can change over time

Explaining my process with the example of a REST api returning a list of objects, each needing a checkbox for selection and further processing. The api may be called multiple times for data refresh, utilizing Observables to handle selected values as an Obs ...

The Typescript component functions as expected, although it falsely reports an error due to its failure to identify an existing property

While utilizing the three.js library to render an image on the screen, I encountered a peculiar issue. Specifically, when I instantiate my particles using THREE.point(geometry, materials), TypeScript throws an error stating that vertices are nonexistent in ...

Unable to locate any static exports within the TypeScript library bundle

In my file Style.ts, I have a class called Style: export class Style { ... } The Style class consists of properties, methods, and a constructor, along with import statements for other class dependencies. It is being used by other classes through the ...

Issue with displaying tab icons in Ionic 4

After updating the versions of Angular, Cordova, and Ionic, I started experiencing an issue with the tab icons displaying partially. Specifically, when my app loads with 4 tabs, only the first and third icons are visible. However, upon touching one of the ...

Protractor fetches filtered column data from all rows

I am attempting to retrieve only the rows that I have filtered in the 3rd column of my data table. A visual representation of the structure can be seen in this image: [Click here for site reference](https://i.sstatic.net/z8Heb.png). You can also visit th ...

Need help resolving the issue of "Type Property '' does not exist on type 'IntrinsicAttributes & Function'? Let's find a solution together

Looking at my parent component below: import FilterComponent from 'filter/filterComponent' const handleReload = useCallback( (event: MouseEvent) => { event.preventDefault(); // implement logic here }, [Reload, Fetch ...

Enhance the firstLevel Tree component with Angular Material

I recently developed a multi-level tree in Angular with 3 levels. Currently, when the tree is loaded, only the first level is opened by default. Check out the demo here My goal is to enable users to add or delete items within this tree, and whenever an a ...

Type aliases using generics may demonstrate varying behaviors from type aliases without generics

Here is a code snippet to consider: type TestTuple = [ { test: "foo" }, { test: "bar"; other: 1; } ]; type Foo<Prop extends string> = TestTuple extends Record<Prop, string>[] ? true : fal ...

Vue: Storing selected list values in an array

I am working on a Vue application where I need to select two elements from a list component and place them inside an array. Currently, I have my list set up with selection functionality thanks to Vuetify. I have bound the selected items to an array using v ...

Compilation error in VueJS: missing dependency detected

I am facing an issue in my VueJS project where a file I am referencing seems to be causing a compilation error. Despite being present in the node_modules directory, the dependency is declared as not found. In the image on the left, you can see the directo ...

Determining the Clicked Button in ReactJS

I need help with a simple coding requirement that involves detecting which button is clicked. Below is the code snippet: import React, { useState } from 'react' const App = () => { const data = [ ['Hotel 1A', ['A']], ...

Utilize a combination of generic parameters as the keys for objects in TypeScript

Is there a method to utilize multiple generic parameters as object keys in TypeScript? I came across this answer which works well when there is only one parameter, but encounters issues with more than one. The error message "A mapped type may not declar ...

Utilizing TypeScript loops to set resource tags in AWS CDK

I encountered a Circular dependency error while trying to create an aws tag. Instead of adding the class instance each time, I opted to create a function that iterates over a given object and applies them to tags. Iterator: .... ResourceTagger = (this, ...

Enhance the Nuxt 3 experience by expanding the functionality of the NuxtApp type with

When I include a plugin in my NuxtApp, it correctly identifies its type. https://i.stack.imgur.com/UFqZW.png However, when I attempt to use the plugin on a page, it only displays the type as "any." https://i.stack.imgur.com/hVSzA.png Is there a way for ...

Verify automatically filled data using Playwright

Currently experimenting with Playwright and encountering an issue. I have a web form with 4 fields. When 2 of them are filled, a calculated value appears in the third one. I expected .soft to return the newly appeared value as a string: "" Here ...

What is the method to merge min and max validation errors when using React Hook Form?

<input {...register("subject", { maxLength: 50, minLength: 2, required: true, })} disabled={isLoading} id="subject" autoComplete=&q ...

Issue encountered with Angular 11 not being compatible with any edition of ngx chess-board, whereas it operated seamlessly with @angular/cdk: "^12.2.9"

After successfully using angular ngx-chess-board, I encountered an issue when attempting to run it with Angular 11. An incompatible version error was thrown, indicating that ngx-chess-board only supports cdk versions 10 or 13, while my project is running o ...

How can I import multiple variables in TypeScript?

I have a React application built with TypeScript, and my project directory is structured as follows: App.tsx /pages Page1.tsx The contents of Page1.tsx are shown below: Page1.tsx class PageParams { constructor() { } } class Page1 { co ...