Library
React Components / v9 (@fluentui/react-components)
System Info
Are 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.
https://nodejs.org/api/esm.html
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: module or type: commonjs so Node does not know how to handle .js files
- we don't ship
.mjs or .cjs files 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
import entry
Ideal solution: ship dual packages
- Upgrade TypeScript to support new module resolution and apply it (
moduleResolution: node16)
- Add
type: module to package.json files
- Ship ESM in
.js file, ship CommonJS in .cjs files
- ✅ 🍾
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
Requested priority
High
Products/sites affected
No response
Are you willing to submit a PR to fix?
no
Validations
Library
React Components / v9 (@fluentui/react-components)
System Info
Are you reporting Accessibility issue?
no
Reproduction
https://stackblitz.com/edit/node-b7xc87
Bug Description
Actual Behavior
Native ES modules don't work:
Expected Behavior
ES Modules work:
ESM in Node
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):
type: moduleortype: commonjsso Node does not know how to handle.jsfiles.mjsor.cjsfiles to indicate contents of themMid-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
nodefield (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:importentryIdeal solution: ship dual packages
moduleResolution: node16)type: moduletopackage.jsonfiles.jsfile, ship CommonJS in.cjsfilesLogs
Requested priority
High
Products/sites affected
No response
Are you willing to submit a PR to fix?
no
Validations