Skip to content

Commit

Permalink
fix: support user baseURL, close #506
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Nov 20, 2023
1 parent e604124 commit 2697340
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 25 deletions.
4 changes: 3 additions & 1 deletion packages/devtools/client/components/BuildAnalyzeDetails.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<script setup lang="ts">
import { formatTimeAgo } from '@vueuse/core'
import type { AnalyzeBuildMeta } from '../../src/types'
import { useRuntimeConfig } from '#imports'
const props = defineProps<{
current: AnalyzeBuildMeta
prev?: AnalyzeBuildMeta
}>()
const ROUTE_ANALYZE = '/__nuxt_devtools__/analyze/'
const runtimeConfig = useRuntimeConfig()
const ROUTE_ANALYZE = `${runtimeConfig.app.baseURL}/__nuxt_devtools__/analyze/`.replace(/\/+/g, '/')
const tabs = computed(() => {
const items = [
Expand Down
18 changes: 10 additions & 8 deletions packages/devtools/client/composables/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,19 @@ export const rpc = createBirpc<ServerFunctions, ClientFunctions>(clientFunctions
})

async function connectVite() {
let base = window.parent?.__NUXT__?.config?.app?.baseURL
let base = window.parent?.__NUXT__?.config?.app?.baseURL ?? '/'
const buildAssetsDir = window.parent?.__NUXT__?.config?.app.buildAssetsDir.replace(/^\/|\/$/g, '') ?? '_nuxt'
if (base && !base.endsWith('/'))
base += '/'
const hot = await tryCreateHotContext(undefined, [
...(base
? [`${base}${buildAssetsDir}/`, base]
: []),
'/_nuxt/',
'/',
])
const current = window.location.href.replace(/\/__nuxt_devtools__\/client\/.*$/, '/')
const hot = await tryCreateHotContext(undefined, Array.from(new Set([
current,
`${current}${buildAssetsDir}/`,
`${current}_nuxt/`,
base,
`${base}${buildAssetsDir}/`,
`${base}_nuxt/`,
])))

if (!hot) {
wsConnecting.value = true
Expand Down
15 changes: 13 additions & 2 deletions packages/devtools/client/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ export default defineNuxtConfig({
DevTools,
],
ssr: false,
pages: true,
nitro: {
preset: 'static',
output: {
publicDir: r('../dist/client'),
},
Expand All @@ -26,6 +24,12 @@ export default defineNuxtConfig({
base: r('./.data/test'),
},
},
hooks: {
'prerender:routes': function (routes) {
// Disable prerendering as it's an SPA
routes.clear()
},
},
},
alias: {
'@nuxt/devtools-kit/iframe-client': r('../../devtools-kit/src/runtime/iframe-client'),
Expand Down Expand Up @@ -70,4 +74,11 @@ export default defineNuxtConfig({
typescript: {
includeWorkspace: true,
},
// Production Overrides
$production: {
app: {
// We set a placeholder for the middleware to be replaced with the correct base URL
baseURL: '/__NUXT_DEVTOOLS_BASE__/',
},
},
})
6 changes: 0 additions & 6 deletions packages/devtools/src/constant.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { provider } from 'std-env'
import type { ModuleOptions, NuxtDevToolsOptions } from './types'

export const ROUTE_PATH = '/__nuxt_devtools__'
export const ROUTE_ENTRY = `${ROUTE_PATH}/entry`
export const ROUTE_CLIENT = `${ROUTE_PATH}/client`
export const ROUTE_AUTH = `${ROUTE_PATH}/auth`
export const ROUTE_AUTH_VERIFY = `${ROUTE_PATH}/auth-verify`
export const ROUTE_ANALYZE = `${ROUTE_PATH}/analyze`
export const WS_EVENT_NAME = 'nuxt:devtools:rpc'

const isSandboxed = provider === 'stackblitz' || provider === 'codesandbox'
Expand Down
36 changes: 31 additions & 5 deletions packages/devtools/src/module-main.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { existsSync } from 'node:fs'
import os from 'node:os'
import fs from 'node:fs/promises'
import type { ServerResponse } from 'node:http'
import { join } from 'pathe'
import type { Nuxt } from 'nuxt/schema'
import { addPlugin, addTemplate, addVitePlugin, logger } from '@nuxt/kit'
import type { ViteDevServer } from 'vite'
import type { Connect, ViteDevServer } from 'vite'

Check failure on line 8 in packages/devtools/src/module-main.ts

View workflow job for this annotation

GitHub Actions / ci

'Connect' is defined but never used
import { searchForWorkspaceRoot } from 'vite'
import sirv from 'sirv'
import { colors } from 'consola/utils'
import { version } from '../package.json'
import type { ModuleOptions, NuxtDevToolsOptions } from './types'
import { setupRPC } from './server-rpc'
import { clientDir, isGlobalInstall, packageDir, runtimeDir } from './dirs'
import { ROUTE_ANALYZE, ROUTE_AUTH, ROUTE_AUTH_VERIFY, ROUTE_CLIENT, defaultTabOptions } from './constant'
import { defaultTabOptions } from './constant'
import { getDevAuthToken } from './dev-auth'
import { readLocalOptions } from './utils/local-options'

Expand Down Expand Up @@ -122,12 +124,36 @@ window.__NUXT_DEVTOOLS_TIME_METRIC__.appInit = Date.now()
})
})

const ROUTE_PATH = `${nuxt.options.app.baseURL || '/'}/__nuxt_devtools__`.replace(/\/+/g, '/')
const ROUTE_CLIENT = `${ROUTE_PATH}/client`
const ROUTE_AUTH = `${ROUTE_PATH}/auth`
const ROUTE_AUTH_VERIFY = `${ROUTE_PATH}/auth-verify`
const ROUTE_ANALYZE = `${ROUTE_PATH}/analyze`

// TODO: Use WS from nitro server when possible
nuxt.hook('vite:serverCreated', (server: ViteDevServer) => {
server.middlewares.use(ROUTE_ANALYZE, sirv(analyzeDir, { single: false, dev: true }))
// serve the front end in production
if (clientDirExists)
server.middlewares.use(ROUTE_CLIENT, sirv(clientDir, { single: true, dev: true }))
// Serve the front end in production
if (clientDirExists) {
const indexHtmlPath = join(clientDir, 'index.html')
const indexContent = fs.readFile(indexHtmlPath, 'utf-8')
const handleStatic = sirv(clientDir, {
dev: true,
single: false,
})
// We replace the base URL in the index.html based on user's settings
const handleIndex = async (res: ServerResponse) => {
res.setHeader('Content-Type', 'text/html')
res.statusCode = 200
res.write((await indexContent).replace(/\/__NUXT_DEVTOOLS_BASE__\//g, `${ROUTE_CLIENT}/`))
res.end()
}
server.middlewares.use(ROUTE_CLIENT, (req, res) => {
if (req.url === '/')
return handleIndex(res)
return handleStatic(req, res, () => handleIndex(res))
})
}
server.middlewares.use(ROUTE_AUTH, sirv(join(runtimeDir, 'auth'), { single: true, dev: true }))
server.middlewares.use(ROUTE_AUTH_VERIFY, async (req, res) => {
const search = req.url?.split('?')[1]
Expand Down
5 changes: 3 additions & 2 deletions packages/devtools/src/runtime/plugins/view/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { popupWindow, state } from './state'

// eslint-disable-next-line ts/prefer-ts-expect-error
// @ts-ignore tsconfig
import { useAppConfig } from '#imports'
import { useAppConfig, useRuntimeConfig } from '#imports'

const clientRef = shallowRef<NuxtDevtoolsHostClient>()

Expand Down Expand Up @@ -123,7 +123,8 @@ export async function setupDevToolsClient({

function getIframe() {
if (!iframe) {
const CLIENT_PATH = '/__nuxt_devtools__/client'
const runtimeConfig = useRuntimeConfig()
const CLIENT_PATH = `${runtimeConfig.app.baseURL}/__nuxt_devtools__/client`.replace(/\/+/g, '/')
const initialUrl = CLIENT_PATH + state.value.route
try {
iframe = document.createElement('iframe')
Expand Down
3 changes: 2 additions & 1 deletion packages/devtools/src/server-rpc/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import type { ModuleOptions, NuxtLayout } from '@nuxt/schema'
import type { AutoImportsWithMetadata, HookInfo, NuxtDevtoolsServerContext, ServerFunctions } from '../types'
import { setupHooksDebug } from '../runtime/shared/hooks'
import { getDevAuthToken } from '../dev-auth'
import { ROUTE_AUTH } from '../constant'

export function setupGeneralRPC({ nuxt, options, refresh, openInEditorHooks }: NuxtDevtoolsServerContext) {
const components: Component[] = []
Expand Down Expand Up @@ -196,6 +195,8 @@ export function setupGeneralRPC({ nuxt, options, refresh, openInEditorHooks }: N

origin ||= `${nuxt.options.devServer.https ? 'https' : 'http'}://${nuxt.options.devServer.host === '::' ? 'localhost' : (nuxt.options.devServer.host || 'localhost')}:${nuxt.options.devServer.port}`

const ROUTE_AUTH = `${nuxt.options.app.baseURL || '/'}/__nuxt_devtools__/auth`.replace(/\/+/g, '/')

const message = [
`A browser is requesting permissions of ${colors.bold(colors.yellow('writing files and running commands'))} from the DevTools UI.`,
colors.bold(info),
Expand Down

0 comments on commit 2697340

Please sign in to comment.