Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript library import with sub paths

I have a Typescript library that is being consumed from a React app. I wanted to import the TS library contents with sub-paths like

import {base} from "my-lib"
import {foo} from "my-lib/path1"
import {bar} from "my-lib/path2"

I came across the Github issue which states that this is not yet supported (exports in package.json) by Typescript. I'm using Typescript 4.3.

There is a workaround posted in the same thread - Github repo typescript-subpath-exports-workaround. It uses exports and typeVersions

{
  "main": "dist/index.js",
  "types": "dist-types/index.d.ts",
  "exports": {
    ".": "./dist/index.js",
    "./exported": "./dist/exported.js"
  },
  "typesVersions": {
    "*": {
      "exported": ["dist-types/exported"]
    }
  }
}

I created a new react app (via npx create-react-app command) and tried importing hello from typescript-subpath-exports-workaround and it worked fine. But couldn't import `typescript-subpath-exports-workaround/exported

import {hello} from "typescript-subpath-exports-workaround" //works fine
import {foo} from "typescript-subpath-exports-workaround/exported" //gives "Module not found" error

Full error is below:

./src/App.js
Module not found: Can't resolve 'typescript-subpath-exports-workaround/exported' in '/Users/...../my-react-app/src'

Codesandbox code - https://codesandbox.io/s/create-react-app-forked-5yxd8

UPDATE: The sub-path used in import and the folder structure are different. In the above example, there won't be a folder named path1 or path2.

like image 898
user7 Avatar asked Oct 10 '21 07:10

user7


1 Answers

Look at the Next.JS React Framework. You can see that they use exactly the same approach as you have described. You can create a simple typescript application with their CLI tool like this:

npx create-next-app@latest --typescript

Then pay attention on imports used for instance in ./pages/index.tsx.

Then if you'll look into the ./node_modules/next/package.json you will see that they expose built files in two ways: actual code and type defs are inside ./node_modules/next/dist/* and their re-exports are right in ./node_modules/next/*.

At least this is a real-life example and a good place to start your experiments. It doesn't mean you have to learn the whole their codebase. You just need to mimic the essencial parts of their package.json file (https://github.com/vercel/next.js/blob/canary/packages/next/package.json), specifically main, types and files in your Typescript library.

Update

Just look where absent imports could be imported from:

enter image description here

As you might understand, those are the places, where corresponding *.d.ts files are placed. So you just need to create reexport files in the root folder of you library and mention them in 'files' property of your lib's package.json.

The exactly similar picture I have for my own library.

I think there is no other way to impement imports of your lib the way you want, except of having either reexports or original type definitions right in the lib's root folder

like image 61
Ruslan Zhomir Avatar answered Sep 17 '22 17:09

Ruslan Zhomir