Directly mapping packages to Typescript source code in the package.json files of a monorepo

How can I properly configure the package.json file in an npm monorepo to ensure that locally referenced packages resolve directly to their .ts files for IDE and build tooling compatibility (such as vscode, tsx, ts-node, vite, jest, tsc, etc.)?

I want to avoid local Typescript tasks (such as bundling, ts-jest testing, debugging) resolving to transpiled .js files in the dist folder or the .d.ts artifacts. These files may be out of date if the author forgets to rebuild after editing .ts files in src, or doesn't have a watch procedure in place. Ideally, these tasks should resolve directly to the original .ts files.

To better understand how to achieve this, I have created a sample monorepo at this link, focusing on how to point to Typescript source files within an npm-compatible package.json (not pnpm). You can view the example package.json for "@starter/multiply" and "@starter/sum" from the same repo to see how local resolutions work in various tools.

In the past, I relied on pnpm's tooling, which allows the "main" field of package.json to be overridden during publishing. The "main" field was set to "src/index.ts" during development and changed to "dist/index.cjs" later in the release process.

However, I am now exploring ways to achieve similar results with npm, as it does not support overriding the main field through publishConfig. I am unsure if there is a npm postpack step where I could script changes to the tar to set "main" permanently to "src/index.ts" locally and switch to .js before publishing.

The reference npm monorepo I provided has functioning tests, cached build tasks, and sourcemapping for debugging. However, the loaded source is not the .ts files even within the monorepo. Instead, main resolves to src/index.mjs, which imports from dist/index.js with sourcemapping back to src/index.ts. This leads to issues when the background build isn't rerun, resulting in outdated .js files.

I have raised a related ticket at https://github.com/microsoft/TypeScript/issues/51750 to suggest a solution, but I am curious if there are conventional approaches or tricks that others are using.

Answer №1

After reviewing the changes made in this commit, it appears that the configuration now meets the necessary requirements.

The package.json file contains correct references to transpiled source files (such as ./dist/index.cjs and ./dist/index.mjs) for npm publishing, with no mention of index.ts.

Upon navigating to packages/multiply, the expected outcome is achieved. It seems that tsc successfully recognizes the package's src/index.ts (located next to src/index.mjs). This suggests that any tool using tsc should be able to do the same.

packages/multiply]$ npx tsc --traceResolution | grep '@starter/sum' | more
======== Resolving module '@starter/sum' from '/home/cefn/Documents/github/starter/packages/multiply/src/index.ts'. ========
======== Module name '@starter/sum' was successfully resolved to '/home/cefn/Documents/github/starter/packages/sum/src/index.ts'. ========

This success can likely be attributed to the top-level shared tsconfig.json's paths resolution at this location. However, there may still be exceptions or issues if tools like esbuild or jest do not adhere to this resolution and opt for node's package.json resolutions instead.

Although promising, I will refrain from marking this as the definitive answer just yet. There could be valuable insights and potential challenges shared by others regarding exceptions and possible problems.

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

Missing "this" after initialization? (typescript/node/express)

I am currently working on creating a basic http application using node-express. One issue I encountered is that when setting up routes, the constructor of the MyRouter class has access to this, but it seems to be lost within the getRoutes() function. cla ...

Comparing the map function and for loop in the Puppeteer package for Node.js

