Time is fast , This is the second half of this series Vue The first 12 It's time , Yesterday I also thought about it briefly , Maybe another one tomorrow ,Vue
It's almost over , Why , Here's a digression , When I was blogging , I just want to give you more motivation to learn , Remind me every day , There is no outline or arrangement to explain anything at all , Is to follow the direction of my own learning , I just found a rule : Every series happens to be
1 Introduction + 12
Text , I don't know if you feel about this , You may know when you see my picture , ha-ha , Actually, I'm a big fan , It's just a coincidence , Both series have formed this , I selfishly drew a plan for myself , It's just a set of judgments —— Twelve hairpins , Vice volume , Another copy and so on ( explain : This is my own wishful thinking , If you have fans , Please don't spray me
[ wry smile ] ), according to schedule , Should be able to write 9 Ministry , Except for the introduction , nothing less than 108
piece , Ha ha, let's talk about it later . Here, I thought about it yesterday , If you have fans, you can also find me , Additive group (867095512) Or individuals QQ(3143422472) Either way .

because Vue This series still has a lot to say , But we've talked about the basics , You can go through the portal again 《Vue study 12 piece
》, What about today , Let's talk about a cliche , It's how to do it Vue Of SSR Server rendering , If it's the first time you've been exposed to it , It may be strange , Don't panic , This article is for you to pass
Nuxt.js frame , To explain the problem , Then in order to realize our second project in the future , It would look like this ( Notice that the source code of the page already has content ):



be careful : I'm just going to show you today SSR Server rendering , Can say a little DEMO
, The specific code of the frame in the figure above , We'll talk about it in our second blog project , Because there is no end to one or two articles in this framework .


Zero , The blue block is to be completed today



One ,Vue Of SSR What the hell is it ?


From the official explanation :

Vue.js Is the framework for building client applications . By default , It can be output in the browser Vue assembly , Generate DOM And operation
DOM. however , You can also render the same component as server-side HTML character string , Send them directly to the browser , Finally, these static tags are " activation " It is a fully interactive application on the client .

Server rendered Vue.js Applications can also be considered " isomorphism " or " currency ", Because most of the application code can run on both the server and the client .

Shyness is hard to understand

My personal understanding is that :

1, at present Vue The pattern of :

In the process of generating the page , We are now putting the components in the browser , And then put Data Generated by filling into components
DOM, This is also the action of a general asynchronous operation , That's what we usually do , Write it on the page first DIV, Then use Jquery get data , Fill in data to DIV in


2,SSR What about the mode of , It's going to be in the server first Data First render the components into Html character string , As a static resource , It's like css String , Then throw it to the front page .

The second is SSR Server rendering , You should have noticed the difference between this and ordinary —— It's rendering html Control of the fragment has shifted to the server , So why do you do this ? Please look down .

  be careful : The server here , It's not in us .net core api Generated in , It's in the vue in , We passed webpack After packing node server To deal with .

Two , Why SSR Server rendering ?

1, First of all, we need to talk about search engines —— SEO

Let's turn on any search engine , Whether it's Google , Or Baidu , Or Sogou and so on , You can see all kinds of information , written words , picture , video , I don't know what people think of this process , I used to think it was all kinds of people , Submit your own content or document to Baidu's server , Then we read from Baidu's server , search , Um. , This comes from when I was in high school , The imagination of searching all kinds of Baidu Library , This is a search I know
1.0 .

And then I worked , Start writing for the first time Web , At that time, the manager asked to write TDK(Title + Description +
Key), I was curious at the time why I said that , Said the manager , It's for the sake of SEO , Well, all right , Although I don't quite understand , I understand —— Set up the TDK
in the future , That search engine will find our keywords , Then we can search our website in the search engine , Um. ~ That sounds good , This is the time , I'm in a mess , Not that we have to save into Baidu's database , Can we find it , Isn't it amazing , This is what I know about search
2.0 .

