Skip to content

Instantly share code, notes, and snippets.

@innocenzi
Last active October 27, 2022 07:34
Show Gist options
  • Save innocenzi/5334b9679c35465defe72bdb57dd541c to your computer and use it in GitHub Desktop.
Save innocenzi/5334b9679c35465defe72bdb57dd541c to your computer and use it in GitHub Desktop.
Laravel domain-driven front-end with Vite
import type { Plugin } from 'vite'
const PLUGIN_NAME = 'vite:inertia:layout'
const TEMPLATE_LAYOUT_REGEX = /<template +layout(?: *= *['"](?:(?:(\w+):)?(\w+))['"] *)?>/
export default (): Plugin => ({
name: PLUGIN_NAME,
transform: (code: string) => {
if (!TEMPLATE_LAYOUT_REGEX.test(code)) {
return
}
const isTypeScript = /lang=['"]ts['"]/.test(code)
return code.replace(TEMPLATE_LAYOUT_REGEX, (_, domainName, layoutName) => {
const resolvedLayoutName = layoutName ?? 'default'
const layout = domainName
? `@/domains/${domainName}/layouts/${resolvedLayoutName}.vue`
: `@/layouts/${resolvedLayoutName}.vue`
return `
<script${isTypeScript ? ' lang="ts"' : ''}>
import layout from '${layout}'
export default { layout }
</script>
<template>
`
})
},
})
export async function resolvePageComponent(name: string, pages: Record<string, any>, defaultLayout?: any) {
const mapped: string[] = []
const path = Object.keys(pages)
.sort((a, b) => a.length - b.length)
.find((path) => {
mapped.push(
path = path
.replace('../domains/', '')
.replace('/pages/', '/')
.replace('.vue', '')
.replace('/', '.'),
)
return path === name
})
if (!path) {
throw new Error(`Page component "${name}" could not be found. Available pages: \n- ${mapped.join('\n- ')}`)
}
let component = typeof pages[path] === 'function'
? await pages[path]()
: pages[path]
component = component.default ?? component
component.layout ??= defaultLayout
return component
}
@innocenzi
Copy link
Author

Hey, yes, this function was specifically updated for Vite 3. The sorting part is what I came up with to make up for the import.meta.glob order changes. This one function is for DDD and uses a specific architecture though, so you should adapt it to your needs.

@MtDalPizzol
Copy link

Hey... Thanks for the feedback... I'm using a striped down version of this, but in my case I had to add enforce: 'pre' to the plugin export after upgrading to Vite 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment