0.0.23 • Published 7 months ago
@opengis/vite-page v0.0.23
Vite Page
Multi page ssr vite plugin based on folder - using pinia, vue-router, vite
Features
- auto routing based on file structure
- backend data preload
- nested route
- flexible by design
- high perfomance
Structure
site # root vite folder
- pages/
- demo/ # /demo
- page.vue # vue page component
- data.js # backend data optional
- news+id/ # /news/:id?
- page.vue # vue page component
- data.js # backend data optional
- src/
- main.js # main app, use 3d party library
- App.vue # Root Component
- vite.config.js
- index.html # main page Demo in git examples directory
Usage
npm i @opengis/vite-page
// server.js
import renderPage from '@opengis/vite-mpa/renderPage.js';
fastify.get('*', async (req, reply) => {
const url = req.originalUrl;
const html = await renderPage({
url,
vite,
page: {}, // {{ page }} optional
template: 'news', // pages template name optional
seo: { title: page?.title, meta: { description: 'my description', keywords: 'my keywords' } }, // seo title + meta optional
root: 'site',
ctx: { user: null, settings: {}}
})
reply.headers({ 'Cache-Control': 'public, no-cache' })
.type('text/html')
.send(html);
})<!-- context -->
<template>
user: {{ $user }}
settings: {{ $settings }}
ssr: {{ $ssr }}
url: {{ $url }}
</template>import fs from 'node:fs'
import path from 'node:path'
import Fastify from 'fastify';
import { createServer as createViteServer, defineConfig } from 'vite';
import renderPage from '@opengis/vite-mpa/renderPage.js';
const fastify = Fastify();
const isProd = process.env.NODE_ENV === 'production';
const vite = !isProd ? await createViteServer({
root: 'site',
server: { middlewareMode: true },
}) : null;
fastify.addHook('onRequest', async (req, reply) => {
if (isProd) return;
// const { user } = req.session?.passport || {};
const next = () => new Promise((resolve) => {
vite.middlewares(req.raw, reply.raw, () => resolve());
});
await next();
});
fastify.get('/assets/:file', async (req, reply) => {
const stream = fs.createReadStream(`site/dist/client/assets/${req.params.file}`);
return stream;
});
fastify.get('*', async (req, reply) => {
const url = req.originalUrl;
const html = await renderPage({ url, vite, root: 'site' })
reply.headers({ 'Cache-Control': 'public, no-cache' })
.type('text/html')
.send(html);
})
fastify.listen({ host: '0.0.0.0', port: process.env.PORT || 3000 }, (err) => {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import cms from '@opengis/vite-page/plugin.js';
export default defineConfig({
plugins: [vue(), cms()],
})<!DOCTYPE html>
<html ${htmlAttrs}>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!--head-tags-->
<!--preload-links-->
</head>
<body ${bodyAttrs}>
<div id="app"><!--app-html--></div>
<script>window.__pinia = {};</script>
<script type="module" src="/src/entry-client.js"></script>
</body>
</html>Page Example
/site/pages/demo
- page.vue
- data.js// data.js - use backend data & function
export default function (page) {
return { title: 1 }
}<!-- page.vue -->
<script lang="js">
import { computed, defineComponent, reactive } from "vue";
import { useStore } from "/src/store.js";
export default defineComponent({
name: "Demo",
setup() {
const store = useStore();
const title = computed(() => store.data.title);
const state = reactive({ count: 0 });
return {
state,
title
};
},
});
</script>
<template>
<h1 class="title">DEMO {{ title }}</h1>
<button @click="state.count++">count is: {{ state.count }}</button>
</template>0.0.23
7 months ago
0.0.22
7 months ago
0.0.21
8 months ago
0.0.20
8 months ago
0.0.19
8 months ago
0.0.18
8 months ago
0.0.17
9 months ago
0.0.16
9 months ago
0.0.15
9 months ago
0.0.14
9 months ago
0.0.13
9 months ago
0.0.12
9 months ago
0.0.11
10 months ago
0.0.10
10 months ago
0.0.9
10 months ago
0.0.8
10 months ago
0.0.7
10 months ago
0.0.6
10 months ago
0.0.5
10 months ago
0.0.4
10 months ago
0.0.3
10 months ago
0.0.2
10 months ago
0.0.1
10 months ago