Skip to content

Commit b45bf94

Browse files
refactor(vite): load devtools resource (#521)
1 parent a44978f commit b45bf94

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

packages/vite/src/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function removeUrlQuery(url: string): string {
2+
return url.replace(/\?.*$/, '')
3+
}

packages/vite/src/vite.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { fileURLToPath } from 'node:url'
22
import path from 'node:path'
3+
import fs from 'node:fs'
34
import { normalizePath } from 'vite'
45
import type { PluginOption, ResolvedConfig, ViteDevServer } from 'vite'
56
import sirv from 'sirv'
@@ -11,6 +12,7 @@ import { bold, cyan, dim, green, yellow } from 'kolorist'
1112
import type { VitePluginInspectorOptions } from 'vite-plugin-vue-inspector'
1213
import { DIR_CLIENT } from './dir'
1314
import { getRpcFunctions } from './rpc'
15+
import { removeUrlQuery } from './utils'
1416

1517
function getVueDevtoolsPath() {
1618
const pluginPath = normalizePath(path.dirname(fileURLToPath(import.meta.url)))
@@ -26,6 +28,8 @@ function normalizeComboKeyPrint(toggleComboKey: string) {
2628
return toggleComboKey.split('-').map(key => toggleComboKeysMap[key] || key[0].toUpperCase() + key.slice(1)).join(dim('+'))
2729
}
2830

31+
const devtoolsNextResourceSymbol = '?__vue-devtools-next-resource'
32+
2933
export interface VitePluginVueDevToolsOptions {
3034
/**
3135
* append an import to the module id ending with `appendTo` instead of adding a script into body
@@ -118,6 +122,10 @@ export default function VitePluginVueDevTools(options?: VitePluginVueDevToolsOpt
118122
console.log(` ${green('➜')} ${bold('Vue DevTools')}: ${green(`Press ${yellow(keys)} in App to toggle the Vue DevTools`)}\n`)
119123
}
120124
}
125+
126+
const devtoolsOptionsImportee = 'virtual:vue-devtools-options'
127+
const resolvedDevtoolsOptions = `\0${devtoolsOptionsImportee}`
128+
121129
const plugin = <PluginOption>{
122130
name: 'vite-plugin-vue-devtools',
123131
enforce: 'pre',
@@ -129,17 +137,26 @@ export default function VitePluginVueDevTools(options?: VitePluginVueDevToolsOpt
129137
configureServer(server)
130138
},
131139
async resolveId(importee: string) {
132-
if (importee.startsWith('virtual:vue-devtools-options')) {
133-
return importee
140+
if (importee === devtoolsOptionsImportee) {
141+
return resolvedDevtoolsOptions
134142
}
143+
// Why use query instead of vite virtual module on devtools resource?
144+
// Devtools resource will import `@vue/devtools-core` and other packages, which vite cannot analysis correctly on virtual module.
145+
// So we should use absolute path + `query` to mark the resource as devtools resource.
135146
else if (importee.startsWith('virtual:vue-devtools-path:')) {
136147
const resolved = importee.replace('virtual:vue-devtools-path:', `${vueDevtoolsPath}/`)
137-
return resolved
148+
return `${resolved}${devtoolsNextResourceSymbol}`
138149
}
139150
},
140151
async load(id) {
141-
if (id === 'virtual:vue-devtools-options')
152+
if (id === resolvedDevtoolsOptions) {
142153
return `export default ${JSON.stringify({ base: config.base, componentInspector: pluginOptions.componentInspector })}`
154+
}
155+
else if (id.endsWith(devtoolsNextResourceSymbol)) {
156+
const filename = removeUrlQuery(id)
157+
// read file ourselves to avoid getting shut out by vite's fs.allow check
158+
return await fs.promises.readFile(filename, 'utf-8')
159+
}
143160
},
144161
transform(code, id, options) {
145162
if (options?.ssr)

0 commit comments

Comments
 (0)