vite-plugin-layouts
Version:
Router-based Layout Plugin for Vite.
107 lines (86 loc) • 3.31 kB
TypeScript
import type { Plugin } from 'vite';
declare const MODULE_IDS: Array<'layouts-generated' | 'virtual:generated-layouts']
const MODULE_ID_VIRTUAL = '/@vite-plugin-layouts/generated-layouts>;
export declare function defaultImportMode(name: string): 'sync' | 'async';
declare function resolveOptions(userOptions: UserOptions): ResolvedOptions;
export declare function ClientSideLayout(options?: clientSideOptions): Plugin;
declare function canEnableClientLayout(options: UserOptions): void;
export * from './types'
export default function Layout(userOptions: UserOptions = {}): Plugin {
if (canEnableClientLayout(userOptions)) {
return ClientSideLayout({
defaultLayout: userOptions.defaultLayout,
layoutDir: userOptions.layoutsDirs as string,
})
}
let config: ResolvedConfig
const options: ResolvedOptions = resolveOptions(userOptions)
let layoutDirs: string[]
let pagesDirs: string[]
return {
name: 'vite-plugin-layouts',
enforce: 'pre',
configResolved(_config) {
config = _config
const resolvedLayoutDirs = resolveDirs(options.layoutsDirs, config.root)
layoutDirs = resolvedLayoutDirs.length > 0 ? [resolvedLayoutDirs[resolvedLayoutDirs.length - 1]] : []
const resolvedPagesDirs = resolveDirs(options.pagesDirs, config.root)
pagesDirs = resolvedPagesDirs.length > 0 ? [resolvedPagesDirs[resolvedPagesDirs.length - 1]] : []
},
configureServer({ moduleGraph, watcher, ws }) {
watcher.add(options.layoutsDirs)
const reloadModule = (module: ModuleNode | undefined, path = '*') => {
if (module) {
moduleGraph.invalidateModule(module)
if (ws) {
ws.send({
path,
type: 'full-reload',
})
}
}
}
const updateVirtualModule = (path: string) => {
path = normalizePath(path)
if (pagesDirs.length === 0
|| pagesDirs.some(dir => path.startsWith(dir))
|| layoutDirs.some(dir => path.startsWith(dir))) {
debug('reload', path)
const module = moduleGraph.getModuleById(MODULE_ID_VIRTUAL)
reloadModule(module)
}
}
watcher.on('add', (path) => {
updateVirtualModule(path)
})
watcher.on('unlink', (path) => {
updateVirtualModule(path)
})
watcher.on('change', async (path) => {
updateVirtualModule(path)
})
},
resolveId(id) {
return MODULE_IDS.includes(id) || MODULE_IDS.some(i => id.startsWith(i))
? MODULE_ID_VIRTUAL
: null
},
async load(id) {
if (id === MODULE_ID_VIRTUAL) {
const container: FileContainer[] = []
for (const dir of layoutDirs) {
const layoutsDirPath = dir.substr(0, 1) === '/'
? normalizePath(dir)
: normalizePath(resolve(config.root, dir))
debug('Loading Layout Dir: %O', layoutsDirPath)
const _f = await getFilesFromPath(layoutsDirPath, options)
container.push({ path: layoutsDirPath, files: _f })
}
const importCode = getImportCode(container, options)
const clientCode = getClientCode(importCode, options)
debug('Client code: %O', clientCode)
return clientCode
}
},
}
};