// main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import {createRouter} from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
const createApp = () => {
const router = createRouter()
const app = new Vue({
router,
render: h => h(App)
})
return {app, router}
}
export {createApp}
同样router.js也需要通过工厂函数创建
// router.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import HelloSsr from '@/components/HelloSsr'
Vue.use(Router)
export function createRouter () {
return new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},{
path: '/ssr',
name: 'HelloSsr',
component: HelloSsr
}]
})
}
// webpack.prod.conf.js
plugins:[
// ...
// new ExtractTextPlugin({
// filename: utils.assetsPath('css/[name].[contenthash].css'),
// // Setting the following option to `false` will not extract CSS from codesplit chunks.
// // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
// allChunks: true,
// }),
// ...
]
手写ssr渲染
前言
在正式搭建项目之前,我们还是要回顾下vue服务器端渲染的一些特性。 服务器端渲染的 Vue.js 应用程序,是使vue应用既可以在客户端(浏览器)执行,也可以在服务器端执行,我们称之为“同构”或“通用”。
之所以能够实现同构,是因为在客户端和服务端都创建了vue应用程序,并都用webpack进行打包,生成了server bundle和client bundle。server bundle用于服务器渲染,client bundle是一个客户端的静态标记,服务器渲染好html页面片段后,会发送给客户端,然后混合客户端静态标记,这样应用就具有vue应用的特性。 需要注意是:
服务器端渲染过程中,只会调用beforeCreate和created两个钩子函数,其它的只会在客户端执行。那么以前spa应用中,在created中创建一个setInterval,然后在destroyed中将其销毁的类似操作就不能出现了,服务器渲染期间不会调用销毁钩子函数,所以这个定时器会永远保留下来,服务器很容易就崩了。 由于服务器可客户端是两种不同的执行平台环境,那么一些特定平台的API就不能用了,比如window和document,在node.js(比如created钩子函数)中执行就会报错。并且,我们使用的第三方API中,需要确保能在node和浏览器都能正常运行,比如axios,它向服务器和客户端都暴露相同的 API(浏览器的源生XHR就不行)。
安装依赖包
1.创建一个简单的ssr渲染
创建一个vue ssr 渲染器
// 第二步创建一个 ssr 渲染器 const renderer = require('vue-server-renderer').createRenderer()
// 第三步将vue实例渲染为html字符串
renderer.renderToString(app, (err, html) => { if (err) throw err console.log(html) })
将模板文件内容设置到渲染器里
创建一个express服务
2.利用vue-cli创建一个ssr模板
安装vue-cli脚手架
创建项目
安装vue-server-renderer
改造src下的文件
通用入口main.js和路由router.js改造
main.js作为浏览器和服务器通用创建实例入口,需要改造成工厂函数来创建实例,保证各自独立性。且因单线程的机制,在服务器端渲染时,过程中有类似于单例的操作,那么所有的请求都会共享这个单例的操作。
同样router.js也需要通过工厂函数创建
客户端 entry-client.js
服务端 entry-server.js
webpack 配置
vue相关代码已处理完毕,接下来就需要对webpack打包配置进行修改了。 官方推荐了下面配置:
webpack.base.conf.js修改
1.修改入口配置
1.引入SSR渲染插件client-plugin
修改utils.js
注释webpack.prod.conf.js的 ExtractTextPlugin 插件
webpack.server.conf.js配置
1.引入 webpack-node-externals, 引入并使用server-plugin
package.json打包命令修改
修改index.html
打包构建
构建服务器端
引用
带你走近Vue服务器端渲染(VUE SSR)