Skip to content

Commit

Permalink
feat: support --base option in build, fix #41
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 12, 2024
1 parent 3bab7e8 commit 1156bb5
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 37 deletions.
6 changes: 5 additions & 1 deletion app/app.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<script setup lang="ts">
import { useHead } from '@unhead/vue'
import { errorInfo, isLoading } from '~/composables/payload'
import { useRuntimeConfig } from '#app/nuxt'
import { errorInfo, init, isLoading } from '~/composables/payload'
import 'floating-vue/dist/style.css'
import './styles/global.css'
import './composables/dark'
const config = useRuntimeConfig()
init(config.app.baseURL)
useHead({
title: 'ESLint Config Inspector',
})
Expand Down
62 changes: 34 additions & 28 deletions app/composables/payload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ function isErrorInfo(payload: Payload | ErrorInfo): payload is ErrorInfo {
return 'error' in payload
}

async function get() {
async function get(baseURL: string) {
isFetching.value = true
const payload = await $fetch<Payload | ErrorInfo>('/api/payload.json')
const payload = await $fetch<Payload | ErrorInfo>('/api/payload.json', { baseURL })
if (isErrorInfo(payload)) {
errorInfo.value = payload
isLoading.value = false
Expand All @@ -46,36 +46,42 @@ async function get() {
return payload
}

const _promises = get()
.then((payload) => {
if (!payload)
return
let _promise: Promise<Payload | undefined> | undefined

if (typeof payload.meta.wsPort === 'number') {
// Connect to WebSocket, listen for config changes
const ws = new WebSocket(`ws://${location.hostname}:${payload.meta.wsPort}`)
ws.addEventListener('message', async (event) => {
console.log(LOG_NAME, 'WebSocket message', event.data)
const payload = JSON.parse(event.data)
if (payload.type === 'config-change')
get()
})
ws.addEventListener('open', () => {
console.log(LOG_NAME, 'WebSocket connected')
})
ws.addEventListener('close', () => {
console.log(LOG_NAME, 'WebSocket closed')
})
ws.addEventListener('error', (error) => {
console.error(LOG_NAME, 'WebSocket error', error)
})
}
export function init(baseURL: string) {
if (_promise)
return
_promise = get(baseURL)
.then((payload) => {
if (!payload)
return

return payload
})
if (typeof payload.meta.wsPort === 'number') {
// Connect to WebSocket, listen for config changes
const ws = new WebSocket(`ws://${location.hostname}:${payload.meta.wsPort}`)
ws.addEventListener('message', async (event) => {
console.log(LOG_NAME, 'WebSocket message', event.data)
const payload = JSON.parse(event.data)
if (payload.type === 'config-change')
get(baseURL)
})
ws.addEventListener('open', () => {
console.log(LOG_NAME, 'WebSocket connected')
})
ws.addEventListener('close', () => {
console.log(LOG_NAME, 'WebSocket closed')
})
ws.addEventListener('error', (error) => {
console.error(LOG_NAME, 'WebSocket error', error)
})
}

return payload
})
}

export function ensureDataFetch() {
return _promises
return _promise
}

export const payload = computed(() => Object.freeze(resolvePayload(data.value!)))
Expand Down
8 changes: 3 additions & 5 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ export default defineNuxtConfig({
},
},

appConfig: {
baseURL: './',
},

experimental: {
typedPages: true,
},
Expand Down Expand Up @@ -55,10 +51,11 @@ export default defineNuxtConfig({
},

app: {
baseURL: './',
head: {
viewport: 'width=device-width,initial-scale=1',
link: [
{ rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' },
{ rel: 'icon', type: 'image/svg+xml', href: `/favicon.svg` },
],
},
},
Expand All @@ -69,6 +66,7 @@ export default defineNuxtConfig({
defineModel: true,
},
},
base: './',
},

devtools: {
Expand Down
24 changes: 24 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import open from 'open'
import { getPort } from 'get-port-please'
import cac from 'cac'
import c from 'picocolors'
import fg from 'fast-glob'
import { createHostServer } from './server'
import { distDir } from './dirs'
import { readConfig } from './configs'
Expand All @@ -20,7 +21,10 @@ cli
.option('--config <configFile>', 'Config file path')
.option('--files', 'Include matched file paths in payload', { default: true })
.option('--basePath <basePath>', 'Base directory for globs to resolve. Default to directory of config file if not provided')
// Build specific options
.option('--base <baseURL>', 'Base URL for deployment', { default: '/' })
.option('--outDir <dir>', 'Output directory', { default: '.eslint-config-inspector' })
// Action
.action(async (options) => {
console.log(MARK_INFO, 'Building static ESLint config inspector...')

Expand All @@ -36,10 +40,28 @@ cli
globMatchedFiles: options.files,
})

let baseURL = options.base
if (!baseURL.endsWith('/'))
baseURL += '/'
if (!baseURL.startsWith('/'))
baseURL = `/${baseURL}`
baseURL = baseURL.replace(/\/+/g, '/')

if (existsSync(outDir))
await fs.rm(outDir, { recursive: true })
await fs.mkdir(outDir, { recursive: true })
await fs.cp(distDir, outDir, { recursive: true })
const htmlFiles = await fg('**/*.html', { cwd: distDir, onlyFiles: true })
// Rewrite HTML files with base URL
if (baseURL !== '/') {
for (const file of htmlFiles) {
const content = await fs.readFile(resolve(distDir, file), 'utf-8')
const newContent = content
.replaceAll(/\s(href|src)="\//g, ` $1="${baseURL}`)
.replaceAll('baseURL:"/"', `baseURL:"${baseURL}"`)
await fs.writeFile(resolve(outDir, file), newContent, 'utf-8')
}
}
await fs.mkdir(resolve(outDir, 'api'), { recursive: true })

configs.payload.meta.configPath = ''
Expand All @@ -55,9 +77,11 @@ cli
.option('--config <configFile>', 'Config file path')
.option('--files', 'Include matched file paths in payload', { default: true })
.option('--basePath <basePath>', 'Base directory for globs to resolve. Default to directory of config file if not provided')
// Dev specific options
.option('--host <host>', 'Host', { default: process.env.HOST || '127.0.0.1' })
.option('--port <port>', 'Port', { default: process.env.PORT || 7777 })
.option('--open', 'Open browser', { default: true })
// Action
.action(async (options) => {
const host = options.host
const port = await getPort({ port: options.port, portRange: [7777, 9000], host })
Expand Down
12 changes: 9 additions & 3 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ export async function createHostServer(options: CreateWsServerOptions) {

const ws = await createWsServer(options)

const fileMap = new Map<string, Promise<string | undefined>>()
const readCachedFile = (id: string) => {
if (!fileMap.has(id))
fileMap.set(id, readFile(id, 'utf-8').catch(() => undefined))
return fileMap.get(id)
}

app.use('/api/payload.json', eventHandler(async (event) => {
event.node.res.setHeader('Content-Type', 'application/json')
return event.node.res.end(JSON.stringify(await ws.getData()))
Expand All @@ -19,12 +26,11 @@ export async function createHostServer(options: CreateWsServerOptions) {
app.use('/', eventHandler(async (event) => {
const result = await serveStatic(event, {
fallthrough: true,
getContents: id => readFile(join(distDir, id), 'utf-8'),
getContents: id => readCachedFile(join(distDir, id)),
getMeta: async (id) => {
const stats = await stat(join(distDir, id)).catch(() => {})
if (!stats || !stats.isFile())
return

return {
type: lookup(id),
size: stats.size,
Expand All @@ -34,7 +40,7 @@ export async function createHostServer(options: CreateWsServerOptions) {
})

if (result === false)
return readFile(join(distDir, 'index.html'), 'utf8')
return readCachedFile(join(distDir, 'index.html'))
}))

return createServer(toNodeListener(app))
Expand Down

0 comments on commit 1156bb5

Please sign in to comment.