diff --git a/coldspa/vite/plugin.js b/coldspa/vite/plugin.js index 0064b1c..8c0ae66 100644 --- a/coldspa/vite/plugin.js +++ b/coldspa/vite/plugin.js @@ -41,20 +41,28 @@ function normalizeViteId(id) { return cleanId.startsWith('/@fs/') ? cleanId.slice('/@fs/'.length) : cleanId; } -function toViteFsId(path) { - return `/@fs/${path.split('\\').join('/')}`; -} - const FRAMEWORK_CLIENTS = { vue: toViteId(resolve(__dirname, 'clients/vue-client.js')), react: toViteId(resolve(__dirname, 'clients/react-client.js')) }; -const FRAMEWORK_CLIENT_URLS = { - '/coldspa/vite/clients/vue-client.js': FRAMEWORK_CLIENTS.vue, - '/coldspa/vite/clients/react-client.js': FRAMEWORK_CLIENTS.react +const FRAMEWORK_CLIENT_MODULES = { + '/coldspa/vite/clients/vue-client.js': { + framework: 'vue', + path: FRAMEWORK_CLIENTS.vue, + virtualId: '\0coldspa:vue-client' + }, + '/coldspa/vite/clients/react-client.js': { + framework: 'react', + path: FRAMEWORK_CLIENTS.react, + virtualId: '\0coldspa:react-client' + } }; +const VIRTUAL_CLIENT_MODULES = Object.fromEntries( + Object.values(FRAMEWORK_CLIENT_MODULES).map((entry) => [entry.virtualId, entry]) +); + // SSR entries -- one per framework that supports server rendering. const FRAMEWORK_SSR = { vue: toViteId(resolve(__dirname, 'clients/vue-ssr.js')), @@ -183,6 +191,11 @@ export default function coldspa(options = {}) { input[`${fw}-client`] = clientPath; globsByClientPath[clientPath] = userGlobs[fw] ?? DEFAULT_GLOBS[fw]; + const virtualClient = Object.values(FRAMEWORK_CLIENT_MODULES).find((entry) => entry.framework === fw); + if (virtualClient) { + globsByClientPath[virtualClient.virtualId] = userGlobs[fw] ?? DEFAULT_GLOBS[fw]; + } + // SSR entry (if framework supports it). Same glob applies. if (FRAMEWORK_SSR[fw]) { const ssrPath = FRAMEWORK_SSR[fw]; @@ -234,6 +247,11 @@ export default function coldspa(options = {}) { // placeholder and bails. These files are entry points // anyway -- they don't belong in the optimized deps cache. optimizeDeps: { + include: frameworks.flatMap((fw) => { + if (fw === 'react') return ['react', 'react-dom', 'react-dom/client']; + if (fw === 'vue') return ['vue']; + return []; + }), entries: [], exclude: Object.values(FRAMEWORK_CLIENTS).concat( Object.values(FRAMEWORK_SSR) @@ -250,15 +268,15 @@ export default function coldspa(options = {}) { }; }, - configureServer(server) { - server.middlewares.use((req, _res, next) => { - const parsed = new URL(req.url || '/', 'http://coldspa.local'); - const clientPath = FRAMEWORK_CLIENT_URLS[parsed.pathname]; - if (clientPath) { - req.url = `${toViteFsId(clientPath)}${parsed.search}`; - } - next(); - }); + resolveId(id) { + const cleanId = id.split('?')[0]; + const entry = FRAMEWORK_CLIENT_MODULES[cleanId]; + return entry ? entry.virtualId : null; + }, + + load(id) { + const entry = VIRTUAL_CLIENT_MODULES[id]; + return entry ? readFileSync(entry.path, 'utf8') : null; }, // Replace the glob placeholder in our client entries with the diff --git a/coldspa/vite/ssr-server.js b/coldspa/vite/ssr-server.js old mode 100644 new mode 100755