1、修改路由配置

// router/index.jsimport Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'Vue.use(VueRouter)// 工厂函数 每次请求返回一个Router实例
export function createRouter() {return new VueRouter({mode: 'history',base: process.env.BASE_URL,routes})
}const routes = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About', component: () => import('../views/About.vue')}
]

2、修改vuex配置

// store/index.jsimport Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)//createStore
export function createStore() {return new Vuex.Store({state: {count: 99,},mutations: {add(state){ state.count += 1}},actions: {},modules: {}})
}

3、修改main.js

// main.jsimport Vue from 'vue'
import App from './App.vue'//引用createRouter,createStore
import { createRouter } from './router'
import { createStore } from './store'Vue.config.productionTip = false// 需要每次请求 放回一个vue实例(不用挂载app)
export function createApp(context) {const router = createRouter()const store = createStore()const app = new Vue({router,store, // 挂载context, // 用于和外的renderer交互render: h => h(App)})return {app, router}
}

4、在src录下创建服务端入口(entry-server.js)

// src/entry-server.js
// 和渲染器打交道
// 创建vue实例
import { createApp } from './main'export default context => {const { app, router } = createApp(context)return new Promise((resolve, reject) => {// 跳转首屏地址router.push(context.url)// 等待路由就绪router.onReady(() => {resolve(app)}, reject)})
}

5、在src目录下创建客户端入口文件entry-client.js

// src/entry-client.jsimport { createApp } from './main'const { app, router } = createApp()router.onReady(() => {app.$mount('#app')
})

6、webpack配置

npm install webpack-node-externals lodash.merge -D

npm i vue vue-server-renderer -S // 必须和vue保持同一版本

7、在项目根目录下创建vue.config.js并配置

// 两个插件分别负责打包客户端和服务端
const VueSSRServerPlugin = require("vue-server-renderer/server-plugin");
const VueSSRClientPlugin = require("vue-server-renderer/client-plugin");
const nodeExternals = require("webpack-node-externals");
const merge = require("lodash.merge");// 根据传入环境变量决定入口文件和相应配置项
const TARGET_NODE = process.env.WEBPACK_TARGET === "node";
const target = TARGET_NODE ? "server" : "client";module.exports = {css: {extract: false},outputDir: './dist/'+target,configureWebpack: () => ({// 将 entry 指向应用程序的 server / client 文件entry: `./src/entry-${target}.js`,// 对 bundle renderer 提供 source map 支持devtool: 'source-map',// target设置为node使webpack以Node适用的方式处理动态导入,// 并且还会在编译Vue组件时告知`vue-loader`输出面向服务器代码。target: TARGET_NODE ? "node" : "web",// 是否模拟node全局变量node: TARGET_NODE ? undefined : false,output: {// 此处使用Node风格导出模块libraryTarget: TARGET_NODE ? "commonjs2" : undefined},// https://webpack.js.org/configuration/externals/#function// https://github.com/liady/webpack-node-externals// 外置化应用程序依赖模块。可以使服务器构建速度更快,并生成较小的打包文件。externals: TARGET_NODE? nodeExternals({// 不要外置化webpack需要处理的依赖模块。// 可以在这里添加更多的文件类型。例如,未处理 *.vue 原始文件,// 还应该将修改`global`(例如polyfill)的依赖模块列入白名单whitelist: [/\.css$/]}): undefined,optimization: {splitChunks: undefined},// 这是将服务器的整个输出构建为单个 JSON 文件的插件。// 服务端默认文件名为 `vue-ssr-server-bundle.json`// 客户端默认文件名为 `vue-ssr-client-manifest.json`。plugins: [TARGET_NODE ? new VueSSRServerPlugin() : new VueSSRClientPlugin()]}),chainWebpack: config => {// cli4项目添加if (TARGET_NODE) {config.optimization.delete('splitChunks')}config.module.rule("vue").use("vue-loader").tap(options => {merge(options, {optimizeSSR: false});});}
};

8、脚本配置安装依赖

npm i cross-env -D

9、修改package.json配置

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "npm run build:server & npm run build:client",
    "build:client": "vue-cli-service build",
    "build:server": "cross-env WEBPACK_TARGET=node vue-cli-service build"
  },

10、修改public目录下的index.html

<!DOCTYPE html>
<html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><!-- 1.删掉之前动态标签 --><title>{{title}}</title></head><body><!-- 2.把宿主元素变成一个注释 --><div id="app"><!--vue-ssr-outlet--></div></body>
</html>

11、新增服务器启动文件 (根目录创建文件 server/ssr.js)

// 创建一个express实例
const express = require('express')const app = express()// 获取绝对地址
const resolve = dir => require('path').resolve(__dirname, dir)// 静态文件服务
// 开发dist/client目录,关闭默认的index页面打开功能
app.use(express.static(resolve('../dist/client'), {index: false}))// 创建渲染器
const { createBundleRenderer } = require('vue-server-renderer')
// 参数1:服务端bundle
const bundle = resolve('../dist/server/vue-ssr-server-bundle.json')
const renderer = createBundleRenderer(bundle, {runInNewContext: false, // https://ssr.vuejs.org/zh/api/#runinnewcontexttemplate: require('fs').readFileSync(resolve("../public/index.html"), "utf-8"), // 宿主文件clientManifest: require(resolve("../dist/client/vue-ssr-client-manifest.json")) // 客户端清单
})// 只做一个件事,渲染
app.get('*', async (req, res) => {try {const context = {
title:'',url: req.url}// 渲染: 得到html字符串const html = await renderer.renderToString(context)// 发送回前端res.send(html)} catch (error) {res.status(500).send('服务器内部错误')}})// 监听端口
app.listen(3000, () => console.log('服务器开启'))

12、打包文件

npm run build

//会创建一个dist文件目录,名下包括client和server两个文件件

13、启动服务器node

node ./server/ssr.js

14、注意事项

1)、vue与vue-server-renderer版本一致

2)、报错:Error: [webpack-node-externals] : Option 'whitelist' is not supported. Did you mean 'allowlist'   //修改vue.config.js(whitelist 改成 allowlist)

3)、在beforeCreate,created除外的生命周期以及全局的执行环境中调用特定的api前需要判断执行环境

4)、每次修改需要重新打包,重启服务器

5)、其他注意事项vue-ssr问题 - 简书

VUE项目配置SSR相关推荐

  1. 使用Jenkins持续集成Vue项目配置Sonar任务

    title: 使用Jenkins持续集成Vue项目配置Sonar任务 tags: jenkins Vue.js Sonar categories: ci date: 2017-12-05 22:09: ...

  2. 新版Vue项目配置项目名称-publicPath-前端_v1.0.2

    文件名称 版本号 作者 qq 版本 新版Vue项目配置项目名称-publicPath-前端 v1.0.2 学生宫布 8416837 webpack 4.28.4 文章目录 js配置 js配置 定义全局 ...

  3. vue项目设置服务器地址,vue项目配置后端服务器地址

    vue项目配置后端服务器地址 内容精选 换一换 查询负载均衡器状态树.可通过该接口查询负载均衡器关联的监听器.后端云服务器组.后端云服务器.健康检查.转发策略.转发规则的主要信息,了解负载均衡器下资源 ...

  4. Vue项目配置本地访问地址和IP访问地址

    Vue项目配置本地访问地址和IP访问地址 1.在config/index.js配置: dev: {host: '0.0.0.0', } 2.在build/webpack.dev.config.js更改 ...

  5. SwitchHosts使用和vue项目配置

    SwitchHosts使用和vue项目配置 1.解压SwitchHosts到本地电脑上,右键以管理员身份运行exe文件: 2.配置自己需要的域名 3.vue项目中修改配置文件 webpack.dev. ...

  6. vue项目配置eslint(附visio studio code配置)

    eslint基础环境搭建 全局安装eslint:npm install eslint -g 项目eslint初始化:eslint --init,按团队或自己的编程风格回答三道题. ? How woul ...

  7. vue项目配置public静态资源路径访问

    1.简介 一般的vue项目都有一个初始index.html,而其他js.css都是这个html引入的,默认情况下使用绝对路径引入,如/js/app.js 这样就有一个问题,静态资源经常要部署在不同的上 ...

  8. vue项目配置 webpack-obfuscator 进行代码加密混淆

    背景 公司代码提供给第三方使用,为了不完全泄露源码,需要对给出的代码进行加密混淆,前端代码虽然无法做到完全加密混淆,但是通过使用 webpack-obfuscator 通过增加随机废代码段.字符编码转 ...

  9. vue项目配置生产、测试和开发环境

    目前的 web 项目开发基本都是基于前后端分离的模式. 在实际的开发过程中,从开发到测试完成.发布到线上所调用到的接口地址可能都不一样,那就需要在项目中分别配置各个环境的接口地址(或者域名,也可以定义 ...

  10. vue项目配置rem移动端适配

    一.项目介绍 脚手架CLI:@vue/cli Vue版本:2.6.11 移动UI组件库:Vant#2.10.14 CSS预处理器:sass 二.配置lib-flexible插件 下载插件 npm i ...

最新文章

  1. “反过来”学数学:从图形到符号的思考法
  2. 使用Wasserstein距离鉴别器的无监督图对齐
  3. 30 万奖金悬赏 | CSDN 软件开发精英赛即日启动!
  4. bom event周期_DOM-BOM-EVENT(1)
  5. sscanf()函数的用法
  6. java 前端页面传过来的值怎么防止篡改_杂谈!了解一些额外知识,让你的前端开发锦上添花...
  7. [转载]项目风险管理七种武器-霸王枪
  8. [上海]招募.net网站测试员(实习/见习)
  9. java8 streamlist转化
  10. 雪亮工程视频监控应用系统解决方案
  11. 会议录播软件测试自学,如何录制Zoom视频会议?
  12. Assassin’s Creed(hdu4415,贪心)
  13. linux+pe+网络扫描,Ubuntu 18.04及其他版本Linux 下 Nmap 网络扫描工具的安装与使用
  14. 从Docker镜像创建Singularity镜像(SIF文件)
  15. 35行代码搞定事件研究法(下)
  16. Pycharm远程调试服务器代码出错:[Errno 2] No such file or directory
  17. 情人节如何表达你的“心”
  18. Android OKHttp 拦截器
  19. 【技美百人计划】图形 4.2 SSAO算法 屏幕空间环境光遮蔽(&HBAO)
  20. 自动化测试===【转】Robot Framework作者建议如何选择自动化测试框架

热门文章

  1. 钟平逻辑英语语法_钟平逻辑英语教程视频1-5季全(含笔记 支持百度云)
  2. 究竟云计算就业前景好不好 零基础如何学云计算
  3. IE浏览器不能使用window.open()的解决方案
  4. 如何编写一份高质量的测试报告
  5. SEM 与 SEO 之间的区别与联系
  6. 中国止血分析仪行业市场供需与战略研究报告
  7. MFC USB调试助手
  8. 什么是项目沟通管理?
  9. Word转图片的方法(两种)
  10. Johnson法则-流水作业调度-动态规划