Skip to content

Instantly share code, notes, and snippets.

@bruceharrison1984
Last active February 28, 2024 15:59
Show Gist options
  • Save bruceharrison1984/91a19ff3365cc477a9231916764fe228 to your computer and use it in GitHub Desktop.
Save bruceharrison1984/91a19ff3365cc477a9231916764fe228 to your computer and use it in GitHub Desktop.
HonoX Islands Detection
import { existsSync } from 'fs'
import { lstat, readFile } from 'fs/promises'
import path from 'path'
import MagicString from 'magic-string'
import precinct from 'precinct'
import { normalizePath, type Plugin } from 'vite'
import { IMPORTING_ISLANDS_ID } from '../constants'
export function injectImportingIslands(): Plugin {
const isIslandRegex = new RegExp(/\/islands\//)
const routesRegex = new RegExp(/routes\/.*\.[t|j]sx$/)
return {
name: 'inject-importing-islands',
async transform(sourceCode, id) {
if (!routesRegex.test(id)) {
return
}
const hasIslandsImport = (await walkDependencyTree(id))
.flat()
.some((x) => isIslandRegex.test(normalizePath(x)))
if (!hasIslandsImport) {
return
}
const islandEnabledSource = new MagicString(sourceCode)
islandEnabledSource.append(`export const ${IMPORTING_ISLANDS_ID} = true;`)
return { code: islandEnabledSource.toString(), map: islandEnabledSource.generateMap() }
},
}
}
const cache: Record<string, string> = {}
const walkDependencyTree: (baseFile: string, dependencyFile?: string) => Promise<string[]> = async (
baseFile: string,
dependencyFile?: string
) => {
const depPath = dependencyFile
? path.join(path.dirname(baseFile), dependencyFile) + '.tsx' //TODO: This only includes tsx files
: baseFile
const deps = [depPath]
if (!existsSync(depPath) || (await lstat(depPath)).isDirectory()) {
return deps
}
if (!cache[depPath]) {
cache[depPath] = (await readFile(depPath)).toString()
}
const currentFileDeps = precinct(cache[depPath]) as string[]
const childDeps = await Promise.all(
currentFileDeps.map(async (x) => await walkDependencyTree(depPath, x))
)
deps.push(...childDeps.flat())
return deps
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment