vitejs / vite-plugin-react-swc

Speed up your Vite dev server with SWC
MIT License
781 stars 50 forks source link

Feature request: Add "include" and "exclude" option just like in `@vitejs/plugin-react` #47

Closed xsjcTony closed 1 year ago

xsjcTony commented 1 year ago

Unfortunately, this package currently does not support "include" and "exclude" options just like in @vitejs/plugin-react

ArnaudBarre commented 1 year ago

Hi! What's the need/use case behind this?

xsjcTony commented 1 year ago

@ArnaudBarre Hey, thanks for the reply. My use case is to exclude test files.

All my test files are under /src/__tests__ folder, using Vitest, and whenever I changed some test file, the dev server will refresh the page. So I want to exclude those files from triggering HMR.

ArnaudBarre commented 1 year ago

This is not something that can be changed by a plugin. You can use https://vitejs.dev/config/server-options.html#server-watch to ignore test files.

Maybe we should change how files are watched by default, I will discuss this with the team.

xsjcTony commented 1 year ago

@ArnaudBarre Hey, I've tried your suggestion but unfortunately, it won't work. It will disable the HMR for vitest as well.

Usually, we will write vitest config inside vite.config.ts so we don't need to repeat those shared configs like resolve.alias.

The only solution is to create another vitest.config.ts and copy those shared configs, so server.watch.ignored won't apply to Vitest... which means I need to change in two places whenever those shared configs need to change

A little bit frustrating...

ArnaudBarre commented 1 year ago

Technically you could share some config via a third file imported in both. But that's a bit frustrating I agree.

Are you using Tailwind? I think this could be the cause of the fact that test files triggers a refresh

xsjcTony commented 1 year ago

Yeah exactly. I was wondering why it will trigger the refresh... Looking forward to hearing about what's happening under the hood if you have time.

ArnaudBarre commented 1 year ago

The simple solution is to remove __test__ from Tailwind content.

Here is a plugin I added to a project to solve this issue more globally for an SPA. Maybe this could be fixed in core but not sure we can have an exact list of entry points. You can thanks @liautaud for writing down this nice comment.

    {
      name: "fix-tailwind-page-reload",
      apply: "serve",
      /**
       * Fixes a bug in the interaction between Tailwind and Vite where creating
       * or editing un-imported or type-only TS files would trigger a full reload.
       *
       * In short, the issue is that Tailwind needs to listen to changes in all
       * TS files in development, which it accomplishes in a hacky way by adding
       * an edge between `index.css` and every TS file in the Vite dependency
       * graph–even if the file is otherwise un-imported or contains only types.
       *
       * This lead to a bug in Vite where TS or HTML files imported by no other
       * file were not being treated as entry-points because they were being
       * "implicitly" imported by `index.css`, which was mitigated in vite#3929
       * by treating files as entry-points if they are only being imported by
       * CSS files. Unfortunately, since the Vite dependency graph also contains
       * un-imported and type-only files, these get treated as entry-points too,
       * and so they trigger a full page reload.
       *
       * In our case, though, we know that the only entry-point is `index.tsx`,
       * so we can avoid the issue altogether by hooking into `handleHotUpdate`
       * (see https://vitejs.dev/guide/api-plugin.html#handlehotupdate) and
       * disabling full page reloads for "wrong" entry-points, i.e. files being
       * imported only by CSS files which are not `index.tsx`.
       */
      handleHotUpdate({ file, modules }) {
        if (
          modules.every((m) =>
            [...m.importers].every((i) => i.url.endsWith(".css")),
          ) &&
          !file.endsWith("src/index.tsx")
        ) {
          return [];
        }
      },