Skip to content

feat: vitest support #615

Open
Open
@nmoon1

Description

@nmoon1

Prerequisites

Describe the Feature Request

Add support for vitest testing framework.

Describe the Use Case

Vitest resolves dependency exports using the Node.js resolution with no way to override this behavior (vitest-dev/vitest#4233). This results in the following error when running vitest for tests that use React wrappers of Stencil web-components:

Error: require() of ES Module C:\vite-test-app\node_modules\@lit\react\node\development\index.js from C:\vite-test-app\node_modules\@stencil\react-output-target\dist\react.cjs not supported.
Instead change the require of index.js in C:\vite-test-app\node_modules\@stencil\react-output-target\dist\react.cjs to a dynamic import() which is available in all CommonJS modules.

The import of @stencil/react-output-target/runtime is resolved via the node condition to the cjs bundle when we actually want the ESM version.

Describe Preferred Solution

The Node.js resolution algorithm will respect import conditions. Adding this condition to the exports field of the package.json and pointing it to the ESM bundle results in the correct import when running vitest. Example:

// @stencil/react-output-target/package.json
...
"exports": {
    ".": {
      "types": "./dist/react-output-target/index.d.ts",
      "node": {
        "default": "./dist/react-output-target.cjs"
      },
      "default": "./dist/react-output-target.js"
    },
    "./runtime": {
      "types": "./dist/react/index.d.ts",
      "browser": {
        "default": "./dist/react.js"
      },
      "import": {
        "default": "./dist/react.js" // adding this condition
      }
      "node": {
        "default": "./dist/react.cjs"
      },
      "default": "./dist/react.js"
    },
    "./ssr": {
      "types": "./dist/react/ssr.d.ts",
      "browser": {
        "default": "./dist/ssr.js"
      },
      "default": "./dist/ssr.js"
    }
  } 

Describe Alternatives

Vitest does not allow you specify mainFields or conditions priority like Vite does. However, it does let you alias imports to specific files. Adding the following to my vite.config.js does work around the issue.

import { resolve } from "node:path";
export default defineConfig({   
    ...
    test: {
        alias: {
            "@stencil/react-output-target/runtime": resolve(__dirname, "node_modules/@stencil/react-output-target/dist/react.js"),
        }
    }
)} 

Related Code

No response

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wanteda good issue for the community

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions