Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ESM exports #491

Open
jer-sen opened this issue Dec 12, 2023 · 0 comments
Open

Fix ESM exports #491

jer-sen opened this issue Dec 12, 2023 · 0 comments

Comments

@jer-sen
Copy link

jer-sen commented Dec 12, 2023

There are many errors to fix in all react-component modules for them to work well when imported from an ESM module.

Importing things from "rc-???" & types from "rc-???/es/..." from an ESM module with recommended (less fault-tolerant / strictest) TS config should not raise any error.

My tsconfig.json contains:

{
  "compilerOptions": {
    "moduleResolution": "NodeNext",
    "module": "NodeNext",
    "skipLibCheck": false,
    "skipDefaultLibCheck": false,
    "allowImportingTsExtensions": false,
    "allowSyntheticDefaultImports": false,
    "strict": true,
    "verbatimModuleSyntax": true,
    "isolatedModules": true
  },
}

Origin of errors:

  • ESM files in "rc-???/es/..." must have .d.mts or .mjs extension, or a package.json containing {"type":"module"} must be added to the folder
  • in "rc-???/es/..." do not import any file from CJS exports of a module, there should not have any import ... from 'rc-???/lib/...'; => import will fail if (and it would be a good thing) imported module restricts its /lib/ path to only CJS requires (exportsfield in package.json)
  • in "rc-???/es/..." any relative import (specifier or expression) in a .d.ts or .js should point to a file (not a directory) and have a file extension => TS error since modules are resolved as any
  • there should be no comment between /*#__PURE__*/ comment and the function call, cf rc-field-form/es/utils/validateUtil.js => esbuild error during build
  • modules with no default export (such as react) should not be imported using import Module from 'module' but instead with import * as Module from 'module', cf rc-dialog/es/Dialog/Content/Panel.d.ts or rc-picker/es/interface.d.ts => TS error with allowSyntheticDefaultImports disabled and runtime error without a bundler that fakes a default import
  • TS looks for types through the main field of package.json, even when module is imported from an ESM, so package.json should be patched with:
-  "main": "./lib/index",
-  "module": "./es/index",
+  "exports": {
+    ".": {
+      "types": {
+        "import": "./es/index.d.ts",
+        "default": "./lib/index.d.ts"
+      },
+      "import": "./es/index.js",
+      "default": "./lib/index.js"
+    },
+    "./es/*": {
+      "types": {
+        "import": "./es/*"
+      },
+      "import": "./es/*"
+    },
+    "./lib/*": {
+      "types": {
+        "require": "./lib/*"
+      },
+      "require": "./lib/*"
+    }
+  },

Interesting reading:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant