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

Node.js subpath import not working #6412

Closed
6 tasks done
JunyeongChoi0 opened this issue Aug 27, 2024 · 7 comments
Closed
6 tasks done

Node.js subpath import not working #6412

JunyeongChoi0 opened this issue Aug 27, 2024 · 7 comments

Comments

@JunyeongChoi0
Copy link

Describe the bug

I'm encountering an issue where the subpath import specified in package.json with the key 'test' does not seem to work with Vitest. Instead of resolving to the 'test' path, Vitest consistently resolves to the 'default' path.

  • I attempted to resolve this by adding resolve.conditions = ['test'] to vite.config.
  • I also tried running the test with an additional Node environment variable: NODE_OPTIONS="--conditions=test".
    However, neither of these approaches resolved the issue.

Below is my repro code - I also uploaded my repo link.

In package.json, I've defined the subpath import as follows:

"imports": {
    "#utils/service": {
      "test": "./src/utils/service.mock.ts",
      "default": "./src/utils/service.ts"
    },
    "#*": [
      "./src/*",
      "./src/*.ts",
      "./src/*.tsx",
      "./src/*/index.ts",
      "./src/*/index.tsx"
    ]
  },

Here is a simple React component importing service:

import { service } from "#utils/service";

export default function Component() {
  const [data, setData] = useState("");
  const [data2, setData2] = useState("");

  useEffect(() => {
    service.apiOne().then((response) => {
      setData(response);
    });
    service.apiTwo().then((response) => {
      setData2(response);
    });
  });

  return (
    <div>
      <div>this is data one: {data}</div>
      <div>this is data two: {data2}</div>
    </div>
  );
}

And here is the test code for the component:

import Component from "#components/Component";
import { render, screen } from "@testing-library/react";
import { it, expect } from "vitest";
import React from "react";


const setup = () => {
  render(<Component />);
};

it("yes mock", async () => {
  setup();
  expect(await screen.findByText(/api one mock/)).toBeInTheDocument();
});

Reproduction

https://github.com/JunyeongChoi0/vitest-repro

System Info

System:
    OS: macOS 14.5
    CPU: (10) arm64 Apple M1 Max
    Memory: 13.32 GB / 64.00 GB
    Shell: 3.2.57 - /bin/sh
  Binaries:
    Node: 20.16.0 - ~/.nvm/versions/node/v20.16.0/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.8.1 - ~/.nvm/versions/node/v20.16.0/bin/npm
    pnpm: 9.7.0 - ~/.nvm/versions/node/v20.16.0/bin/pnpm
  Browsers:
    Chrome: 127.0.6533.122
    Safari: 17.5
  npmPackages:
    @vitejs/plugin-react: ^4.3.1 => 4.3.1
    vite: ^5.4.1 => 5.4.2
    vitest: ^2.0.5 => 2.0.5

Used Package Manager

npm

Validations

@sheremet-va
Copy link
Member

sheremet-va commented Aug 27, 2024

Sorry, but I don't see any resolve.conditions in your reproduction. Adding this to the config makes tests pass:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    conditions: ['test']
  },
  plugins: [react()],
  test: {
    environment: "jsdom",
    setupFiles: ["./setupTest.ts"],
  },
});

@JunyeongChoi0
Copy link
Author

I must have confused something, sorry for bothering. Thanks!

@JunyeongChoi0
Copy link
Author

I discovered what was causing the issue and found workaround, and I’m sharing it here for anyone who might encounter the same problem.

Initially, I attempted to include the following code within the test object, but I later realized that there is no resolve.conditions option available in the Vitest configuration.

resolve: {
  conditions: ['test']
},

The documentation was a bit misleading for me, as it suggests that the Vite and Vitest configurations share the same structure, which isn’t entirely accurate.

"In addition to the following options, you can also use any configuration option from Vite. For example, define to define global variables, or resolve.alias to define aliases."

It wasn't until I checked the TypeScript type VitestInlineConfig that I understood resolve.conditions doesn't exist in the Vitest config.

Here’s the workaround I used:

const env = loadEnv(mode, process.cwd(), '')

// ...

resolve: {
  conditions: env.VITEST ? ['vitest'] : [],
},

@JunyeongChoi0
Copy link
Author

JunyeongChoi0 commented Aug 28, 2024

@sheremet-va And a question - why vitest does not support resolve.conditions option?

@sheremet-va
Copy link
Member

I don't know what you are talking about. Vitest config is Vite config with a test property. test property has its own options defined in the documentation, but all other options are inherited from the Vite config including plugins.

@JunyeongChoi0
Copy link
Author

Ah, I misunderstood. I thought the “vitest config” referred only to the configs within the test property. In that case, if I want to add a conditions array only in the vitest environment, is the workaround I mentioned the best option, or is there a better approach?

@sheremet-va
Copy link
Member

sheremet-va commented Aug 28, 2024

Ah, I misunderstood. I thought the “vitest config” referred only to the configs within the test property. In that case, if I want to add a conditions array only in the vitest environment, is the workaround I mentioned the best option, or is there a better approach?

You can create a separate file called vitest.config.ts: https://vitest.dev/config/file.html

Beware that it does not inherit your vite.config.

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

No branches or pull requests

2 participants