mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
feat!: generate vue sfcs as part of build (#67)
This commit is contained in:
parent
1428c46e96
commit
62e2f94fcd
@ -3,6 +3,7 @@ import { resolve, join, dirname, basename } from 'upath'
|
||||
import type { Plugin } from 'vite'
|
||||
import Critters from 'critters'
|
||||
import template from 'lodash.template'
|
||||
import { genObjectFromRawEntries } from 'knitwork'
|
||||
import htmlMinifier from 'html-minifier'
|
||||
import { camelCase } from 'scule'
|
||||
import genericMessages from '../templates/messages.json'
|
||||
@ -72,6 +73,36 @@ export const RenderPlugin = () => {
|
||||
'const _template = (messages) => _render({ messages: { ..._messages, ...messages } })'
|
||||
].join('\n').trim()
|
||||
|
||||
const templateContent = html
|
||||
.match(/<body.*?>([\s\S]*)<\/body>/)?.[0]
|
||||
.replace(/(?<=<|<\/)body/g, 'div')
|
||||
.replace(/messages\./g, '')
|
||||
.replace(/<a href="([^"]+)"([^>]*)>([\s\S]*)<\/a>/g, '<NuxtLink to="$1"$2>$3</NuxtLink>')
|
||||
.replace(/>{{\s*([\s\S]+?)\s*}}<\/[\w-]*>/g, ' v-html="$1" />')
|
||||
// We are not matching <link> <script> and <meta> tags as these aren't used yet in nuxt/ui
|
||||
// and should be taken care of wherever this SFC is used
|
||||
const title = html.match(/<title.*?>([\s\S]*)<\/title>/)?.[1].replace(/{{([\s\S]+?)}}/g, (r) => {
|
||||
return `\${${r.slice(2, -2)}}`.replace(/messages\./g, 'props.')
|
||||
})
|
||||
const styleContent = Array.from(html.matchAll(/<style[^>]*>([\s\S]*?)<\/style>/g)).map(block => block[1])
|
||||
const props = genObjectFromRawEntries(Object.entries({ ...genericMessages, ...messages }).map(([key, value]) => [key, {
|
||||
type: typeof value === 'string' ? 'String' : typeof value === 'number' ? 'Number' : typeof value === 'boolean' ? 'Boolean' : 'undefined',
|
||||
default: JSON.stringify(value)
|
||||
}]))
|
||||
const vueCode = [
|
||||
'<script setup lang="ts">',
|
||||
title && ' import { useMeta } from \'#app\'',
|
||||
` const props = defineProps(${props})`,
|
||||
title && ` useMeta({ title: \`${title}\` })`,
|
||||
'</script>',
|
||||
'<template>',
|
||||
templateContent,
|
||||
'</template>',
|
||||
'<style scoped>',
|
||||
...styleContent,
|
||||
'</style>'
|
||||
].filter(Boolean).join('\n').trim()
|
||||
|
||||
// Generate types
|
||||
const types = [
|
||||
`export type DefaultMessages = Record<${Object.keys(messages).map(a => `"${a}"`).join(' | ')}, string | boolean | number >`,
|
||||
@ -88,6 +119,7 @@ export const RenderPlugin = () => {
|
||||
|
||||
// Write new template
|
||||
await fsp.writeFile(fileName.replace('/index.html', '.mjs'), `${jsCode}\nexport const template = _template`)
|
||||
await fsp.writeFile(fileName.replace('/index.html', '.vue'), vueCode)
|
||||
await fsp.writeFile(fileName.replace('/index.html', '.d.ts'), `${types}`)
|
||||
|
||||
// Remove original html file
|
||||
|
@ -4,7 +4,7 @@
|
||||
"repository": "nuxt/ui",
|
||||
"license": "CC-BY-ND-4.0",
|
||||
"exports": {
|
||||
"./templates/*": "./dist/templates/*.mjs",
|
||||
"./templates/*": "./dist/templates/*",
|
||||
".": "./dist/index.mjs",
|
||||
"./*": "./dist/*"
|
||||
},
|
||||
@ -31,6 +31,7 @@
|
||||
"globby": "^13.1.1",
|
||||
"html-minifier": "^4.0.0",
|
||||
"jiti": "^1.13.0",
|
||||
"knitwork": "^0.1.1",
|
||||
"lodash.template": "^4.5.0",
|
||||
"scule": "^0.2.1",
|
||||
"upath": "^2.0.1",
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"statusCode": "500",
|
||||
"statusMessage": "Server error",
|
||||
"description": "An error occurred in the application and the page could not be served. If you are the application owner, check your server logs for details."
|
||||
"description": "An error occurred in the application and the page could not be served. If you are the application owner, check your server logs for details.",
|
||||
"stack": ""
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user