Package exports and eslint-plugin-import
Posted 10 February 2025
I was recently creating a new npm package with multiple entrypoints. Using Vite library mode I configured the entry points:
import { defineConfig } from "vite";
export default defineConfig({
build: {
lib: {
entry: {
"library": "src/index.ts",
"some-import": "src/some-import.ts",
},
name: "library",
},
},
});
I then added the exports field to the package's package.json
file:
{
"name": "library",
"main": "./dist/library.cjs",
"module": "./dist/library.js",
"types": "./dist/library.d.ts",
"exports": {
".": {
"types": "./dist/library.d.ts",
"import": "./dist/library.js",
"require": "./dist/library.cjs",
"default": "./dist/library.cjs"
},
"./some-import": {
"types": "./dist/some-import.d.ts",
"import": "./dist/some-import.js",
"require": "./dist/some-import.cjs",
"default": "./dist/some-import.cjs"
}
}
}
I then tried using this package in another project, and although TypeScript was able to resolve the module I was seeing errors from eslint
:
error Unable to resolve path to module 'library/some-import' import/no-unresolved
I found this eslint-plugin-import issue with recommendations to switch to eslint-import-resolver-typescript
, but I didn't want to force other projects to change their configuration just to use this package.
I also saw that in this same project we were importing msw/browser
without any complaints from eslint
, so I decided to look at how msw
was configured.
// No complaints from eslint!
import { setupWorker } from "msw/browser";
msw
's root package.json
matched my own, but there was also a browser
directory in the root of the package with another package.json
:
// node_modules/msw/browser/package.json
{
"main": "../lib/browser/index.js",
"module": "../lib/browser/index.mjs",
"types": "../lib/browser/index.d.ts"
}
This was the key to getting this working, helping the resolver treat msw/browser
as a separate package which resolved correctly. I added an extra package.json
to my own library in library/some-import/package.json
:
{
"main": "../dist/some-import.cjs",
"module": "../dist/some-import.js",
"types": "../dist/some-import.d.ts"
}
And everything worked as expected! I hope this helps you if you're running into similar issues.