Karl Taylor
Karl Taylor

Reputation: 5279

importing different nested packages in npm module

Say I have a library structure as below:

my-library
|-- lib
|   |
|   |-- foo
|   |   |--index.js
|   |
|   |-- bar
|       |--index.js
|
|---src
|   |-- foo
|       |-- button.js
|       |-- index.js
|   |-- bar
|       |-- button.js
|       |-- index.js
|-- package.json

I want to import these packages like this:

import { button } from 'my-library/foo'
import { button } from 'my-library/bar'

Is this possible?

The only way I have got it working is to import it like:

import { Button } from 'my-library/lib/foo'

I'm using Babel if that helps. Should I just transpile to the root directory and not use a lib dir?

I'm was looking at packages that do this such as lodash and React Native Vector Icons where they specify what they are importing.

Similar question here: Root directory in package.json

Upvotes: 1

Views: 3543

Answers (1)

morganney
morganney

Reputation: 13580

ECMAScript modules (ES modules) support an experimental property in package.json called exports that allows submodule aliases.

Given a package.json file with this config:

{
  "name": "my-library",
  "exports": {
    "./foo/": "./lib/foo/",
    "./bar/": "./lib/bar/"
  }
}

You should be able to import modules like:

import { button } from 'my-library/foo'
import { button } from 'my-library/bar'

Another option is to update your build script:

  • copy ./my-library/package.json over to ./my-library/lib/package.json
  • update the main field if needed
  • publish from the ./my-library/lib directory

Regarding updating the main field, you might want to consider adding a ./my-library/lib/index.js file that exports every module from your library for consumers that want to import from a fixed path (however, in a browser environment this would increase their bundle size):

import { button } from 'my-library'

Upvotes: 1

Related Questions