Skip to content

Commit

Permalink
fix(vite): improve hmr by using hash instead of timestamp, close #176
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Aug 5, 2022
1 parent c97360a commit 6d8d75b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
36 changes: 22 additions & 14 deletions packages/vite/src/modes/global/dev.ts
@@ -1,10 +1,11 @@
import type { Plugin, Update, ViteDevServer, ResolvedConfig as ViteResolvedConfig } from 'vite'
import type { UnocssPluginContext } from '@unocss/core'
import { notNull } from '@unocss/core'
import { LAYER_MARK_ALL, getPath, resolveId, resolveLayer } from '../../integration'
import { LAYER_MARK_ALL, getHash, getPath, resolveId, resolveLayer } from '../../integration'

const WARN_TIMEOUT = 20000
const WS_EVENT_PREFIX = 'unocss:hmr'
const HASH_LENGTH = 6

export function GlobalModeDevPlugin({ uno, tokens, affectedModules, onInvalidate, extract, filter }: UnocssPluginContext): Plugin[] {
const servers: ViteDevServer[] = []
Expand All @@ -14,8 +15,7 @@ export function GlobalModeDevPlugin({ uno, tokens, affectedModules, onInvalidate
const entries = new Set<string>()

let invalidateTimer: any
let lastUpdate = Date.now()
let lastServed = 0
const lastServedHash = new Map<string, string>()
let resolved = false
let resolvedWarnTimer: any

Expand All @@ -37,11 +37,13 @@ export function GlobalModeDevPlugin({ uno, tokens, affectedModules, onInvalidate
}
}
clearTimeout(invalidateTimer)
invalidateTimer = setTimeout(() => sendUpdate(ids), timer)
invalidateTimer = setTimeout(() => {
lastServedHash.clear()
sendUpdate(ids)
}, timer)
}

function sendUpdate(ids: Set<string>) {
lastUpdate = Date.now()
for (const server of servers) {
server.ws.send({
type: 'update',
Expand All @@ -53,7 +55,7 @@ export function GlobalModeDevPlugin({ uno, tokens, affectedModules, onInvalidate
return <Update>{
acceptedPath: mod.url,
path: mod.url,
timestamp: lastUpdate,
timestamp: Date.now(),
type: 'js-update',
}
})
Expand All @@ -80,7 +82,7 @@ export function GlobalModeDevPlugin({ uno, tokens, affectedModules, onInvalidate
}

onInvalidate(() => {
invalidate(0, new Set([...entries, ...affectedModules]))
invalidate(10, new Set([...entries, ...affectedModules]))
})

return [
Expand All @@ -92,9 +94,9 @@ export function GlobalModeDevPlugin({ uno, tokens, affectedModules, onInvalidate
async configureServer(_server) {
servers.push(_server)

_server.ws.on(WS_EVENT_PREFIX, (servedTime: number) => {
if (servedTime < lastUpdate)
invalidate(0)
_server.ws.on(WS_EVENT_PREFIX, ([layer, hash]: string[]) => {
if (lastServedHash.get(layer) !== hash)
invalidate(10)
})
},
buildStart() {
Expand Down Expand Up @@ -128,11 +130,15 @@ export function GlobalModeDevPlugin({ uno, tokens, affectedModules, onInvalidate

await Promise.all(tasks)
const result = await uno.generate(tokens)
lastServed = Date.now()
return layer === LAYER_MARK_ALL

const css = layer === LAYER_MARK_ALL
? result.getLayers(undefined, Array.from(entries)
.map(i => resolveLayer(i)).filter((i): i is string => !!i))
: result.getLayer(layer)
const hash = getHash(css || '', HASH_LENGTH)
lastServedHash.set(layer, hash)
// add hash to the chunk of CSS that it will send back to client to check if there is new CSS generated
return `/*${hash}*/${css}`
},
},
{
Expand All @@ -143,11 +149,13 @@ export function GlobalModeDevPlugin({ uno, tokens, affectedModules, onInvalidate
},
enforce: 'post',
transform(code, id) {
const layer = resolveLayer(getPath(id))

// inject css modules to send callback on css load
if (entries.has(getPath(id)) && code.includes('import.meta.hot')) {
if (layer && code.includes('import.meta.hot')) {
return `${code}
if (import.meta.hot) {
try { await import.meta.hot.send('${WS_EVENT_PREFIX}', ${lastServed}); }
try { await import.meta.hot.send('${WS_EVENT_PREFIX}', ['${layer}', __vite__css.slice(2,${2 + HASH_LENGTH})]); }
catch (e) { console.warn('[unocss-hmr]', e) }
if (!import.meta.url.includes('?'))
await new Promise(resolve => setTimeout(resolve, 100))
Expand Down
4 changes: 4 additions & 0 deletions playground/src/auto-imports.d.ts
Expand Up @@ -199,9 +199,11 @@ declare global {
const usePermission: typeof import('@vueuse/core')['usePermission']
const usePointer: typeof import('@vueuse/core')['usePointer']
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
const usePrecision: typeof import('@vueuse/math')['usePrecision']
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
const useProjection: typeof import('@vueuse/math')['useProjection']
const useRafFn: typeof import('@vueuse/core')['useRafFn']
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
Expand Down Expand Up @@ -238,6 +240,8 @@ declare global {
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
const useTitle: typeof import('@vueuse/core')['useTitle']
const useToFixed: typeof import('@vueuse/math')['useToFixed']
const useToNumber: typeof import('@vueuse/core')['useToNumber']
const useToString: typeof import('@vueuse/core')['useToString']
const useToggle: typeof import('@vueuse/core')['useToggle']
const useTransition: typeof import('@vueuse/core')['useTransition']
const useTrunc: typeof import('@vueuse/math')['useTrunc']
Expand Down

0 comments on commit 6d8d75b

Please sign in to comment.