这篇的程序码在 https://github.com/DanSnow/ironman-2020/tree/master/static-site-generator/packages/vue-ssr
这篇要来实际尝试 Vue 的 SSR ,这篇做的事很简单,就是在 server render 好一个 Vue 的程序,然後在 Client 端也把 js 加上去,程序的部份放在 App.vue
中,是个很简单的 counter ,我们直接来看其它部份,首先我们要准备一个 app.js
,里面 export 一个函式用来建立 Vue 的程序:
import Vue from 'vue'
import App from './App.vue'
export function createApp() {
const app = new Vue({
render: (h) => h(App),
})
return { app }
}
这边做最主要的原因是确保每次的 render 都会是新的程序,不会受到之前的状态影响之类的,如果有需要加上 store 等等的也要加在里面,目前先不加
再来我们要准备两个进入点,一个给 server 用来 render html,另一个是在 client 回复程序的状态时使用,它们分别叫 entry-server.js
与 entry-client.js
,先是 entry-server.js
:
import { createApp } from './app'
export default (context) => {
const { app } = createApp()
return app
}
目前就很简单的把 createApp
包装一下再 export 出去而已,再来是 entry-client.js
,这其实跟平常写 Vue 没什麽两样:
import { createApp } from './app'
const { app } = createApp()
app.$mount('#root')
再来要准备 webpack 的设定打包这两个档案,我们来写个 webpack.config.js
,另外这篇用的是 webpack 5 ,原生就支援 PnP 感觉很方便:
const webpack = require('webpack')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const baseConfig = {
module: {
rules: [
// vue loader 的设定
{
test: /\.vue$/,
loader: 'vue-loader',
},
],
},
plugins: [
new VueLoaderPlugin(),
// webpack 5 预设不再提供 node 的 API 了
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
}),
],
optimization: {
// 开一下串接模组,这样产出来的档案会小一点,比较好看
// 如果全都是 es6 module , webpack 5 甚至有可能编出不含 runtime 的 code 喔
concatenateModules: true,
},
mode: 'none',
devtool: false,
}
module.exports = [
// server 的设定
{
...baseConfig,
entry: {
server: './src/entry-server',
},
output: {
// 要把 app export 出来,所以这边要设定 `libraryTarget`
libraryTarget: 'commonjs2',
},
// 不需要打包进 vue
externals: ['vue'],
// 一定要指明是 `node` ,这同时会让 vue-loader 编出 SSR 用的 code
target: 'node',
},
// client 的设定
{
...baseConfig,
entry: {
client: './src/entry-client',
},
},
]
写完後就直接输入 yarn webpack
跑一下打包吧,最後是 server.js
:
const { resolve } = require('path')
const express = require('express')
const { createRenderer } = require('vue-server-renderer')
const createApp = require('./dist/server').default
// vue-ssr-outlet 是 vue 的 renderer 会插入 render 好的 html 的位置
const template = `
<html>
<head>
<title>SSR test</title>
</head>
<body>
<!--vue-ssr-outlet-->
<script src="client.js"></script>
</body>
</html>
`
const app = express()
const renderer = createRenderer({
template,
})
app.use(express.static(resolve(__dirname, 'dist')))
app.get('/', async (req, res) => {
const context = {}
const app = createApp()
// 第一个参数是一个 vue 的 instance ,第二个则是一个 object ,回传是一个 promise 包着 html
const html = await renderer.renderToString(app, context)
res.send(html)
})
app.listen(3000, () => {
console.log('listen at http://localhost:3000')
})
就这样,可以在终端机中输入 yarn node server.js
试试了,应该可以在 http://localhost:3000 看到我们的网页,到这边基本的东西准备完了,下一篇我们再来把 vue-router 跟 Vuex 加进去,也顺便试一下 serverPrefetch
跟 bundle renderer 吧
<<: JS读书笔记30天 - Day29 Vue的起手式——建立应用程序
if-else Kotlin的条件判断叙述比较特别,它能够用 if-else 赋值给变数 val r...
GitHub Repo https://github.com/b2etw/Spring-Kotlin...
当在公司历经了三年左右的时间,若能在前面文章的概念中不断落实与反覆演练,加上三年的时间应该可以历经起...
接下来详细一点的说明 YOLOv4 的内部架构! 目标检测通常由以下几个部分组成: Input: 指...
前辈们, 是否有推荐的网路分析仪呢? 目前察到LinkRunner™ G2 Network Auto...