Skip to content

[Bug] LazyXDSTooltip import() break all components due to missing mandatory file extensions for ESM #4569

Description

@davidjb

Description

When trying to use any component, such as a Button, its import fails because of the following, seen as output from Rspack:

ERROR in ./node_modules/@astryxdesign/core/dist/Text/Text.js
  × Module not found: Can't resolve '../Tooltip/Tooltip' in 'node_modules/@astryxdesign/core/dist/Text'
    ╭─[25:53]
 23 │ import { themeProps } from "../utils/themeProps.js";
 24 │ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
 25 │ const LazyXDSTooltip = /*#__PURE__*/lazy(async () => import('../Tooltip/Tooltip').then(mod => ({
    ·                                                      ────────────────────────────
 26 │   default: mod.Tooltip
 27 │ })));
    ╰────
  help: Did you mean '../Tooltip/Tooltip.js'?

        The request '../Tooltip/Tooltip' failed to resolve only because it was resolved as fully specified,
        probably because the origin is strict ECMAScript Module,
        e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"'.

        The extension in the request is mandatory for it to be fully specified.
        Add the extension to the request.

Grepping the code base, this affects any component using LazyXDSTooltip, which is Heading, Text and Timestamp, which are then used by effectively, if not actually, all other components. The dynamic import() syntax is passed through as-is from the source code below, into the compiled dist output, whereas compiled static import calls all have file extensions:

const LazyXDSTooltip = lazy(async () =>
import('../Tooltip/Tooltip').then(mod => ({default: mod.Tooltip})),
);

const LazyXDSTooltip = lazy(async () =>
import('../Tooltip/Tooltip').then(mod => ({default: mod.Tooltip})),
);

const LazyXDSTooltip = lazy(async () =>
import('../Tooltip/Tooltip').then(mod => ({default: mod.Tooltip})),
);

As the error indicates, @astryxdesign/core/package.json is set as `"type": "module"', which then specifies itself as an ECMAScript module. Per https://nodejs.org/api/esm.html#mandatory-file-extensions, file extensions are mandatory:

A file extension must be provided when using the import keyword to resolve relative or absolute specifiers. Directory indexes (e.g. './startup/index.js') must also be fully specified.

This behavior matches how import behaves in browser environments, assuming a typically configured server.

Reproduction

  1. import {Button} from '@astryxdesign/core/Button'; in an environment like Rspack that adheres to strict ECMAScript modules.
  2. Observe import error due to import('../Tooltip/Tooltip') syntax missing a file extension.

Astryx Version

@astryxdesign/core@0.2.0

Environment

Rspack v2.1.7

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions