1
1
import { fileURLToPath } from 'node:url'
2
2
import path from 'node:path'
3
+ import fs from 'node:fs'
3
4
import { normalizePath } from 'vite'
4
5
import type { PluginOption , ResolvedConfig , ViteDevServer } from 'vite'
5
6
import sirv from 'sirv'
@@ -11,6 +12,7 @@ import { bold, cyan, dim, green, yellow } from 'kolorist'
11
12
import type { VitePluginInspectorOptions } from 'vite-plugin-vue-inspector'
12
13
import { DIR_CLIENT } from './dir'
13
14
import { getRpcFunctions } from './rpc'
15
+ import { removeUrlQuery } from './utils'
14
16
15
17
function getVueDevtoolsPath ( ) {
16
18
const pluginPath = normalizePath ( path . dirname ( fileURLToPath ( import . meta. url ) ) )
@@ -26,6 +28,8 @@ function normalizeComboKeyPrint(toggleComboKey: string) {
26
28
return toggleComboKey . split ( '-' ) . map ( key => toggleComboKeysMap [ key ] || key [ 0 ] . toUpperCase ( ) + key . slice ( 1 ) ) . join ( dim ( '+' ) )
27
29
}
28
30
31
+ const devtoolsNextResourceSymbol = '?__vue-devtools-next-resource'
32
+
29
33
export interface VitePluginVueDevToolsOptions {
30
34
/**
31
35
* 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
118
122
console . log ( ` ${ green ( '➜' ) } ${ bold ( 'Vue DevTools' ) } : ${ green ( `Press ${ yellow ( keys ) } in App to toggle the Vue DevTools` ) } \n` )
119
123
}
120
124
}
125
+
126
+ const devtoolsOptionsImportee = 'virtual:vue-devtools-options'
127
+ const resolvedDevtoolsOptions = `\0${ devtoolsOptionsImportee } `
128
+
121
129
const plugin = < PluginOption > {
122
130
name : 'vite-plugin-vue-devtools' ,
123
131
enforce : 'pre' ,
@@ -129,17 +137,26 @@ export default function VitePluginVueDevTools(options?: VitePluginVueDevToolsOpt
129
137
configureServer ( server )
130
138
} ,
131
139
async resolveId ( importee : string ) {
132
- if ( importee . startsWith ( 'virtual:vue-devtools-options' ) ) {
133
- return importee
140
+ if ( importee === devtoolsOptionsImportee ) {
141
+ return resolvedDevtoolsOptions
134
142
}
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.
135
146
else if ( importee . startsWith ( 'virtual:vue-devtools-path:' ) ) {
136
147
const resolved = importee . replace ( 'virtual:vue-devtools-path:' , `${ vueDevtoolsPath } /` )
137
- return resolved
148
+ return ` ${ resolved } ${ devtoolsNextResourceSymbol } `
138
149
}
139
150
} ,
140
151
async load ( id ) {
141
- if ( id === 'virtual:vue-devtools-options' )
152
+ if ( id === resolvedDevtoolsOptions ) {
142
153
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
+ }
143
160
} ,
144
161
transform ( code , id , options ) {
145
162
if ( options ?. ssr )
0 commit comments