How to NPM publish so that consumers can imports from different top-level directories
Asked Answered
J

0

6

I am publishing a library to NPM. The library was written in Typescript, and the result of the Typescript compilation is put in a lib/ folder. The main file is an index.ts that exports my public API:

export * from './functions';
export * from './models';

In package.json, I specify:

{"main": "lib/index.js", "types": "lib/index.d.ts", "files": ["lib/**/*"]}

Once my package is published and installed elsewhere, its folder structure is:

lib/
  index.js
  index.d.ts
  functions/
    index.ts
    my-function.ts
  models/
    index.ts
    my-model.ts

the consumer imports everything from the package root:

import {someFunction, SomeModel} from 'a-library';

This works, but I like the idea of segregating paths. One path for functions, and another for models. Currently if I remove the top-level index, the imports become segregated but they now include the lib/ folder in the path which I don't want:

import {someFunction} from 'a-library/lib/functions';
import {SomeModel} from 'a-library/lib/models';

What I would actually like to accomplish is the same but without lib/. I have a working solution but it seems too convoluted. Here is what works:

  1. In package.json, remove the main types and files key.
  2. Delete or empty the index.ts
  3. To publish replace the simple npm publish with the following steps:
    • copy package.json and paste it into /lib folder
    • cd into the /lib folder and run npm pack and take note of the created tarball's name
    • run npm publish {{TARBALL_NAME}}
    • cd back up to the project root

As a result, the published package has the following folder structure once installed:

functions/
  index.ts
  my-function.ts
models/
  index.ts
  my-model.ts

Because things are no longer nested within a lib/ directory the consumer can import as I wished:

import {someFunction} from 'a-library/functions';
import {SomeModel} from 'a-library/models';

The problem is that packing and publishing to accomplish this seems too cumbersome. I'll never get my teammates to by into a 3 or 4 step process when they've just been running npm publish all this time.

Is there a simpler way to accomplish what I'm after?

Jae answered 24/2, 2020 at 5:48 Comment(2)
You could potentially move the 4 steps to a npm script to automate it, and your teammates can run the script, like npm run pack-publishLaevogyrate
did you find a solution to this?Unwitting

© 2022 - 2024 — McMap. All rights reserved.