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

Vitest uses other library file then vite due to "main" vs. "module" in package.json #3206

Closed
6 tasks done
manuel-mauky opened this issue Apr 18, 2023 · 1 comment
Closed
6 tasks done

Comments

@manuel-mauky
Copy link

Describe the bug

I have a library with this package.json:

"main": "dist/index.js",
"module": "dist/index.esm.js"

Now I'm using this library in my Vite-based app (using template react-ts) and everything works. It's using the "dist/index.esm.js" file from that library.
However, now I tried to add Vitest and it doesn't work anymore because Vitest is using "dist/index.js". So there seems to be a difference in the actual file which is loaded.

Maybe I'm missing some config options?
One of the goals of Vitest is to have the same pipeline for both prod and test which seems to be not the case here.

(my initial problem was that I have a PNPM based monorepo setup were I'm having a react library and an example react project. Before, I was using create-react-app which had the issue of React-Hooks violation due to duplicated react versions. By switching to Vite, I was able to fix that (due to auto dedupe in the react-plugin I assume) which is great. However, in my Vitest-based tests I still had the error and I was able to debug to the point that Vitest is using the file from "main" while Vite is using the file from "module")

Reproduction

https://github.com/manuel-mauky/repro_vitest_issue_module_resolution

In my-lib there is a minimal npm package with these files:

// dist/index.js

console.log("index.js")

function helloWorld() {
    return "hello world index.js"
}

module.exports = helloWorld
// dist/index.esm.js

console.log("index.esm.js")

export default function helloWorld() {
    return "hello world index.esm.js"
}
// package.json
{
   ...
   "main": "dist/index.js", 
   "module": "dist/index.esm.js",
   ...
}

In my-app is a react app freshly generated with npm create vite my-app -- --template react-ts.

In App.tsx I'm using the helloWorld function:

import helloWorld from "my-lib"

function App() {

  return (
    <div className="App">
        {helloWorld()}
    </div>
  )
}

When I start this app, in the browser I see hello world index.esm.js.

In App.test.tsx I'm testing this behavior:

import { render } from '@testing-library/react';
import React from "react";
import App from "./App";

describe("App", () => {
    it("should create the app", () => {
        const { container } = render(<App/>)
        const app = container.querySelector(".App")
        expect(app).toBeDefined()

        expect((app as HTMLDivElement).textContent).toEqual("hello world index.esm.js")
    })
})

but it fails with

AssertionError: expected 'hello world index.js' to deeply equal 'hello world index.esm.js'

System Info

System:
    OS: macOS 13.2.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 83.14 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.17.1 - ~/Library/Caches/fnm_multishells/41270_1676891186121/bin/node
    Yarn: 1.22.19 - ~/Library/Caches/fnm_multishells/41270_1676891186121/bin/yarn
    npm: 8.15.0 - ~/Library/Caches/fnm_multishells/41270_1676891186121/bin/npm
    Watchman: 2023.03.27.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 112.0.5615.49
    Firefox: 111.0.1
    Safari: 16.3

Used Package Manager

npm

Validations

@sheremet-va
Copy link
Member

sheremet-va commented Apr 18, 2023

Node.js doesn't support module field, so Vitest cannot use it by default. You can force it by specifying resolve.mainFields:

export default defineConfig({
  resolve: {
    mainFields: ['module']
  }
})

But I would not recommend using it, since it is meant to be used by bundlers. If you want to publish actual ESM file that Node will understand, you need to use exports field in your package.json. Here is more info: https://github.com/sheremet-va/dual-packaging

@github-actions github-actions bot locked and limited conversation to collaborators Jun 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants