English | 简体中文
use vite and egg for ssr or csr
This example not enable ssr by default,it just enable csr
- Add
vite
filed to config by default will use default config it will set vite root dir at/client
//config/config.default.ts
import {EggAppConfig, PowerPartial} from "egg";
const config: PowerPartial<EggAppConfig> = {
vite: {}
}
export default config;
- Add tegg-vite-plugin to
plugin.ts
//config/plugin.ts
import { EggPlugin } from 'egg';
import * as path from 'path';
const plugin: EggPlugin = {
teggVite: {
enable: true,
package: '@seasonjs/tegg-vite-plugin',
},
};
export default plugin;
vite
config filed extends vite
config options by InlineConfig ,
detail see vite doc:createserver.
but there have add an new filed call teggSSR
:
interface ViteConfig extends InlineConfig {
teggSSR?: {
html?: string //template html path
entry?: string //ssr server js entry
}
}
- Add
vite
filed to config by default will use default config it will set vite root dir at/client
.
If you use default setting,it will set html path to your-project-root/client/index.html
and use ssr-entry by this plugin default render function:
//config/config.default.ts
import {EggAppConfig, PowerPartial} from "egg";
import * as path from 'path';
const config: PowerPartial<EggAppConfig> = {
vite: {
server: {middlewareMode: 'ssr'},
}
}
export default config;
or you can set by custom:
//config/config.default.ts
import {EggAppConfig, PowerPartial} from "egg";
import * as path from 'path';
const config: PowerPartial<EggAppConfig> = {
vite: {
server: {middlewareMode: 'ssr'},
teggSSR: {
html: path.reslove('../client/index.html'),//path to your-project/client/index.html
entry: path.reslove('../client/ssr-entry.ts')//path to your-project/client/ssr-entry.ts
}
}
}
export default config;
- Put your render function to controller,if you want to use this plugin default handler:
[Notie]: default handler not ready for work
//controller/SSRController.ts
import {
Context,
EggContext,
HTTPController,
HTTPMethod,
HTTPMethodEnum,
HTTPQuery,
} from '@eggjs/tegg';
import { EggLogger } from 'egg';
@HTTPController()
export class SSRController {
@HTTPMethod({
method: HTTPMethodEnum.GET,
path: '/*',
})
async hello(@Context() ctx: EggContext) {
this.logger.info('access url: %s', ctx.url);
ctx.viteSSRRender(ctx)
}
}
Else I suggest you use your custom handle function It not complex:
//controller/SSRController.ts
import {
Context,
EggContext,
HTTPController,
HTTPMethod,
HTTPMethodEnum,
HTTPQuery,
} from '@eggjs/tegg';
import {Application, EggLogger} from 'egg';
@HTTPController()
export class SSRController {
@Inject()
private app: Application;
@HTTPMethod({
method: HTTPMethodEnum.GET,
path: '/*',
})
async hello(@Context() ctx: EggContext) {
this.logger.info('access url: %s', ctx.url);
const url = ctx.req.originalUrl
try {
// 1. Read index.html
let template = fs.readFileSync(
path.resolve(__dirname, 'index.html'),
'utf-8'
)
// 2. Apply Vite HTML transforms. This injects the Vite HMR client, and
// also applies HTML transforms from Vite plugins, e.g. global preambles
// from @vitejs/plugin-react-refresh
template = await this.app.vite.transformIndexHtml(url, template)
// 3. Load the server entry. vite.ssrLoadModule automatically transforms
// your ESM source code to be usable in Node.js! There is no bundling
// required, and provides efficient invalidation similar to HMR.
const {render} = await this.app.vite.ssrLoadModule('/src/entry-server.js')
// 4. render the app HTML. This assumes entry-server.js's exported `render`
// function calls appropriate framework SSR APIs,
// e.g. ReactDOMServer.renderToString()
const appHtml = await render(url)
// 5. Inject the app-rendered HTML into the template.
const html = template.replace(`<!--ssr-outlet-->`, appHtml)
// 6. Send the rendered HTML back.
ctx.status = 200;
ctx.set('Content-Type', 'text/html');
ctx.body = html;
} catch (e) {
// If an error is caught, let Vite fix the stracktrace so it maps back to
// your actual source code.
app.vite.ssrFixStacktrace(e);
ctx.logger.error(e);
ctx.res.status(500);
ctx.body = e.message;
}
}
}
Support all node > 14.0.0 and egg > 2.0.0
MIT Copyright © 2021, seasonjs