Files
sk-react-toolkit/vite/index.ts
T

57 lines
2.2 KiB
TypeScript

import type { Plugin } from 'vite'
/** The choices of VITE_FONT. */
export const FONTS = ['cdn', 'bundled', 'none'] as const
export type Font = (typeof FONTS)[number]
const FONT_MODULE = 'virtual:font'
/**
* Provides the fonts of the toolkit's fonts.ts as VITE_FONT selects: cdn adds the Google Fonts links for Roboto and
* Roboto Mono to index.html, bundled imports @fontsource/roboto through the virtual:font module, none adds nothing; a
* font not provided falls back to the system fonts of its stack. The toolkit's renderApp imports virtual:font.
*/
export function font(choice: Font): Plugin {
const resolved = `\0${FONT_MODULE}`
return {
name: 'font',
resolveId(id) {
return id === FONT_MODULE ? resolved : undefined
},
load(id) {
if (id !== resolved) {
return undefined
}
return choice === 'bundled' ? ['300', '400', '500', '700'].map((weight) => `import '@fontsource/roboto/${weight}.css'`).join('\n') : ''
},
transformIndexHtml() {
if (choice !== 'cdn') {
return []
}
return [
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
{ tag: 'link', attrs: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true } },
{ tag: 'link', attrs: { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Roboto+Mono:wght@300;400;500;700&display=swap' } },
]
},
}
}
/** VITE_FONT of env, the variables Vite's loadEnv answers, cdn when it is not set; another value throws. */
export function fontChoice(env: Record<string, string>): Font {
const choice = env.VITE_FONT ?? 'cdn'
if (!FONTS.includes(choice as Font)) {
throw new Error(`VITE_FONT=${choice} is not one of ${FONTS.join(', ')}.`)
}
return choice as Font
}
/**
* The resolve options of an application that uses the toolkit's web code through a link: the toolkit's imports of
* React, MUI and Emotion are resolved from the application's own node_modules, so the page has one copy of each.
*/
export const TOOLKIT_RESOLVE = {
dedupe: ['react', 'react-dom', '@mui/material', '@mui/icons-material', '@mui/system', '@emotion/react', '@emotion/styled'],
}