@@ -209,7 +209,13 @@ export interface StartOptions {
209209 * @default undefined (probe env.ts / env.js; off when absent)
210210 */
211211 env ?: boolean | string ;
212- /** Enable the development toolbar. @default true */
212+ /**
213+ * Enable the development toolbar. By default it is enabled when
214+ * `@solidjs/start-devtools` is installed. Setting this to `true` requires
215+ * the package, while `false` disables it.
216+ *
217+ * @default undefined
218+ */
213219 devtools ?: boolean ;
214220 /**
215221 * Add the default production error boundary to generated entries.
@@ -435,7 +441,8 @@ export function startServe(
435441 const serverComponents = ! ! internal . serverComponents ;
436442 const errorBoundary = options . errorBoundary !== false ;
437443 const styleFilter = internal . styleFilter ;
438- const devtools = options . devtools !== false ;
444+ let devtools : boolean | undefined = false ;
445+ let devtoolsResolution : Promise < boolean > | undefined ;
439446 // `external` is server-mode-only (documented no-op in client mode, so a
440447 // host-integrated config survives the `ssr` boolean flip untouched).
441448 const externalServer = ! clientMode && ! ! options . external ;
@@ -454,6 +461,19 @@ export function startServe(
454461 return entries ;
455462 }
456463
464+ async function resolveDevtools ( resolve : ( ) => Promise < unknown > ) : Promise < boolean > {
465+ if ( devtools !== undefined ) return devtools ;
466+ devtoolsResolution ??= resolve ( ) . then ( Boolean ) ;
467+ devtools = await devtoolsResolution ;
468+ if ( ! devtools && options . devtools === true ) {
469+ throw new Error (
470+ '[@solidjs/vite-plugin] start.devtools requires @solidjs/start-devtools. ' +
471+ 'Install it as a development dependency or set start.devtools to false.' ,
472+ ) ;
473+ }
474+ return devtools ;
475+ }
476+
457477 /** Import specifier for generated code: absolute for files, id for virtuals. */
458478 function entryServerSpec ( ) : string {
459479 const { entryServer } = requireEntries ( ) ;
@@ -631,9 +651,8 @@ export function startServe(
631651 ] . join ( '\n' ) ;
632652 }
633653
634- function generatedEntryClientCode ( ) : string {
654+ function generatedEntryClientCode ( toolbar : boolean ) : string {
635655 const { app } = requireEntries ( ) ;
636- const toolbar = devtools && ! isBuild ;
637656 if ( clientMode ) {
638657 // render(), not hydrate(): the shell's body is empty, the app mounts
639658 // fresh. Client code compiles non-hydratable in client mode, so the
@@ -1001,6 +1020,11 @@ export function startServe(
10011020 enforce : 'pre' ,
10021021 config ( userConfig , env ) {
10031022 root = path . resolve ( userConfig . root || process . cwd ( ) ) ;
1023+ devtools =
1024+ env . command === 'serve' && ! env . isPreview && options . devtools !== false
1025+ ? undefined
1026+ : false ;
1027+ devtoolsResolution = undefined ;
10041028 entries = resolveEntries ( root , options , clientMode ) ;
10051029 middlewarePath = options . middleware
10061030 ? path . resolve ( root , normalizeUserPath ( root , options . middleware , 'middleware' ) )
@@ -1141,7 +1165,7 @@ export function startServe(
11411165 ) {
11421166 return { id : source , moduleSideEffects : source === ENTRY_CLIENT_ID } ;
11431167 }
1144- if ( ! isBuild && devtools && ( source === DEVTOOLS_ID || source === DEVTOOLS_MOUNT_ID ) ) {
1168+ if ( devtools && ( source === DEVTOOLS_ID || source === DEVTOOLS_MOUNT_ID ) ) {
11451169 return { id : source , moduleSideEffects : true } ;
11461170 }
11471171 return null ;
@@ -1165,7 +1189,12 @@ export function startServe(
11651189 return devStylesModuleCode ( this . environment , ( file ) => this . addWatchFile ( file ) ) ;
11661190 }
11671191 if ( id === ENTRY_SERVER_ID ) return generatedEntryServerCode ( ) ;
1168- if ( id === ENTRY_CLIENT_ID ) return generatedEntryClientCode ( ) ;
1192+ if ( id === ENTRY_CLIENT_ID ) {
1193+ const toolbar = await resolveDevtools ( ( ) =>
1194+ this . resolve ( '@solidjs/start-devtools' , requireEntries ( ) . app ! , { skipSelf : true } ) ,
1195+ ) ;
1196+ return generatedEntryClientCode ( toolbar ) ;
1197+ }
11691198 if ( id === DOCUMENT_ID ) return documentShellCode ;
11701199 if ( id === ERROR_BOUNDARY_ID ) return errorBoundaryCode ;
11711200 if ( id === DEVTOOLS_ID || id === DEVTOOLS_MOUNT_ID ) {
@@ -1176,13 +1205,17 @@ export function startServe(
11761205 }
11771206 return null ;
11781207 } ,
1179- transform ( code , id , opts ) {
1180- if ( isBuild || ! devtools ) return null ;
1208+ async transform ( code , id , opts ) {
1209+ if ( isBuild || devtools === false ) return null ;
11811210 const current = requireEntries ( ) ;
11821211 if ( current . generated || getEnvironmentConsumer ( this . environment , opts ) !== 'client' ) {
11831212 return null ;
11841213 }
11851214 if ( id . split ( '?' ) [ 0 ] !== path . resolve ( root , current . entryClient ) ) return null ;
1215+ const toolbar = await resolveDevtools ( ( ) =>
1216+ this . resolve ( '@solidjs/start-devtools' , id , { skipSelf : true } ) ,
1217+ ) ;
1218+ if ( ! toolbar ) return null ;
11861219 return {
11871220 code : `import ${ JSON . stringify ( DEVTOOLS_MOUNT_ID ) } ;\n${ code } ` ,
11881221 map : null ,
0 commit comments