ssr学习笔记

什么是ssr
服务端渲染 service render
加载速度,seo
传统vue纯浏览器渲染 浏览器请求,服务器返回一个空的HTML和js给浏览器
这种渲染方式的问题:首页加载时,将所有页面的js都返回了,首屏加载慢。
seo是基于HTML来收录网站,只能爬到一个空的HTML页面
性能问题:先执行js,生成dom,发送请求,请求返回后,浏览器解析数据,操作数据,
重新渲染dom,

优点:能够带来接近原生app的体验,能够前后端分离。

ssr渲染:请求发送到node服务器上
接收到请求后,分析是请求的那个页面,然后node服务端拿到这个页面的组件,将这个页面
设计的js执行完,生成HTML,然后返回给服务器。

ssr需要哪些东西:
将app.js分成两个入口,交给webpack来打包,生成server的bundle在服务端yunx
生成的client的bundle在客户端进行。

ssr的特性
每次访问必须新建一个vue实例,只会触发组件的beforeCreate和created钩子
所以需要客户端的js

核心库
vue和vue-server-render

实现

1.把vue对象变成HTML字符串
test.js

const vue =require('vue');
const app=new vue({
template:'<div>{{num}}</div>',
data:{
    num:123
}

const renderer=require('vue-server-render').createRenderer();
renderer.renderToString(app).then(html=>{
    console.log(html)
})

})

node test.js

server.js
const vue =require('vue');
const server=require('express')();
const renderer=require('vue-server-render').createRenderer();
const fs=require('fs');

function createApp(url){
//根据URL返回vue实例
if(url=="/"){
url="/index"
}
var json=fs.readFileSync(`json${url}.json`,'utf-8');
var template=fs.readFileSync(`json${url}.html`,'utf-8');

return new vue({
   template:template,
   data:Json.parse(json).data
})

}
//请求所有地址
server.get('*',function(req,res){
    if(req.url!='/favicon.ico'){
    const app=createApp(req.url);
renderer.renderToString(app,(err,html)=>{
    if(err)
    {
        res.status(500).end('server error');
        return;
    }
    res.end(html);
})
    
}

})
server.listen(7070);

node server.js

将vue项目改造成为ssr

1.新建client.js文件和server.js文件
2.新建index.ssr.html文件和index.html文件

在index.ssr.htnl 文件中加注释
<!--vue-ssr-outlet-->
引入js文件
htmlwebpackPlugin.options.file.js

3改造路由
index.js

export function createRouter(){
    return new Router({
    mode:'history',
routes:[
{
path:'/',
name:'helloword',
component:Helloword
},
{
path:'/test',
name:'test',
component:Test
}
]

})

4.main.js 

引入index.js获取到路由
import {createRouter} from ...

var router=createRouter();

改造创建vue根实例方法

export function createApp(){
    const app=new Vue({
    router,
render:h=>h(App)
})
}
return {app,router}
}

5改造server.js

import{createApp} from ...
//context 是req

export default context=>{
 return new Promise((resove,reject)=>{
    const {app,router}=createApp();
    router.push(context.url);
    router.onReady(()=>{
    const matchComponets=router.getMatchedComponents();
    if(!matchComponets){
    return reject({code:404});
}
resolve(app);

},reject)
})
}

改造client.js
import{createApp} from ...
const {app,router}=createApp();

router.onReady(()=>{
//挂载组件
    app.$mount("#app");
    
})

改造webpack打包文件
新建
webpackbuildclicent.js

webpackbuildServer.js


//webpackbuildServer.js

//引入插件
const vuessrserverplugin=require('vue-server-render/server-plugin')
指定入口
entry:{
app:'./src/server.js
},
target:'node',
output:{
libraryTarget:'commonjs2'
}

plugins:[
    new VueSSRServerPlugin()
]

//去掉代码分割,复制还有一些配置,太复杂

修改HTMLwebpackplugin的template

为ssr.html

且去掉压缩注释的配置【因为去掉注释,不知道把生成的HTML插入到哪里了】

files:{
js:app.js
}


//webpackbuildclicent.js

//去掉代码分割

//引入插件
const vuessrclientplugin=require('vue-server-render/client-plugin')


plugins:[
    new VueSSRClientPlugin()
]


entry:{
app:'./src/client.js
},

删掉出口【因为base.conf.js中有出口,可以合并】

修改package.js
"scripts":{
"build:client":"webpack --config build/webpack.buildclient.js"
"build:server":"webpack --config build/webpack?buildserver.js"
}

打包
npm run build:client

npm run build:server


编写服务  server.js

const express=require('express');
const server=express();
const {createBuldeRenderer}=require('vue-server-renderer');
const path=require('path');
const fs=require('fs');//文件读取模块
//json文件是通知服务器,哪些js是跑在客户端的js,哪些是跑在服务端的js
const serverBundle=require(path.resolve(__dirname,"../dist/vue-ssr-server-bundle.json));
const clientManifest=require(path.resolve(__dirname,"../dist/vue-ssr-client-manifest.json));
const template=fs.readFileSync(path.resolve(__dirname,"../dist/index.ssr.html"),"utf-8");

//生成渲染对象
const renderer=createBuldeRenderer(serverBundle,{
runInNewContest:false,
template:template,
clientManifest:clientManifest//客户端
})

//设置静态目录,服务开启后,这个文件可以被访问
server.use(express.static(path.resolve(__dirname,"./dist")));

//设置访问路由
server.get('*',function(req,res){
    if(req.url!='/favicon.ico'){
    const context={url:req.url};
const ssrStream=renderer.renderToStream(context);
let buffers=[];
ssrStream.on('error',(err)=>{console.log(err)});
ssrStream.on('error',(data)=>{buffes.push(data)});
ssrStream.on('end',()=>{
    res.end(Buffer.concat(buffers));
})

}
    
})
    
server.listen(1000)

运行 node server.js

})

nuxt的使用
npx create-nuxt-app

https://segmentfault.com/a/1190000016637877#item-2-2


自己手动搭建一个ssr+vue项目

vue方便的ssr框架nuxt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值