Skip to content

Commit

Permalink
fix: duplicate watcher, virtual module hmr
Browse files Browse the repository at this point in the history
  • Loading branch information
hemengke1997 committed Jul 31, 2024
1 parent d87951d commit 9ec4d8c
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 24 deletions.
2 changes: 1 addition & 1 deletion client.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './dist/client/index.js'
export * from './dist/client'
File renamed without changes.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"bump": "bumpp package.json -c --no-push -t --all -x \"pnpm run changelog\""
},
"peerDependencies": {
"esbuild": ">=0.19.0",
"esbuild": ">=0.21.3",
"vite": ">=4.0.0 || >=5.0.0"
},
"peerDependenciesMeta": {
Expand All @@ -71,6 +71,7 @@
"@babel/preset-typescript": "^7.24.1",
"browserslist": "^4.23.0",
"core-js": "^3.37.1",
"debounce": "^2.1.0",
"debug": "^4.3.4",
"esbuild": "^0.21.3",
"esbuild-plugin-browserslist": "^0.12.0",
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 13 additions & 4 deletions src/node/helper/file-watcher.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import debounce from 'debounce'
import createDebug from 'debug'
import path from 'node:path'
import colors from 'picocolors'
Expand Down Expand Up @@ -38,6 +39,10 @@ async function handleFileChange(filePath: string, cb?: () => void) {
handleFileAdded(filePath, cb)
}

function debounced(fn: () => void) {
debounce(fn, 200, { immediate: true })()
}

export async function initWatcher(cb: (file: HmrFile) => void) {
try {
const { default: Watcher } = await import('watcher')
Expand All @@ -49,16 +54,20 @@ export async function initWatcher(cb: (file: HmrFile) => void) {
renameTimeout: 100,
})

watcher.on('unlink', (filePath: string) => handleUnlink(filePath, () => cb({ path: filePath, event: 'deleted' })))
watcher.on('unlink', (filePath: string) =>
debounced(() => handleUnlink(filePath, () => cb({ path: filePath, event: 'deleted' }))),
)

watcher.on('add', (filePath: string) => handleFileAdded(filePath, () => cb({ path: filePath, event: 'added' })))
watcher.on('add', (filePath: string) =>
debounced(() => handleFileAdded(filePath, () => cb({ path: filePath, event: 'added' }))),
)

watcher.on('rename', async (f: string, fNext: string) => {
handleFileRenamed(f, fNext, () => cb({ path: fNext, event: `renamed` }))
debounced(() => handleFileRenamed(f, fNext, () => cb({ path: fNext, event: `renamed` })))
})

watcher.on('change', (filePath: string) => {
handleFileChange(filePath, () => cb({ path: filePath, event: 'changed' }))
debounced(() => handleFileChange(filePath, () => cb({ path: filePath, event: 'changed' })))
})

return watcher
Expand Down
38 changes: 29 additions & 9 deletions src/node/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type Watcher from 'watcher'
import createDebug from 'debug'
import fs from 'fs-extra'
import path from 'node:path'
import { type PluginOption, type ResolvedConfig } from 'vite'
import { type PluginOption, type ResolvedConfig, type ViteDevServer } from 'vite'
import { buildAllOnce } from './build'
import { globalConfig } from './global-config'
import { resolveOptions } from './helper/default-options'
Expand All @@ -18,17 +19,21 @@ import {
setupGlobalConfig,
setupManifestCache,
} from './helper/utils'
import { resolvedVirtualModuleId } from './helper/virtual'
import { type VitePublicTypescriptOptions } from './interface'
import { getManifest, manifestCache } from './manifest-cache'
import { getManifestInNode, manifestCache } from './manifest-cache'
import { pluginServer } from './plugins/server'
import { pluginVirtual } from './plugins/virtual'

const debug = createDebug('vite-plugin-public-typescript:index ===> ')

let wathcer: Watcher | undefined

export default function publicTypescript(options: VitePublicTypescriptOptions = {}) {
debug('user options:', options)

let viteConfig: ResolvedConfig
let server: ViteDevServer

let opts = {
...options,
Expand All @@ -48,12 +53,17 @@ export default function publicTypescript(options: VitePublicTypescriptOptions =
await setupGlobalConfig(viteConfig, opts)
await setupManifestCache(viteConfig, opts)
},
async configureServer(server) {
async configureServer(_server) {
server = _server
const { ws } = server

globalConfig.set('viteDevServer', server)

const wathcer = await initWatcher((file) => reloadPage(ws, file))
if (wathcer) {
wathcer.close()
}

wathcer = await initWatcher((file) => reloadPage(ws, file))
server.httpServer?.addListener('close', () => {
wathcer?.close()
})
Expand All @@ -65,7 +75,7 @@ export default function publicTypescript(options: VitePublicTypescriptOptions =

fs.ensureFileSync(manifestPath)

const parsedCacheJson = getManifest()
const parsedCacheJson = getManifestInNode()

debug('buildStart - parsedCacheJson:', parsedCacheJson)

Expand Down Expand Up @@ -137,10 +147,15 @@ export default function publicTypescript(options: VitePublicTypescriptOptions =
},
async handleHotUpdate(ctx) {
const { file } = ctx

const { moduleGraph } = server
moduleGraph.onFileChange(resolvedVirtualModuleId)
const module = moduleGraph.getModuleById(resolvedVirtualModuleId)
// virtual module hmr
if (module) {
moduleGraph.invalidateModule(module)
}
if (_isPublicTypescript(file) || isManifestFile(file)) {
debug('hmr disabled:', file)

return []
}
},
Expand All @@ -153,7 +168,12 @@ export default function publicTypescript(options: VitePublicTypescriptOptions =
return plugins as any
}

export { getManifest } from './manifest-cache'
export { type Scripts, type ScriptDescriptor, injectScripts, injectScriptsToHtml } from './plugins/inject-script'
export { getManifestInNode } from './manifest-cache'
export {
type ManifestScriptsFn,
type ScriptDescriptor,
injectScripts,
injectScriptsToHtml,
} from './plugins/inject-script'
export { publicTypescript }
export { type VitePublicTypescriptOptions }
2 changes: 1 addition & 1 deletion src/node/manifest-cache/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function saveManifestPathToDisk(cacheDir: string) {
})
}

export function getManifest(root?: string): Record<string, string> {
export function getManifestInNode(root?: string): Record<string, string> {
if (!isEmptyObject(manifestCache.getManifestJson())) {
return manifestCache.getManifestJson()
}
Expand Down
12 changes: 6 additions & 6 deletions src/node/plugins/inject-script.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { type HtmlTagDescriptor, type PluginOption } from 'vite'
import { VPPT_DATA_ATTR, injectTagsToHtml } from '../helper/html'
import { getManifest } from '../manifest-cache'
import { getManifestInNode } from '../manifest-cache'

export type ScriptDescriptor = Omit<HtmlTagDescriptor, 'tag'>[]
export type Scripts = (manifest: Record<string, string>) => ScriptDescriptor
export type ManifestScriptsFn = (manifest: Record<string, string>) => ScriptDescriptor

function generateScriptTags(scripts: Scripts) {
const _scripts = scripts(getManifest()) || []
function generateScriptTags(scripts: ManifestScriptsFn) {
const _scripts = scripts(getManifestInNode()) || []
const tags: HtmlTagDescriptor[] = _scripts.map((s) => ({
...s,
attrs: {
Expand All @@ -19,11 +19,11 @@ function generateScriptTags(scripts: Scripts) {
return tags
}

export function injectScriptsToHtml(html: string, scripts: Scripts) {
export function injectScriptsToHtml(html: string, scripts: ManifestScriptsFn) {
return injectTagsToHtml(html, generateScriptTags(scripts))
}

export function injectScripts(scripts: Scripts) {
export function injectScripts(scripts: ManifestScriptsFn) {
const plugin: PluginOption = {
name: 'vite:public-typescript:inject-script',
enforce: 'post',
Expand Down
4 changes: 2 additions & 2 deletions src/node/plugins/virtual.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type PluginOption } from 'vite'
import { resolvedVirtualModuleId, virtualModuleId } from '../helper/virtual'
import { getManifest } from '../manifest-cache'
import { getManifestInNode } from '../manifest-cache'

export function pluginVirtual(): PluginOption {
const plugin: PluginOption = {
Expand All @@ -18,7 +18,7 @@ export function pluginVirtual(): PluginOption {
},
async load(id) {
if (id === resolvedVirtualModuleId) {
return `export default ${JSON.stringify(getManifest())}`
return `export default ${JSON.stringify(getManifestInNode())}`
}
},
}
Expand Down

0 comments on commit 9ec4d8c

Please sign in to comment.