It's been a while , More and more people have been contacted , At this time, I was in charge of a travel project , Said the boss , Our data is only a thousand , Less , It's not very convenient for users to search us , Let me do some online data ( It's legal, of course , Just for display , Focus ), At this time, I learned that there was
Reptiles This thing ! The original online resources can be freely obtained ( lawful × 3
!), This is the time to look back at the engine , Oh ! It turns out that they are crawling the information on the Internet , Take a chestnut : You can search on Baidu   “ Lao Zhang's Philosophy .net core
”, Will see our article , You can see that there are not only topics , There is also the body of the article , That is to say , Baidu crawls is not only ours TDK , And the content of our article , Maybe this is what I know about search 3.0 了 .


So , If we need to make our articles , Websites are crawled by search engines , And it was searched by everyone , Must be set TDK And have page content , But at this time , We're full of new things to open up
Vue The first version of the blog project , And found this ..


The articles we worked so hard to write were not generated by browsers , Naturally, it won't be picked up in the future , If our mall is the same , How much less traffic is that , It's all money , So , If it is with article class , Content class , Commodity
Web project , We must solve this problem , This is why SSR The first reason for .

You can take a look at the second item at the top of the article gif chart , It's through Nuxt Implementation of server-side rendering , There is already content in the source code . 


2, by Vue Rendering bottlenecks help

In the two processes above , We can see that , Normal client rendering , and SSR The biggest difference of server-side rendering is that ,Html Who controls the clip , yes Vue
Or the server , If it's the front end ,h5 request API When , Because it involves cross domain , In addition to the limitations of the server itself , And the user network , Broadband and many other restrictions , We need to wait for the entry page and JS
Download successful , In order to get data according to logic , There will be many problems .

And if the current page has too much logic , When the data is too cumbersome , ours vue
Rendering on the client side can also become a performance bottleneck , The most obvious is the homepage of some e-commerce companies ( For example, some treasure , It's really complicated to open that front page ) The first time it was loaded , The appearance of white screen ,loading Rendering of Graphs , It's embarrassing , Although the fence is now used to preheat , But it's still uncomfortable . This is the bottleneck , If only from
Vue To solve this bottleneck , It costs a lot , So it's used at this time SSR Server rendering , And we can use it Redis To cache these pages Html
fragment , We'll load faster .


  Three , How to achieve this SSR Server rendering —— be based on webpack Simple program for

be careful : Today we are mainly to explain SSR Content of , Principle and basic use , Here's a little Demo Chestnut , We will use a framework for future projects Nuxt.js

1, be based on webpack initialization npm project

New folder  VueSSRDemo3 , After entering , implement   npm i , Initialize project
npm i
You'll see one package-lock.json file , Do you remember that , In a nutshell , It is to ensure the consistency of the project , Make sure that unity development relies on the same package , I'll add it here :

1,npm 5.0.x edition , No matter package.json How ,npm i Time will be based on lock File download

package-lock.json file not updated after package.json file is changed · Issue
#16866 · npm/npm

this issue And charged the problem , It was changed manually package.json, Why don't you give me the upgrade package ! And then it led to 5.1.0 The problem of ...

2,npm 5.1.0  After version npm install Will ignore lock file To download the latest npm

And then someone mentioned this issue why is package-lock being ignored? · Issue #17979 · npm/npm

Complain about the problem , Finally, it evolved into 5.4.2 Rules after version .

3,npm 5.4.2  After version why is package-lock being ignored? · Issue #17979 · npm/npm

It means roughly , If it's changed package.json, And package.json and lock The documents are different , Then execute `npm
i` Time npm According to package Download the latest package with the version number and semantic meaning in , And updated to lock.


2, newly build package.json Dependent package file
{ "name": "ssr", "version": "1.0.0", "description": "", "main": "index.js", "
scripts": { "server": "webpack --config ./webpack/webpack.server.js", "client":
"webpack --config ./webpack/webpack.client.js" }, "author": "laozhang", "license
": "ISC", "dependencies": { "axios": "^0.16.0", "babel": "^6.23.0", "
babel-plugin-transform-runtime": "^6.23.0", "babel-polyfill": "^6.26.0", "
babel-preset-env": "^1.7.0", "body-parser": "^1.18.3", "compression": "^1.7.2",
"express": "^4.15.4", "express-http-proxy": "^1.2.0", "gulp": "^3.9.1", "
gulp-shell": "^0.6.5", "http-proxy-middleware": "^0.18.0", "less": "^3.0.4", "
less-loader": "^4.1.0", "shell": "^0.5.0", "superagent": "^3.8.3", "vue": "
^2.2.2", "vue-meta": "^1.5.0", "vue-router": "^2.2.0", "vue-server-renderer": "
^2.2.2", "vue-ssr-webpack-plugin": "^3.0.0", "vuex": "^2.2.1", "vuex-router-sync
": "^4.2.0" }, "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "
^6.4.1", "babel-preset-es2015": "^6.24.1", "css-loader": "^0.28.4", "
style-loader": "^0.18.2", "vue-loader": "^11.1.4", "vue-template-compiler": "
^2.2.4", "webpack": "^2.7.0" } }
3, implement npm install Install dependency package
npm install
And then it will increase node_modules folder , This is very familiar to everyone .


4, Some new documents , And fill in the contents in turn

The structure is as follows :
├── dist      // Save our packaged files ├── node_modules      // Dependent package folder ├── entry      //
│ └── entry-server.js     // Server file ├── src       // Our project source code documentation │ ├── views //
view Storage directory │ │ ├── about.vue         //about page │ │ ├── like.vue         //like page
│ │ └── Home.vue    //Home page │ └── App.vue          // App Entry file │ └── main.js
         // Master profile │ └── router.js           // Routing profile └── .babelrc // babel configuration file
└── package.json// Project dependency package profile └── package-lock.json // npm5 New documents , optimize performance └──
server.js// server file └── README.md // Documentation

The whole structure is like this , And then you start writing code , There are seven documents , You can try it yourself , Or download it directly git code


to update :

There is no specific update below , Only code and partial comments , You can take a look at my next article , Better understand :

《 From the first, the front and rear ends are separated [ Vue2.0+.NetCore2.1] hexacosa- ║Client Rendering ,Server How much do you know about rendering { supplement }

//1,/* entry-server.js */ import { createApp } from '../src/main' export
default context => { return new Promise((resolve, reject) => { const app =
createApp()// Change route app.$router.push(context.url) // Get the components under the corresponding route const
matchedComponents = app.$router.getMatchedComponents() // If there are no components , Indicates that the route does not exist , report errors 404
if (!matchedComponents.length) { return reject({ code: 404 }) } resolve(app) })
}//2, Three vue page , and app vue page , It's a simple way to write it , You can do whatever you want //3,//main.js import Vue from 'vue'
import createRouterfrom './router' import App from './App.vue' //
Export a factory function , Used to create a new vue example export function createApp() { const router = createRouter()
const app = new Vue({ router, render: h => h(App) }) return app } /*4, route.js
*/ import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter)
exportdefault function createRouter() { let router = new VueRouter({ //
Remember to add mode attribute , because # The latter is not sent to the server , The server does not know which route was requested mode: 'history', routes: [ { alias:
'/', path: '/home', component: require('./views/home.vue') }, { path: '/like',
component: require('./views/like.vue') }, { path: '/about', component: require('
./views/about.vue') } ] }) return router } /* 5,webpack.server.js */ const path
= require('path'); const projectRoot = path.resolve(__dirname, '..');
module.exports= { // Let me know here server bundle use Node Style export module (Node-style exports)
target:'node', entry: ['babel-polyfill', path.join(projectRoot, '
entry/entry-server.js')], output: { libraryTarget: 'commonjs2', path:
path.join(projectRoot,'dist'), filename: 'bundle.server.js', }, module: {
rules: [{ test:/\.vue$/, loader: 'vue-loader', }, { test: /\.js$/, loader: '
babel-loader', include: projectRoot, exclude: /node_modules/, options: {
presets: ['es2015'] } }, { test: /\.less$/, loader: "
style-loader!css-loader!less-loader" } ] }, plugins: [], resolve: { alias: { '
vue$': 'vue/dist/vue.runtime.esm.js' } } } //6,babelre file { "presets": [ "
babel-preset-env" ], "plugins": [ "transform-runtime" ] } /*7, server.js */
const express = require('express')() const renderer = require('
vue-server-renderer').createRenderer() const createApp = require('
./dist/bundle.server.js')['default'] // Respond to routing requests express.get('*', (req, res) => {
const context = { url: req.url } // establish vue example , Incoming request routing information
createApp(context).then(app => { renderer.renderToString(app, (err, html) => {
if (err) { return res.state(500).end(' Runtime error ') } res.send(` <!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <title>Vue2.0 SSR Render Page </title>
</head> <body> ${html} </body> </html> `) }) }, err => { if(err.code === 404) {
res.status(404).end(' The requested page does not exist ') } }) }) // Server listening address express.listen(8089, () =>
{ console.log(' Server started !') })

5, Packed File
npm run server
This is the time , You'll find out , ours dist In folder , One more bundle.server.js file


6, Start service
node server
At this point, we can see the effect

7, View source code , We found that our page has been rendered successfully !

So we've reached it SSR The role of



Four , epilogue

Because of the time today , Let's set up the core file first , You know what it is SSR, And the existing problems and solutions , But specific documents entry-server.js ,
webpack-server.js, and server.js What do you mean , Let's make a unified explanation tomorrow , And by the way, we'll introduce a new framework Nuxg.js, A mature SSR
frame .


Five ,Github


After downloading , before npm install Installation dependency

The package and start service commands are then executed
npm run server
node server
  Last visit localhost:8089