From a42b9de4d6f6708b281e7ebced724915c30e7196 Mon Sep 17 00:00:00 2001 From: Wout Mertens Date: Tue, 22 Nov 2022 09:18:09 +0100 Subject: [PATCH] vite: support HMR --- .changeset/slimy-llamas-dream.md | 5 +++ packages/vite-plugin/src/index.ts | 52 ++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 .changeset/slimy-llamas-dream.md diff --git a/.changeset/slimy-llamas-dream.md b/.changeset/slimy-llamas-dream.md new file mode 100644 index 000000000..681ebaba5 --- /dev/null +++ b/.changeset/slimy-llamas-dream.md @@ -0,0 +1,5 @@ +--- +'@vanilla-extract/vite-plugin': minor +--- + +Hot module reloading now works for Qwik diff --git a/packages/vite-plugin/src/index.ts b/packages/vite-plugin/src/index.ts index 21195e75d..09e2dfe91 100644 --- a/packages/vite-plugin/src/index.ts +++ b/packages/vite-plugin/src/index.ts @@ -19,6 +19,7 @@ const styleUpdateEvent = (fileId: string) => const virtualExtCss = '.vanilla.css'; const virtualExtJs = '.vanilla.js'; +const virtualRE = /.vanilla.(css|js)$/; interface Options { identifiers?: IdentifierOption; @@ -78,6 +79,29 @@ export function vanillaExtractPlugin({ forceEmitCssInSsrBuild = true; } }, + // Re-parse .css.ts files when they change + async handleHotUpdate({ file, modules }) { + if (!cssFileFilter.test(file)) return; + try { + const virtualId = `${file}${ + config.command === 'build' || + // @ts-ignore -- ssr is there + (config.ssr && forceEmitCssInSsrBuild) + ? virtualExtCss + : virtualExtJs + }`; + const virtuals = server.moduleGraph.getModulesByFile(virtualId); + virtuals?.forEach((m) => server.moduleGraph.invalidateModule(m)); + // load new CSS + await server.ssrLoadModule(file); + return [...modules, ...(virtuals || [])]; + } catch (e) { + // eslint-disable-next-line no-console + console.error('vanilla-extract HMR error: ', e); + throw e; + } + }, + // Convert .vanilla.(js|css) URLs to their absolute version resolveId(source) { const [validId, query] = source.split('?'); if (!validId.endsWith(virtualExtCss) && !validId.endsWith(virtualExtJs)) { @@ -90,21 +114,25 @@ export function vanillaExtractPlugin({ ? source : getAbsoluteVirtualFileId(validId); - // There should always be an entry in the `cssMap` here. - // The only valid scenario for a missing one is if someone had written - // a file in their app using the .vanilla.js/.vanilla.css extension - if (cssMap.has(absoluteId)) { - // Keep the original query string for HMR. - return absoluteId + (query ? `?${query}` : ''); - } + // Keep the original query string for HMR. + return absoluteId + (query ? `?${query}` : ''); }, - load(id) { + // Provide virtual CSS content + async load(id) { const [validId] = id.split('?'); - if (!cssMap.has(validId)) { + if (!virtualRE.test(validId)) { return; } + if (!cssMap.has(validId)) { + // Try to parse the parent + const parentId = validId.replace(virtualRE, ''); + await server.ssrLoadModule(parentId); + // Now we should have the CSS + if (!cssMap.has(validId)) return; + } + const css = cssMap.get(validId); if (typeof css !== 'string') { @@ -132,6 +160,7 @@ export function vanillaExtractPlugin({ } `; }, + // Side-effect: If this results in new CSS, it will send HMR event async transform(code, id, ssrParam) { const [validId] = id.split('?'); @@ -189,10 +218,11 @@ export function vanillaExtractPlugin({ let cssSource = source; + // TODO It looks like Vite does this already? Should this go? if (postCssConfig) { const postCssResult = await (await import('postcss')) .default(postCssConfig.plugins) - .process(source, { + .process(cssSource, { ...postCssConfig.options, from: undefined, map: false, @@ -204,7 +234,7 @@ export function vanillaExtractPlugin({ if ( server && cssMap.has(absoluteId) && - cssMap.get(absoluteId) !== source + cssMap.get(absoluteId) !== cssSource ) { const { moduleGraph } = server; const [module] = Array.from(