When publishing an NPM package, there are three distinct types of export that you can specify in a package.json file.
-
This allows you to export multiple ‘indexes’ from a single package, at different paths. For example, this subpath export:
// package.json { "name": "my-package", "exports": { "./submodule": "./dist/submodule.js" } }lets you import that index by writing this:
// app.ts import submodule from 'my-package/submodule'; Environment Conditional Exports
To target a particular package file to Node, React Native, web browsers, or TypeScript, you can use named conditional exports like this:
// package.json { "name": "my-package", "exports": { "browser": "./dist/browser/index.js", "node": "./dist/node/index.js", "react-native": "./dist/react-native/index.js", "types": "./dist/types/index.d.ts" } }Module System Conditional Exports
To target a differently built bundle to consumers using CommonJS vs. ES Modules, you can name the package loader in a conditional export like this:
// package.json { "name": "my-package", "exports": { "import": "./dist/index.js", "require": "./dist/index.cjs" } }
How do you combine all three? I want to offer submodule exports, that serve different files based on environment (Node, React Native, browser), depending on the package loader the consumer is using, and I want it to all work with TypeScript definitions.