Files
bank/app/dash/vite.lib.config.ts
zeekayandHanzo Dev b94609c855 the screens bring what they stand on
Mounted in a host that only imports the built library, every screen threw.
Three things the app had in its own entry file and the library did not:
the layout runtime's theme, the account the screens read, and the gate
that waits for it. Finance now carries all three, and Ready is one gate
rather than two — Layout wraps its chrome around it, the console wraps
none, and what has to be true before a screen can draw is the same either
way. Without it a first-time console customer met eight blank frames.

A host also white-screened on the first render: the runtime reads
process.env directly, thirty times, unguarded, and the app only survives
because its build plugin defines them. The library build defines the
object, so no read is undefined.

The library no longer ships a typeface. Inlined as base64 the fonts were
205 of the stylesheet's 219 kB, and a console importing the nav paid for
them on its marketing page — 219 kB to 10.7. A host renders these screens
in its own brand's font, which is what a console with a brand should do.

It no longer renames its host's tab either. Setting document.title and
the favicon at module load took something that was never offered; the
page belongs to whoever owns it, so lux.finance calls label() and the
console keeps its own name. The brand attribute stays at load, because
the tokens it selects are what make the screens readable at all.

Four packages the library inlines were declared as runtime dependencies,
so installing it pulled 401 packages into a console that needs none of
them, react-native included.

Verified through the built artifact in a host that imports nothing else:
overview $45,898.45 across 7 balances, wallet $27,705.00, earn showing
collateral $7,350.00 against $4,260.00 borrowed for $3,090.00 net, cards
and activity populated, zero page errors.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-25 14:59:07 -07:00

43 lines
1.8 KiB
TypeScript

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { hanzoguiPlugin } from '@hanzogui/vite-plugin'
import { resolve } from 'path'
// The library build. The grid compiler runs HERE, once, so a host consuming
// these screens needs no build plugin of its own — it gets compiled CSS and
// JavaScript. React and the router stay external so the host's copies are the
// only ones on the page; two Reacts is an invalid-hook-call, and two routers
// would each think they owned the URL.
export default defineConfig({
plugins: [
react(),
hanzoguiPlugin({ components: ['@hanzo/gui'], config: './hanzogui.config.ts', optimize: true }),
],
resolve: {
alias: { '@': resolve(__dirname, 'src'), 'react-native': 'react-native-web' },
dedupe: ['react', 'react-dom'],
},
// The runtime reads process.env directly — thirty bare reads of GUI_*, none
// of them guarded by a typeof check. The app survives because the build
// plugin defines them; a host importing only the compiled artifact hits the
// first read and white-screens. Defining the whole object leaves no read
// undefined, which is the only way to be sure while they stay unguarded.
define: {
'process.env.TAMAGUI_TARGET': JSON.stringify('web'),
'process.env': '{}',
'process.platform': JSON.stringify('browser'),
},
build: {
outDir: 'lib',
emptyOutDir: true,
// Fonts ship as files. Inlined as base64 they were 205 of the stylesheet's
// 219 kB, and a host that imports the nav gets the whole sheet on its
// marketing page.
assetsInlineLimit: 0,
lib: { entry: resolve(__dirname, 'src/index.ts'), formats: ['es'], fileName: 'index' },
rollupOptions: {
external: ['react', 'react-dom', 'react/jsx-runtime', 'react-router', '@hanzo/iam', '@hanzo/iam/react', '@hanzo/iam/browser'],
},
},
})