@snorrees working on this I realise it's time for @sanity/plugin-kit to get some love. I'll make a PR on that repo with the new best practices we've developed for semantic-release, @sanity/pkg-utils, shipping ESM, using tsconfig's new module: "Preserve" config and more 🙌
In this PR the goal is to enable strict ESM mode support. What is that? The ability to create a file like test.mjs that does this:
The index.cjs.mjs file is re-exporting the cjs file. In other words, it takes Node out of ESM mode and resolves @sanity/assist, and all its deps, in CJS mode.
It's not enough to simply remove the re-export pattern:
file:///test.mjs:1
import { assist } from "@sanity/assist";
^^^^^^
SyntaxError: Named export 'assist' not found. The requested module '@sanity/assist' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from '@sanity/assist';
const { assist } = pkg;
at ModuleJob._instantiate (node:internal/modules/esm/module_job:132:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:214:5)
at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
at async loadESM (node:internal/process/esm_loader:28:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)
Node.js v20.11.1
And used dependencies (like in this case date-fns) has to be updated to support native ESM, or inlined by moving them out of peerDependencies and dependencies and into devDependencies (@sanity/pkg-utils marks packages in those two lists as external).
Why do we want native ESM mode? New environments like Remix + Vite are much stricter with how it deals with ESM, and doesn't support workarounds like exports["."].node.import that re-exports CJS. To support Studios embedding in those environments we have to be strictly ESM ready.
@snorrees working on this I realise it's time for
@sanity/plugin-kit
to get some love. I'll make a PR on that repo with the new best practices we've developed for semantic-release,@sanity/pkg-utils
, shipping ESM, using tsconfig's newmodule: "Preserve"
config and more 🙌In this PR the goal is to enable strict ESM mode support. What is that? The ability to create a file like
test.mjs
that does this:And have it output
file:///node_modules/@sanity/assist/dist/index.mjs { assist: [Function (anonymous)] }
Today, due to our esm wrapper pattern, it outputs:
The index.cjs.mjs file is re-exporting the cjs file. In other words, it takes Node out of ESM mode and resolves
@sanity/assist
, and all its deps, in CJS mode. It's not enough to simply remove the re-export pattern:This will create this output
As you also need to use
.mjs
file endings:And used dependencies (like in this case
date-fns
) has to be updated to support native ESM, or inlined by moving them out ofpeerDependencies
anddependencies
and intodevDependencies
(@sanity/pkg-utils
marks packages in those two lists asexternal
).Why do we want native ESM mode? New environments like Remix + Vite are much stricter with how it deals with ESM, and doesn't support workarounds like
exports["."].node.import
that re-exports CJS. To support Studios embedding in those environments we have to be strictly ESM ready.