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

vite: Fall back to using inline config if a vite config file cannot be loaded #1395

Merged
merged 2 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rare-oranges-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@vanilla-extract/vite-plugin': patch
---

Fixes a bug that made the plugin incompatible with frameworks that use custom config files
74 changes: 46 additions & 28 deletions packages/vite-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import type {
ConfigEnv,
ViteDevServer,
Rollup,
PluginOption,
UserConfig,
} from 'vite';
import {
cssFileFilter,
Expand All @@ -24,6 +26,22 @@ const fileIdToVirtualId = (id: string) => `${id}${virtualExtCss}`;
const virtualIdToFileId = (virtualId: string) =>
virtualId.slice(0, -virtualExtCss.length);

const removeIncompatiblePlugins = (plugin: PluginOption) =>
typeof plugin === 'object' &&
plugin !== null &&
'name' in plugin &&
// Prevent an infinite loop where the compiler creates a new instance of the plugin,
// which creates a new compiler, which creates a new instance of the plugin, etc.
plugin.name !== 'vanilla-extract' &&
// Skip Remix because it throws an error if it's not loaded with a config file.
// If it _is_ loaded with a config file, it will create an infinite loop because it
// also has a child compiler which uses the same mechanism to load the config file.
// https://github.com/remix-run/remix/pull/7990#issuecomment-1809356626
// Additionally, some internal Remix plugins rely on a `ctx` object to be initialized by
// the main Remix plugin, and may not function correctly without it. To address this, we
// filter out all Remix-related plugins.
!plugin.name.startsWith('remix');

interface Options {
identifiers?: IdentifierOption;
unstable_mode?: 'transform' | 'emitCss';
Expand Down Expand Up @@ -120,39 +138,39 @@ export function vanillaExtractPlugin({
// Ensure we re-use the compiler instance between builds, e.g. in watch mode
if (mode !== 'transform' && !compiler) {
const { loadConfigFromFile } = await vitePromise;
const configFile = await loadConfigFromFile(
{
command: config.command,
mode: config.mode,
isSsrBuild: configEnv.isSsrBuild,
},
config.configFile,
);

let configForViteCompiler: UserConfig | undefined;

// The user has a vite config file
if (config.configFile) {
const configFile = await loadConfigFromFile(
{
command: config.command,
mode: config.mode,
isSsrBuild: configEnv.isSsrBuild,
},
config.configFile,
);

configForViteCompiler = configFile?.config;
}
// The user is using a vite-based framework that has a custom config file
else {
configForViteCompiler = config.inlineConfig;
}

const viteConfig = {
...configForViteCompiler,
plugins: configForViteCompiler?.plugins
?.flat()
.filter(removeIncompatiblePlugins),
};

compiler = createCompiler({
root: config.root,
identifiers: getIdentOption(),
cssImportSpecifier: fileIdToVirtualId,
viteConfig: {
...configFile?.config,
plugins: configFile?.config.plugins?.flat().filter(
(plugin) =>
typeof plugin === 'object' &&
plugin !== null &&
'name' in plugin &&
// Prevent an infinite loop where the compiler creates a new instance of the plugin,
// which creates a new compiler, which creates a new instance of the plugin, etc.
plugin.name !== 'vanilla-extract' &&
// Skip Remix because it throws an error if it's not loaded with a config file.
// If it _is_ loaded with a config file, it will create an infinite loop because it
// also has a child compiler which uses the same mechanism to load the config file.
// https://github.com/remix-run/remix/pull/7990#issuecomment-1809356626
// Additionally, some internal Remix plugins rely on a `ctx` object to be initialized by
// the main Remix plugin, and may not function correctly without it. To address this, we
// filter out all Remix-related plugins.
!plugin.name.startsWith('remix'),
),
},
viteConfig,
});
}
},
Expand Down