The library mode documentation for Vite has an example of a package.json
that uses require
for UMD modules and import
for ESM and this is the example:
{
"name": "my-lib",
"type": "module",
"files": ["dist"],
"main": "./dist/my-lib.umd.cjs",
"module": "./dist/my-lib.js",
"exports": {
".": {
"import": "./dist/my-lib.js",
"require": "./dist/my-lib.umd.cjs"
}
}
}
Are the import
and require
keywords in this case used as "conditional keywords" that toggle the module file resolution?
So if a developer is using ESM syntax and they do something like:
import { Foo } from { my-lib }
then the import will resolved from "./dist/my-lib.js"
and if they do:
const myLib = require('my-lib')
then the import will be resolved from ./dist/my-lib.umd.cjs
?
Also if we are making use of the exports
property like this do we still need main
and module
?
It seems like these are overlapping?
The library mode documentation for Vite has an example of a package.json
that uses require
for UMD modules and import
for ESM and this is the example:
{
"name": "my-lib",
"type": "module",
"files": ["dist"],
"main": "./dist/my-lib.umd.cjs",
"module": "./dist/my-lib.js",
"exports": {
".": {
"import": "./dist/my-lib.js",
"require": "./dist/my-lib.umd.cjs"
}
}
}
Are the import
and require
keywords in this case used as "conditional keywords" that toggle the module file resolution?
So if a developer is using ESM syntax and they do something like:
import { Foo } from { my-lib }
then the import will resolved from "./dist/my-lib.js"
and if they do:
const myLib = require('my-lib')
then the import will be resolved from ./dist/my-lib.umd.cjs
?
Also if we are making use of the exports
property like this do we still need main
and module
?
It seems like these are overlapping?
Share Improve this question edited Mar 28 at 20:25 jonrsharpe 122k30 gold badges268 silver badges475 bronze badges asked Mar 28 at 20:12 OleOle 47.4k70 gold badges237 silver badges445 bronze badges 2- docs.npmjs/cli/v10/configuring-npm/…, nodejs./api/packages.html#package-entry-points – jonrsharpe Commented Mar 28 at 20:26
- 1 main and module are fallbacks. It's unknown in which modular environment the lib will be used. The said rules are expected to work in general but not guaranteed. It's not uncommon to explicitly specify main entry point in an import because of faulty module detection – Estus Flask Commented Mar 28 at 23:23
1 Answer
Reset to default -3I would suggest to 1) understand your target demographic; and 2) determine yourself if you want to support CommonJS and ECMAScript Modules.
node
, deno
, and bun
can run CommonJS and ECMAScript Modules. Technically no package.json
is necessary to execute CommonJS or ECMAScript Modules using either of the above runtimes.
bun
can bundle CommonJS to ECMAScript Modules with bun build
. Though if you read esbuild
issues you'll find where it's claimed it is not possible to do a 1:1 conversion between CommonJS and ECMAScript Modules. Some conversion just has to be done by hand.
deno
has --unstable-detect-cjs
, --unstable-node-globals
for the case of CommonJS and use of Buffer
and process
.
Whether to support CommonJS or EcmaScript Modules, or both, is an individual, and/or anizational choice.
Make it clear in your documentation what you are doing.