I experimented with the Puppeteer package in NodeJS and noticed a significant difference in functionality between using the map function versus a for loop. Here is an illustration of what I observed: Using the map function: data.map(async(info) =>{ ...

Having trouble installing npm package in Angular project

After cloning my project from GitLab, I encountered an issue while trying to install the NPM packages. When I ran npm install, an error popped up: https://i.stack.imgur.com/WNT5s.png Upon checking the log file, I found the following error message: 3060 ...

When attempting to print a Rectangle on my webpage using JavaScript and taking user input, I encountered an error stating that 'str' is not defined

I'm trying to implement a feature where clicking on the "try it" button will prompt the user for the number of lines and then print that many lines in the form of a rectangle. However, when I run my code, nothing appears on the DOM and there is an err ...

Troubleshooting issue with applying hover effect to child divs

How come when I hover over one of the child items in my parentDiv, the background of the last childDiv changes no matter which child I place my mouse on? for (let i = 0; i < Number(height); i++) { for (let j = 0; j < Number(width); j++ ...

Looping through NavItems component using JavaScript or Angular

My Angular project includes a navbar component with an app sidebar that has a navItems attribute. Below is the content of my navBar: <app-header style="background-color : #e65100;" [fixed]="true" [navbarBrandFull]="{ src: &a ...

Having trouble sending an email using nodejs and mailgun

Before accusing me of asking a duplicate question, I want to clarify that I have already searched for solutions and none of them worked for me. For example, I tried the solution provided in this link: Example of the domain name for mailgun before nodejs? ...

Tips on designing unique field validation decorators in NestJS using GraphQL

I'm currently developing a NestJS API using apollo-server-express and have created an InputType for appointments as shown below: @InputType() export class AppointmentInput { @Field(of => String) @IsNotEmpty() name: string; @Field(o ...

npm - Configuring the maximum memory usage in npm

I encountered an error message while trying to build my Angular project, The error states: "CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory" I read somewhere that adjusting the max-old-space-size in npm could resolve this issue. How ...

The issue of losing context when using Papaparse with an Angular 4 function

Check out this block of code httpcsv2Array(event) { var gethttpcsv = Papa.parse('https://docs.google.com/spreadsheets/d/e/yadyada/pub?output=csv', { download: true, header: true, ...

Why do I keep encountering this error every time I attempt to publish a package to npm?

I continuously encounter an error when attempting to publish a package to npm. npm ERR! code ERR_INVALID_ARG_TYPE npm ERR! The "path" argument must be of type string. Received undefined npm ERR! A detailed log of this run can be found in: npm ER ...

Guide to Angular 6 Reactive Forms: Automatically filling one text field when another input is selected

I'm currently learning Angular 6 and exploring reactive forms. I want to set up a feature where selecting an option in one field will automatically populate another field. The objective is to have the coefficient input update based on the number sele ...

What is the best way to format a text component so that the initial word in each sentence is bolded?

Creating a text component where the first word of the sentence is bold can be a bit tricky. The current solution may result in a messy output like "Tips: favouritevacation" where there is no space after "Tips:". This approach is not very elegant. One pos ...

Encountering 401 Unauthorized error when trying to NPM install a private repository

My package.json file contains the following line in my dependencies: "log": "https://git.mydomain.com/myproject/myrepo/repository/archive.tar.gz?ref=0.1.0", When I run npm install, I encounter this error message: km@Karls-MBP ~/dev/vertica (km/ref) $ np ...

Encountered a loading issue with modules in nodejs, where both node and nom were installed through the

After setting up nodejs and npm using repositories in Ubuntu 12.10, my usual method of installing a module is: sudo npm install -g nodemodule However, when I attempt to do var mod = require("nodemodule"), I encounter an error that requires me to use requ ...

Utilizing Ionic to import and parse an Excel file for data processing

I need assistance in uploading an Excel file and reading it using Ionic-Angular. I tried the following code, but it only seems to work for browsers and not for the Ionic app on Android. Can someone please help me with this issue? I am trying to read the E ...

json npm package malfunctioning

I'm utilizing the json npm package to make updates to my package.json file. Here is the command I am using: json -f package.json -I -e this.dependencies.data-version=\"1.0.0.1\" However, I am encountering the following error message: und ...

"Running the command 'npm install' may introduce new and unfamiliar files into your

When I attempt to use npm install uuid to update the dependencies in my package.json file, it seems to add a variety of JavaScript files such as uuid.cmd and uuid.ps1. Oddly enough, the uuid dependency is not included in the package.json file afterwards. ...

Unlock hidden Google secrets within your Angular application using Google Secret Manager

Can the Google Secret Manager API be accessed with a simple API call using an API key? https://secretmanager.googleapis.com/v1/projects/*/secrets/*?key=mykey returns a 401 unauthenticated error. While the Node.js server powering the Angular app uses the c ...

Tips for setting variable values in Angular 7

I'm encountering an issue with assigning values to variables in my code. Can anyone provide assistance in finding a solution? Here is the snippet of my code: app.component.ts: public power:any; public ice:any; public cake:any; changeValue(prop, ...