Skip to content

Commit

Permalink
feat: support 3.3 imported types hmr
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Apr 18, 2023
1 parent 8407cf6 commit bbd98fc
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
16 changes: 6 additions & 10 deletions src/pluginWebpack4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { clientCache, typeDepToSFCMap } from './resolveScript'
import fs = require('fs')
import { compiler as vueCompiler } from './compiler'
import { descriptorCache } from './descriptorCache'
import { needHMR } from './util'

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

Expand Down Expand Up @@ -117,16 +118,11 @@ class VueLoaderPlugin {
...rules,
]

// 3.3 HMR support
const isServer =
vueLoaderOptions.isServerBuild ?? compiler.options.target === 'node'
const isProduction =
compiler.options.mode === 'production' ||
process.env.NODE_ENV === 'production'
const needsHotReload =
!isServer && !isProduction && vueLoaderOptions.hotReload !== false

if (needsHotReload && vueCompiler.invalidateTypeCache) {
// 3.3 HMR support for imported types
if (
needHMR(vueLoaderOptions, compiler.options) &&
vueCompiler.invalidateTypeCache
) {
let watcher: any

const WatchPack = require('watchpack')
Expand Down
41 changes: 41 additions & 0 deletions src/pluginWebpack5.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import * as qs from 'querystring'
import type { VueLoaderOptions } from './'
import type { RuleSetRule, Compiler } from 'webpack'
import { needHMR } from './util'
import { clientCache, typeDepToSFCMap } from './resolveScript'
import { compiler as vueCompiler } from './compiler'
import { descriptorCache } from './descriptorCache'

const id = 'vue-loader-plugin'
const NS = 'vue-loader'
Expand Down Expand Up @@ -225,6 +229,43 @@ class VueLoaderPlugin {
...clonedRules,
...rules,
]

// 3.3 HMR support for imported types
if (
needHMR(vueLoaderOptions, compiler.options) &&
vueCompiler.invalidateTypeCache
) {
compiler.hooks.afterCompile.tap(id, (compilation) => {
if (compilation.compiler === compiler) {
for (const file of typeDepToSFCMap.keys()) {
compilation.fileDependencies.add(file)
}
}
})
compiler.hooks.watchRun.tap(id, () => {
if (!compiler.modifiedFiles) return
for (const file of compiler.modifiedFiles) {
vueCompiler.invalidateTypeCache(file)
const affectedSFCs = typeDepToSFCMap.get(file)
if (affectedSFCs) {
for (const sfc of affectedSFCs) {
// bust script resolve cache
const desc = descriptorCache.get(sfc)
if (desc) clientCache.delete(desc)
// force update importing SFC
// @ts-ignore
compiler.fileTimestamps.set(sfc, {
safeTime: Date.now(),
timestamp: Date.now(),
})
}
}
}
for (const file of compiler.removedFiles) {
vueCompiler.invalidateTypeCache(file)
}
})
}
}
}

Expand Down
14 changes: 13 additions & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import type { LoaderContext } from 'webpack'
import type { Compiler, LoaderContext } from 'webpack'
import type { SFCDescriptor, CompilerOptions } from 'vue/compiler-sfc'
import type { VueLoaderOptions } from '.'
import * as path from 'path'

export function needHMR(
vueLoaderOptions: VueLoaderOptions,
compilerOptions: Compiler['options']
) {
const isServer =
vueLoaderOptions.isServerBuild ?? compilerOptions.target === 'node'
const isProduction =
compilerOptions.mode === 'production' ||
process.env.NODE_ENV === 'production'
return !isServer && !isProduction && vueLoaderOptions.hotReload !== false
}

export function resolveTemplateTSOptions(
descriptor: SFCDescriptor,
options: VueLoaderOptions
Expand Down

0 comments on commit bbd98fc

Please sign in to comment.