Skip to content

Commit bbd98fc

Browse files
committed
feat: support 3.3 imported types hmr
1 parent 8407cf6 commit bbd98fc

File tree

3 files changed

+60
-11
lines changed

3 files changed

+60
-11
lines changed

src/pluginWebpack4.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { clientCache, typeDepToSFCMap } from './resolveScript'
55
import fs = require('fs')
66
import { compiler as vueCompiler } from './compiler'
77
import { descriptorCache } from './descriptorCache'
8+
import { needHMR } from './util'
89

910
const RuleSet = require('webpack/lib/RuleSet')
1011

@@ -117,16 +118,11 @@ class VueLoaderPlugin {
117118
...rules,
118119
]
119120

120-
// 3.3 HMR support
121-
const isServer =
122-
vueLoaderOptions.isServerBuild ?? compiler.options.target === 'node'
123-
const isProduction =
124-
compiler.options.mode === 'production' ||
125-
process.env.NODE_ENV === 'production'
126-
const needsHotReload =
127-
!isServer && !isProduction && vueLoaderOptions.hotReload !== false
128-
129-
if (needsHotReload && vueCompiler.invalidateTypeCache) {
121+
// 3.3 HMR support for imported types
122+
if (
123+
needHMR(vueLoaderOptions, compiler.options) &&
124+
vueCompiler.invalidateTypeCache
125+
) {
130126
let watcher: any
131127

132128
const WatchPack = require('watchpack')

src/pluginWebpack5.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import * as qs from 'querystring'
22
import type { VueLoaderOptions } from './'
33
import type { RuleSetRule, Compiler } from 'webpack'
4+
import { needHMR } from './util'
5+
import { clientCache, typeDepToSFCMap } from './resolveScript'
6+
import { compiler as vueCompiler } from './compiler'
7+
import { descriptorCache } from './descriptorCache'
48

59
const id = 'vue-loader-plugin'
610
const NS = 'vue-loader'
@@ -225,6 +229,43 @@ class VueLoaderPlugin {
225229
...clonedRules,
226230
...rules,
227231
]
232+
233+
// 3.3 HMR support for imported types
234+
if (
235+
needHMR(vueLoaderOptions, compiler.options) &&
236+
vueCompiler.invalidateTypeCache
237+
) {
238+
compiler.hooks.afterCompile.tap(id, (compilation) => {
239+
if (compilation.compiler === compiler) {
240+
for (const file of typeDepToSFCMap.keys()) {
241+
compilation.fileDependencies.add(file)
242+
}
243+
}
244+
})
245+
compiler.hooks.watchRun.tap(id, () => {
246+
if (!compiler.modifiedFiles) return
247+
for (const file of compiler.modifiedFiles) {
248+
vueCompiler.invalidateTypeCache(file)
249+
const affectedSFCs = typeDepToSFCMap.get(file)
250+
if (affectedSFCs) {
251+
for (const sfc of affectedSFCs) {
252+
// bust script resolve cache
253+
const desc = descriptorCache.get(sfc)
254+
if (desc) clientCache.delete(desc)
255+
// force update importing SFC
256+
// @ts-ignore
257+
compiler.fileTimestamps.set(sfc, {
258+
safeTime: Date.now(),
259+
timestamp: Date.now(),
260+
})
261+
}
262+
}
263+
}
264+
for (const file of compiler.removedFiles) {
265+
vueCompiler.invalidateTypeCache(file)
266+
}
267+
})
268+
}
228269
}
229270
}
230271

src/util.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1-
import type { LoaderContext } from 'webpack'
1+
import type { Compiler, LoaderContext } from 'webpack'
22
import type { SFCDescriptor, CompilerOptions } from 'vue/compiler-sfc'
33
import type { VueLoaderOptions } from '.'
44
import * as path from 'path'
55

6+
export function needHMR(
7+
vueLoaderOptions: VueLoaderOptions,
8+
compilerOptions: Compiler['options']
9+
) {
10+
const isServer =
11+
vueLoaderOptions.isServerBuild ?? compilerOptions.target === 'node'
12+
const isProduction =
13+
compilerOptions.mode === 'production' ||
14+
process.env.NODE_ENV === 'production'
15+
return !isServer && !isProduction && vueLoaderOptions.hotReload !== false
16+
}
17+
618
export function resolveTemplateTSOptions(
719
descriptor: SFCDescriptor,
820
options: VueLoaderOptions

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy