UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

82 lines (69 loc) 3.25 kB
import type { Plugin } from 'vite' import { readFileSync } from 'node:fs' import path from 'node:path' import { resolvePath } from '@vxrn/resolve' const DEVTOOLS_VIRTUAL_ID = '/@one/dev.js' export type DevtoolsPluginOptions = { /** include devtools UI (overlay, inspector) - default true */ includeUI?: boolean } export function createDevtoolsPlugin(options: DevtoolsPluginOptions = {}): Plugin { const { includeUI = true } = options return { name: 'one-devtools', apply: 'serve', // only in dev configureServer(server) { // vite 8.1 bundledDev: /@vite/client and /@react-refresh aren't standalone // modules (the HMR client + refresh runtime are bundled into the entry), so // dev.mjs's top-level imports of them 404 / fail MIME checks and take the whole // devtools script down. stub them: HMR (route/loader/css/cursor) becomes a // no-op here and the refresh preamble is installed by the bundled entry instead. const isBundledDev = !!(server.config as any).experimental?.bundledDev // serve the devtools script by reading and combining the source files server.middlewares.use(async (req, res, next) => { if (req.url === DEVTOOLS_VIRTUAL_ID) { try { // resolve and read the devtools files directly const devEntryPath = resolvePath('one/devtools/dev.mjs') const devEntry = readFileSync(devEntryPath, 'utf-8') // remove the relative imports from dev.mjs - we'll conditionally add them let code = devEntry .replace("import './devtools.mjs'", '') .replace("import './source-inspector.mjs'", '') if (isBundledDev) { code = code .replace( "import { createHotContext } from '/@vite/client'", 'const createHotContext = () => ({ on() {}, off() {}, accept() {}, dispose() {}, prune() {}, send() {}, invalidate() {} })' ) .replace( "import { injectIntoGlobalHook } from '/@react-refresh'", 'const injectIntoGlobalHook = () => {}' ) } // only include devtools UI if enabled if (includeUI) { const devtoolsPath = resolvePath('one/devtools/devtools.mjs') const sourceInspectorPath = resolvePath('one/devtools/source-inspector.mjs') const devtools = readFileSync(devtoolsPath, 'utf-8') const sourceInspector = readFileSync(sourceInspectorPath, 'utf-8') const projectName = path.basename(process.cwd()) code = `window.__oneProjectRoot="${projectName}";\n${code}\n${devtools}\n${sourceInspector}` } res.setHeader('Content-Type', 'application/javascript') res.setHeader('Cache-Control', 'no-store') res.end(code) return } catch (e) { console.error('[one] Failed to load devtools script:', e) } res.setHeader('Content-Type', 'application/javascript') res.end('// devtools failed to load') return } next() }) }, } } export { DEVTOOLS_VIRTUAL_ID }