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

Remix and Vitest: "$RefreshSig$ is not defined" #8094

Closed
manzaloros opened this issue Nov 21, 2023 · 7 comments
Closed

Remix and Vitest: "$RefreshSig$ is not defined" #8094

manzaloros opened this issue Nov 21, 2023 · 7 comments

Comments

@manzaloros
Copy link

manzaloros commented Nov 21, 2023

Reproduction

Set up Vitest.

// vite.config.ts
import { unstable_vitePlugin as remix } from "@remix-run/dev";
import { defineConfig, mergeConfig } from "vite";
import { defineConfig as defineVitestConfig } from "vitest/config";
import tsconfigPaths from "vite-tsconfig-paths";
import { HTTPS_CONFIG } from "./server/app-config";

const vitestConfig = defineVitestConfig({
  test: {
    globals: true,
    environment: "jsdom",
    setupFiles: "./__tests__/setup.ts",
  },
});

export const viteConfig = defineConfig({
  plugins: [
    remix({
      ignoredRouteFiles: ["**/.*"],
      serverModuleFormat: "esm",
    }),
    tsconfigPaths(),
  ],
  build: {
    target: "ES2022",
  },
  server: {
    https: {
      ca: HTTPS_CONFIG.ca,
      cert: HTTPS_CONFIG.cert,
      key: HTTPS_CONFIG.key,
      rejectUnauthorized: HTTPS_CONFIG.rejectUnauthorized,
      requestCert: HTTPS_CONFIG.requestCert,
    },
  },
});

export default mergeConfig(viteConfig, vitestConfig);

Set up a test file with the example from the Remix docs:

describe("Renders main page correctly", async () => {
  it("Should render the page correctly", async () => {
    function MyComponent() {
      const data = useLoaderData() as { message: string };
      return <p>Message: {data.message}</p>;
    }

    const RemixStub = createRemixStub([
      {
        path: "/",
        Component: MyComponent,
        loader() {
          return json({ message: "hello" });
        },
      },
    ]);
  });
});

System Info

System:
    OS: macOS 14.1.1
    CPU: (10) x64 Apple M1 Pro
    Memory: 63.03 MB / 32.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 20.5.0 - ~/.volta/tools/image/node/20.5.0/bin/node
    Yarn: 1.22.19 - ~/.volta/tools/image/yarn/1.22.19/bin/yarn
    npm: 9.8.0 - ~/.volta/tools/image/node/20.5.0/bin/npm
  Browsers:
    Chrome: 119.0.6045.159
    Edge: 119.0.2151.72
    Safari: 17.1
  npmPackages:
    @remix-run/css-bundle: 2.3.0 => 2.3.0 
    @remix-run/dev: 2.3.0 => 2.3.0 
    @remix-run/eslint-config: 2.3.0 => 2.3.0 
    @remix-run/express: 2.3.0 => 2.3.0 
    @remix-run/node: 2.3.0 => 2.3.0 
    @remix-run/react: 2.3.0 => 2.3.0 
    @remix-run/testing: ^2.3.0 => 2.3.0 
    vite: ^4.5.0 => 4.5.0

Used Package Manager

yarn

Expected Behavior

The example test file will pass the test.

Actual Behavior

This error is thrown in the console:

ReferenceError: $RefreshSig$ is not defined
 ❯ __tests__/sample.test.tsx:16:54
     14| 
     15| describe("Renders main page correctly", async () => {
     16|   it("Should render the page correctly", async () => {
       |                                                      ^
     17|     // const RemixStub = createRemixStub([
     18|     //   {
@hi-ogawa
Copy link
Contributor

hi-ogawa commented Nov 22, 2023

Would you check if it works by disabling remix plugin like in #7918 (comment)?
I think applying remix plugin during test shouldn't be necessary (and probably it has unintended negative effect at least for perf), so for now, recommended solution is to disable the plugin by the user side.
(There might be a way to transparently handle this kind of scenario on plugin side, but I couldn't come up with a robust way to do this yet.)

@john-griffin
Copy link

john-griffin commented Nov 23, 2023

Also hit this. There is some additonal config complexity when disabling the remix plugin in test mode. You need to manually load the env vars, more context #7934 (comment)

I was hoping to remove this work around when 2.3.0 came out but it's still needed in test mode as you can't use the plugin.

@hi-ogawa
Copy link
Contributor

@john-griffin Would you elaborate your current workaround?
I'm also curious how you have been using vitest for remix project before remix's vite integration (or did you start to use vitest after remix introduced vite integration?).
I think Vitest loads env file but only for VITE_... by default. Vitest regards this as a limitation of vite vitest-dev/vitest#1148 (comment) and also seems to suggest doing loadEnv explicitly for example in setupFiles.

I'm also hoping if there is a way to reduce these frictions out-of-the-box when integrating vite remix plugin, but at this stage, I think it's important to gather use cases and understand what's the actual issues before trying to come up with a general solution.

@john-griffin
Copy link

@hi-ogawa this is a new remix app started with the vite integration from scratch.

We followed the @markdalgleish suggestion here #7934 (comment) that loads the env vars in. We are also following his suggestion here #7958 (comment) around use of process.env vs import.meta.env

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Nov 24, 2023

@john-griffin Thanks for reporting back!

I think I understand the clumsiness you are experiencing, but it would be still helpful if you can provide an exact code snippet of what you do so that we can understand the problems better.

From what I can guess, I made an example repo to show how remix users can handle .env.test on vitest:
https://github.com/hi-ogawa/remix-vite-vitest-example

Here is how vite.config.ts looks like and personally this looks reasonably clean and explicit workaround.
Please let me know how this setup compares with your current workaround.

//
// vite.config.ts
//
import { unstable_vitePlugin as remix } from "@remix-run/dev";
import { defineConfig, loadEnv } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [
    // disable remix plugin for vitest
    !process.env.VITEST && remix(),
    tsconfigPaths(),
  ],
  test: {
    environment: "happy-dom",
    // load variable without "VITE_" prefix in ".env.test"
    env: loadEnv("test", process.cwd(), ""),
  },
});

My current view is that it's fine for remix to see this as a limitation of Vitest (which in turn says it's a limitation of Vite).
Instead of trying to solve this on remix plugin itself, I think it would make more sense to explain this limitation and include example setup in the documentation so people can easily figure it out.

@john-griffin
Copy link

@hi-ogawa thank you! That config works great and is exactly what we needed - much cleaner more targeted approach. Yes some documentation around this would be very helpful!

@pcattori
Copy link
Contributor

We now have docs for Storybook and Vitest integration

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

No branches or pull requests

5 participants