I believe I understand the basic functioning of the exports
key in package.json
files:
// package.json
{
"exports": {
".": {
// used by typescript
"types": "./file_with_type_defs.d.ts",
// used by ESM resolution
"import": "./file_to_import.mjs",
// used by CJS resolution
"require": "./file_to_require.cjs",
// used by ...others?
"default": "./file_one_more.js"
}
}
}
Question: Does the order of the "types", "import", "require", and "default" keys matter? Normally I would think no way, since JSON object keys are unordered. From json.org:
An object is an unordered set of name/value pairs. An object begins with { …
But Typescript documentation says that "types" must come first:
Entry-point for TypeScript resolution – must occur first!
"types": "./types/index.d.ts"
and the NodeJS documentation says "default" should come last
"default" – the generic fallback that always matches. Can be a CommonJS or ES module file. This condition should always come last.
So… Does the order of the export keys matter? If not, what do the NodeJS and Typescript documentation mean when they talk about "first" and "last"?
Having swapped the order of "types" with other keys, its order seems not to matter.
2
Answers
JSON objects are "unordered set" as "key do not have a particular order(i.e. never have to be sorted)", not as "do not have an order"
Parsed JS object DOES have an order of keys matching the orger in JSON
Depending on if the code uses
for (let k in json)
orif (json.types)
the behaviour may be differentSo by whatever reason it’s recommended to order keys in the way some parsers may expect
In your case I’d recommend you to try swapping them, seeing that nothing happens, and swapping them back
Webpack, which also uses the
export
key explains this field as follows:Rather than see this as a plain object, consider it being like this if-else case:
If you were to swap the order, it might be like this:
Even though Typescript understands
.d.ts
files it would usefile_one_more.js
since it matches first.It might be that Typescript prioritizes the
types
condition over others. However, I’d stick with what they advise—"must occur first" is not "ought to occur first", after all.As a side-note, historically JavaScript object keys are unordered / the order is not guaranteed. In practice, browsers did preserve the key order and this behavior was standardized in ES2015: non-integer keys are preserved in insertion order.
The JSON standard doesn’t make the same promise, as there are many implementations of JSON decoders in different languages and it the predates ES2015 standard.