@ -0,0 +1,6 @@ | |||||
{ | |||||
"semi": true, | |||||
"arrowParens": "always", | |||||
"singleQuote": true, | |||||
"trailingComma": "all" | |||||
} |
@ -0,0 +1,20 @@ | |||||
{ | |||||
"editor.tabSize": 2, | |||||
"[javascript]": { | |||||
"editor.defaultFormatter": "esbenp.prettier-vscode", | |||||
"editor.formatOnSave": true | |||||
}, | |||||
"[typescript]": { | |||||
"editor.defaultFormatter": "esbenp.prettier-vscode", | |||||
"editor.formatOnSave": true | |||||
}, | |||||
"[vue]": { | |||||
"editor.defaultFormatter": "esbenp.prettier-vscode", | |||||
"editor.formatOnSave": true | |||||
}, | |||||
"[html]": { | |||||
"editor.defaultFormatter": "vscode.html-language-features", | |||||
"editor.formatOnSave": true | |||||
}, | |||||
"sort-imports.on-save": true | |||||
} |
@ -1,3 +1,10 @@ | |||||
{ | { | ||||
"extends": "../../tsconfig.json" | |||||
"extends": "../../tsconfig.json", | |||||
"ts-node": { | |||||
"transpileOnly": true, | |||||
"compilerOptions": { | |||||
"module": "CommonJS", | |||||
"noImplicitAny": false | |||||
} | |||||
} | |||||
} | } |
@ -0,0 +1,43 @@ | |||||
import compression from 'compression' | |||||
import express from 'express' | |||||
import { createPageRenderer } from 'vite-plugin-ssr' | |||||
import { getPath, isProduction, port } from './shared' | |||||
export async function expressServer() { | |||||
const app = express() | |||||
app.use(compression()) | |||||
let viteDevServer | |||||
if (isProduction) { | |||||
app.use(express.static(getPath('dist/client'))) | |||||
} else { | |||||
const vite = require('vite') | |||||
viteDevServer = await vite.createServer({ | |||||
root: getPath(), | |||||
server: { middlewareMode: 'ssr' }, | |||||
}) | |||||
app.use(viteDevServer.middlewares) | |||||
} | |||||
const renderPage = createPageRenderer({ viteDevServer, isProduction, root: getPath() }) | |||||
app.get('*', async (req, res, next) => { | |||||
const url = req.originalUrl | |||||
const pageContextInit = { | |||||
url, | |||||
} | |||||
const pageContext = await renderPage(pageContextInit) | |||||
const { httpResponse } = pageContext | |||||
if (!httpResponse) return next() | |||||
const { body, statusCode, contentType } = httpResponse | |||||
res.status(statusCode).type(contentType).send(body) | |||||
}) | |||||
app.listen(port) | |||||
console.log(`Server running at http://localhost:${port}`) | |||||
} | |||||
if (require.main === module) { | |||||
expressServer() | |||||
} |
@ -1,43 +1,47 @@ | |||||
import express from 'express' | |||||
import compression from 'compression' | |||||
import { createPageRenderer } from 'vite-plugin-ssr' | |||||
import fastify from 'fastify' | |||||
const isProduction = process.env.NODE_ENV === 'production' | |||||
const root = `${__dirname}/..` | |||||
import { getPath, isDev, port } from './shared' | |||||
startServer() | |||||
async function startServer() { | |||||
const app = express() | |||||
export async function fastifyServer() { | |||||
const app = fastify({ | |||||
logger: { | |||||
prettyPrint: isDev | |||||
} | |||||
}) | |||||
app.use(compression()) | |||||
if (isDev) { | |||||
const vite = await import('vite') | |||||
const { createPageRenderer } = await import('vite-plugin-ssr') | |||||
let viteDevServer | |||||
if (isProduction) { | |||||
app.use(express.static(`${root}/dist/client`)) | |||||
} else { | |||||
const vite = require('vite') | |||||
viteDevServer = await vite.createServer({ | |||||
root, | |||||
await app.register(import('@fastify/express')) | |||||
app.register(import('@fastify/compress'), { global: false }) | |||||
const viteDevServer = await vite.createServer({ | |||||
root: getPath(), | |||||
server: { middlewareMode: 'ssr' }, | server: { middlewareMode: 'ssr' }, | ||||
}) | }) | ||||
app.use(viteDevServer.middlewares) | app.use(viteDevServer.middlewares) | ||||
} | |||||
const renderPage = createPageRenderer({ viteDevServer, isProduction, root }) | |||||
app.get('*', async (req, res, next) => { | |||||
const url = req.originalUrl | |||||
const pageContextInit = { | |||||
url, | |||||
} | |||||
const pageContext = await renderPage(pageContextInit) | |||||
const { httpResponse } = pageContext | |||||
if (!httpResponse) return next() | |||||
const { body, statusCode, contentType } = httpResponse | |||||
res.status(statusCode).type(contentType).send(body) | |||||
}) | |||||
const renderPage = createPageRenderer({ viteDevServer, isProduction: !isDev, root: getPath() }) | |||||
app.get('*', async (req, res) => { | |||||
const url = req.raw.url || req.url | |||||
const pageContextInit = { | |||||
url, | |||||
} | |||||
const pageContext = await renderPage(pageContextInit) | |||||
const { httpResponse } = pageContext | |||||
if (!httpResponse) return | |||||
const { body, statusCode, contentType } = httpResponse | |||||
res.status(statusCode).type(contentType).compress(body) | |||||
}) | |||||
} else { | |||||
app.register(import('@fastify/static'), { | |||||
root: getPath('dist/client') | |||||
}) | |||||
} | |||||
const port = process.env.PORT || 3000 | |||||
app.listen(port) | app.listen(port) | ||||
console.log(`Server running at http://localhost:${port}`) | |||||
} | |||||
if (require.main === module) { | |||||
fastifyServer() | |||||
} | } |
@ -0,0 +1,10 @@ | |||||
import path from 'path' | |||||
export const port = Number(process.env['PORT'] || 16272) | |||||
export const isProduction = process.env['NODE_ENV'] === 'production' | |||||
export const isDev = !isProduction | |||||
export function getPath(...segments: string[]) { | |||||
return path.join(__dirname, '..', ...segments) | |||||
} |