How to specify the distributable directory visible for both NPM and TypeScript? (Multiple files case)

Viewed 199

The library written in TypeScript includes three main files for distribution:

  • NodeJS.js - for, obviously, Node.js runtime.
  • BroswerJS.js - for, obviously, browser runtime.
  • index.js - common functionality for both browser and Node.js

enter image description here

There no "main" file in this library so I has not specified this property in package.json.

Planning usage:

  • import { isUndefined, isNull } from "package-name;
  • import { delegateClickEventHandling } from "package-name/BrowserJS;
  • import { NodeJS_Timer } from "package-name/NodeJS;

Currently, the TypeScript with below config compiles files below Source directory to Distributable directory:

enter image description here

{
  "compilerOptions": {

    "target": "ES2020",
    "module": "CommonJS",
    "moduleResolution": "Node",

    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,

    "removeComments": true,

    "outDir": "Distributable/",
    "declaration": true
  },

  "include": [ "Source/**/*" ]
}

If to publish the library such as, TypeScript even will not see it:

import { isUndefined } from "package-name";
TS2307: Cannot find module 'package-name' or its corresponding type declarations.

Because as default TypeScript expecting that .d.ts files will be in root directory of the library. But the distributables are in Distributable directory!

And of course, isUndefined will not be found. I know about "main" property in package.json, but it is for one file case, but what about directory?

I know that multiple distributable files exporting is the supported scenario. For example the mysql2 exporting promise.ts besides index.js:

import MySQL from "mysql2";
import MySQL_Promise from "mysql2/promise";

Update

The NPM part solved - modern solution is exports filed in package.json:

"exports": {
  ".": "./Distributable/index.js",
  "./NodeJS": "./Distributable/NodeJS.js",
  "./BrowserJS": "./Distributable/BrowserJS.js"
},

But distribution files are still invisible for TypeScript.

TS2307: Cannot find module 'package-name' or its corresponding type declarations.

I learned about "types" field of package.json. Unfortunately, it could be only a string. It means currently it's impossible to specify multiple files. The issue about making in to array has been declined.

But how to make visible all of "./Distributable/index.js", "./Distributable/NodeJS.js", "./Distributable/BrowserJS.js" for TypeScript?

Please don't suggest me again to make all imports to single entry point. In this question we considering the multiple entry points case.

1 Answers

I am not entirely sure what you are trying to achive, in TS generally when you have single project with 1 configuration file, and you emit multiple files from it, you would not use package name within the same project, use path instead './someFileName'.

If you have multiple projects (tsconfig files) to manage different directories - sort of monorepo thing going on.

Your best options is project references: https://www.typescriptlang.org/docs/handbook/project-references.html

Or if you are doing something else then this may help altho I'd do this as last resort :-)

https://www.typescriptlang.org/tsconfig#paths

Related