-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
Library
React Components / v9 (@fluentui/react-components)
System Info
N/AAre you reporting Accessibility issue?
no
Reproduction
https://stackblitz.com/edit/node-b7xc87
Bug Description
Actual Behavior
Native ES modules don't work:
❯ node index.mjs
(node:11) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/home/projects/node-b7xc87/node_modules/@fluentui/react-tabster/lib/index.js:1
export { useArrowNavigationGroup, useFocusableGroup, useFocusFinders, useFocusVisible, useFocusWithin, useKeyboardNavAttribute, useModalAttributes, useTabsterAttributes } from './hooks/index';
^^^^^^
Expected Behavior
ES Modules work:
❯ node index.cjs
function
ESM in Node
Node.js has two module systems: CommonJS modules and ECMAScript modules.
Authors can tell Node.js to use the ECMAScript modules loader via the .mjs file extension, the package.json "type" field, or the --input-type flag. Outside of those cases, Node.js will use the CommonJS module loader. See Determining module system for more details.
Another good summary is there: https://www.typescriptlang.org/docs/handbook/esm-node.html
Problem
We ship CommonJS and ESM code currently, the problem is that our packaging does not follow best practices from Node (https://nodejs.org/api/packages.html#dual-commonjses-module-packages):
- we don't specify
type: moduleortype: commonjsso Node does not know how to handle.jsfiles - we don't ship
.mjsor.cjsfiles to indicate contents of them - our export maps are invalid
Mid-solution: update export maps
"exports": {
".": {
"types": "./dist/index.d.ts",
+ "node": "./lib-commonjs/index.js"
"import": "./lib/index.js",
"require": "./lib-commonjs/index.js"
},
"./package.json": "./package.json"
}We can add node field (order is important) to export maps, so Node will always use CommonJS output. That's not ideal, but things will start to work as expected:
- Node uses CommonJS always
- Bundlers will still use ESM output based on
importentry
Ideal solution: ship dual packages
- Upgrade TypeScript to support new module resolution and apply it (
moduleResolution: node16) - Add
type: moduletopackage.jsonfiles - Ship ESM in
.jsfile, ship CommonJS in.cjsfiles - ✅ 🍾
Note: While this sounds easy, the first step will be the most time consuming:
relative import paths need full extensions
https://www.typescriptlang.org/docs/handbook/esm-node.html
Logs
N/ARequested priority
High
Products/sites affected
No response
Are you willing to submit a PR to fix?
no
Validations
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- The provided reproduction is a minimal reproducible example of the bug.