Skip to content

Fix ESM exports #491

Description

@jer-sen

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:

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions