Skip to content

Commit d9c2612

Browse files
committed
vite: Don't pass through plugins by default, add unstable_pluginFilter option
1 parent c432ff3 commit d9c2612

File tree

2 files changed

+67
-19
lines changed

2 files changed

+67
-19
lines changed

.changeset/three-shirts-knock.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
'@vanilla-extract/vite-plugin': major
3+
---
4+
5+
User-configured vite plugins are no longer forwarded through to the Vanilla Extract compiler by default.
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+
With 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.
10+
11+
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:
12+
13+
```ts
14+
// vite.config.ts
15+
16+
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
17+
import { vitePluginFoo } from 'vite-plugin-foo';
18+
19+
export default defineConfig({
20+
plugins: [
21+
vitePluginFoo(),
22+
vanillaExtractPlugin({
23+
// Only forward the `vite-plugin-foo` plugin through to the Vanilla Extract compiler
24+
unstable_pluginFilter: ({ name, mode }) => plugin.name === 'vite-plugin-foo',
25+
}),
26+
],
27+
});
28+
```
29+
30+
> [!NOTE]
31+
> When providing a plugin filter function, the `vite-tsconfig-paths` plugin will no longer be forwarded through by default.
32+
> If you wish to forward this plugin through, you must include it in your filter function.
33+
34+
> [!IMPORTANT]
35+
> 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

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,37 +19,48 @@ import {
1919
normalizePath,
2020
} from '@vanilla-extract/integration';
2121

22+
const PLUGIN_NAME = 'vite-plugin-vanilla-extract';
2223
const virtualExtCss = '.vanilla.css';
2324

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

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

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

101112
return {
102-
name: 'vanilla-extract',
113+
name: PLUGIN_NAME,
103114
configureServer(_server) {
104115
server = _server;
105116
},
@@ -148,7 +159,9 @@ export function vanillaExtractPlugin({
148159
...configForViteCompiler,
149160
plugins: configForViteCompiler?.plugins
150161
?.flat()
151-
.filter(removeIncompatiblePlugins),
162+
.filter(isPluginObject)
163+
// .filter(removeIncompatiblePlugins)
164+
.filter(withUserPluginFilter({ mode: config.mode, pluginFilter })),
152165
};
153166

154167
compiler = createCompiler({

0 commit comments

Comments
 (0)