Skip to content

Commit 7810b7c

Browse files
authoredJan 30, 2025··
vite: Don't pass through plugins by default, add unstable_pluginFilter option (#1537)

File tree

3 files changed

+75
-19
lines changed

3 files changed

+75
-19
lines changed
 

‎.changeset/metal-jars-fail.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@vanilla-extract/vite-plugin': major
3+
---
4+
5+
Change the plugin name from `"vanilla-extract"` to the more [conventional][plugin conventions] `"vite-plugin-vanilla-extract"`
6+
7+
[plugin conventions]: https://vite.dev/guide/api-plugin.html#conventions

‎.changeset/three-shirts-knock.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
'@vanilla-extract/vite-plugin': major
3+
---
4+
5+
BREAKING CHANGE: User-configured vite plugins are no longer forwarded through to the Vanilla Extract compiler by default. This should not affect most consumers.
6+
7+
Previously, all vite plugins except for a select few incompatible plugins were forwarded through. This resulted in a constant game of whack-a-mole as new plugins were added to the list of incompatible plugins as issues were discovered.
8+
9+
Framework-specific plugins, as well as plugins that handle assets and build output, tend not to be relevant to Vanilla Extract code, and in some cases cause more harm than good.
10+
11+
For that reason, in this release only the `vite-tsconfig-paths` plugin is fowarded through by default. This is a relatively common plugin that is know to be compatible with the Vanilla Extract compiler.
12+
13+
In most cases users should not need to forward any additional plugins through to the Vanilla Extract compiler. However, if such a case arises, a plugin filter function can be provided via the `unstable_pluginFilter` option:
14+
15+
```ts
16+
// vite.config.ts
17+
18+
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
19+
import { vitePluginFoo } from 'vite-plugin-foo';
20+
21+
export default defineConfig({
22+
plugins: [
23+
vitePluginFoo(),
24+
vanillaExtractPlugin({
25+
// Only forward the `vite-plugin-foo` plugin through to the Vanilla Extract compiler
26+
unstable_pluginFilter: ({ name, mode }) => plugin.name === 'vite-plugin-foo',
27+
}),
28+
],
29+
});
30+
```
31+
32+
> [!NOTE]
33+
> When providing a plugin filter function, the `vite-tsconfig-paths` plugin will no longer be forwarded through by default.
34+
> If you wish to forward this plugin through, you must include it in your filter function.
35+
36+
> [!IMPORTANT]
37+
> The `unstable_pluginFilter` API is considered unstable and may be changed or removed without notice in a future non-major version.

‎packages/vite-plugin/src/index.ts

+31-19
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,48 @@ import {
1818
normalizePath,
1919
} from '@vanilla-extract/integration';
2020

21+
const PLUGIN_NAME = 'vite-plugin-vanilla-extract';
2122
const virtualExtCss = '.vanilla.css';
2223

2324
const isVirtualId = (id: string) => id.endsWith(virtualExtCss);
2425
const fileIdToVirtualId = (id: string) => `${id}${virtualExtCss}`;
2526
const virtualIdToFileId = (virtualId: string) =>
2627
virtualId.slice(0, -virtualExtCss.length);
2728

28-
const removeIncompatiblePlugins = (plugin: PluginOption) =>
29-
typeof plugin === 'object' &&
30-
plugin !== null &&
31-
'name' in plugin &&
32-
// Prevent an infinite loop where the compiler creates a new instance of the plugin,
33-
// which creates a new compiler, which creates a new instance of the plugin, etc.
34-
plugin.name !== 'vanilla-extract' &&
35-
// Skip Remix because it throws an error if it's not loaded with a config file.
36-
// If it _is_ loaded with a config file, it will create an infinite loop because it
37-
// also has a child compiler which uses the same mechanism to load the config file.
38-
// https://github.com/remix-run/remix/pull/7990#issuecomment-1809356626
39-
// Additionally, some internal Remix plugins rely on a `ctx` object to be initialized by
40-
// the main Remix plugin, and may not function correctly without it. To address this, we
41-
// filter out all Remix-related plugins.
42-
!plugin.name.startsWith('remix') &&
43-
// As React-Router plugin works the same as Remix plugin, also ignore it.
44-
!plugin.name.startsWith('react-router');
29+
const isPluginObject = (plugin: PluginOption): plugin is Plugin =>
30+
typeof plugin === 'object' && plugin !== null && 'name' in plugin;
31+
32+
type PluginFilter = (filterProps: {
33+
/** The name of the plugin */
34+
name: string;
35+
/**
36+
* The `mode` vite is running in.
37+
* @see https://vite.dev/guide/env-and-mode.html#modes
38+
*/
39+
mode: string;
40+
}) => boolean;
4541

4642
interface Options {
4743
identifiers?: IdentifierOption;
44+
unstable_pluginFilter?: PluginFilter;
4845
unstable_mode?: 'transform' | 'emitCss';
4946
}
47+
48+
// Plugins that we know are compatible with the `vite-node` compiler
49+
// and don't need to be filtered out.
50+
const COMPATIBLE_PLUGINS = ['vite-tsconfig-paths'];
51+
52+
const defaultPluginFilter: PluginFilter = ({ name }) =>
53+
COMPATIBLE_PLUGINS.includes(name);
54+
55+
const withUserPluginFilter =
56+
({ mode, pluginFilter }: { mode: string; pluginFilter: PluginFilter }) =>
57+
(plugin: Plugin) =>
58+
pluginFilter({ name: plugin.name, mode });
59+
5060
export function vanillaExtractPlugin({
5161
identifiers,
62+
unstable_pluginFilter: pluginFilter = defaultPluginFilter,
5263
unstable_mode: mode = 'emitCss',
5364
}: Options = {}): Plugin {
5465
let config: ResolvedConfig;
@@ -98,7 +109,7 @@ export function vanillaExtractPlugin({
98109
}
99110

100111
return {
101-
name: 'vanilla-extract',
112+
name: PLUGIN_NAME,
102113
configureServer(_server) {
103114
server = _server;
104115
},
@@ -147,7 +158,8 @@ export function vanillaExtractPlugin({
147158
...configForViteCompiler,
148159
plugins: configForViteCompiler?.plugins
149160
?.flat()
150-
.filter(removeIncompatiblePlugins),
161+
.filter(isPluginObject)
162+
.filter(withUserPluginFilter({ mode: config.mode, pluginFilter })),
151163
};
152164

153165
compiler = createCompiler({

0 commit comments

Comments
 (0)
Please sign in to comment.