Part3-4-1 搭建自己的SSR
构建同构渲染
构建流程
- 通常 Vue 应用程序是由 webpack 和 vue-loader 构建,并且许多 webpack 特定功能不能直接在Node.js 中运行(例如通过 file-loader 导入文件,通过 css-loader 导入 CSS)。
- 尽管 Node.js 最新版本能够完全支持 ES2015 特性,我们还是需要转译客户端代码以适应老版浏览器。这也会涉及到构建步骤。
<template>
<!-- 客户端渲染的入口节点 -->
<div id="app"><h1>拉勾教育</h1>
</div>
</template> <script>
export default { name: 'App'
}
</script> <style> </style>
import Vue from 'vue'
import App from './App.vue' // 导出一个工厂函数,用于创建新的
// 应用程序、router 和 store 实例
export function createApp () { const app = new Vue({ // 根实例简单的渲染应用程序组件。 render: h => h(App) })return { app }
}
import { createApp } from './app' // 客户端特定引导逻辑……
const { app } = createApp() // 这里假定 App.vue 模板中根元素具有 `id="app"`
app.$mount('#app')
import { createApp } from './app' export default context => { const { app } = createApp() return app
}
构建配置
npm i vue vue-server-renderer express cross-env
npm i -D webpack webpack-cli webpack-merge
webpack-node-externals @babel/core
@babel/plugin-transform-runtime
@babel/preset-env babel-loader
css-loader url- loader file-loader
rimraf vue-loader
vue-template-compiler
friendly-errors- webpack-plugin
webpack.base.config.js
/*** 公共配置 */
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const path = require('path')
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
const resolve = file => path.resolve(__dirname, file)
const isProd = process.env.NODE_ENV === 'production'module.exports = {mode: isProd ? 'production' : 'development',output: {path: resolve('../dist/'),publicPath: '/dist/',filename: '[name].[chunkhash].js'},resolve: {alias: {// 路径别名,@ 指向 src '@': resolve('../src/')},// 可以省略的扩展名 // 当省略扩展名的时候,按照从前往后的顺序依次解析extensions: ['.js', '.vue', '.json']},devtool: isProd ? 'source-map' : 'cheap-module-eval-source-map',module: {rules: [// 处理图片资源 {test: /\.(png|jpg|gif)$/i,use: [{loader: 'url-loader',options: {limit: 8192,},},],},// 处理字体资源 {test: /\.(woff|woff2|eot|ttf|otf)$/,use: ['file-loader',],},// 处理 .vue 资源 {test: /\.vue$/,loader: 'vue-loader'},// 处理 CSS 资源 // 它会应用到普通的 `.css` 文件 // 以及 `.vue` 文件中的 `<style>` 块 {test: /\.css$/,use: ['vue-style-loader', 'css-loader']},// CSS 预处理器,参考:https://vue-loader.vuejs.org/zh/guide/pre- processors.html // 例如处理 Less 资源 {test: /\.less$/,use: ['vue-style-loader', 'css-loader', 'less-loader']},]},plugins: [new VueLoaderPlugin(),new FriendlyErrorsWebpackPlugin()]
}
/*** 客户端打包配置 */
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.base.config.js')
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')module.exports = merge(baseConfig, {entry: {app: './src/entry-client.js'},module: {rules: [// ES6 转 ES5 {test: /\.m?js$/,exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],cacheDirectory: true,plugins: ['@babel/plugin-transform-runtime']}}},]},// 重要信息:这将 webpack 运行时分离到一个引导 chunk 中, // 以便可以在之后正确注入异步 chunk。 optimization: {splitChunks: {name: "manifest",minChunks: Infinity}},plugins: [// 此插件在输出目录中生成 `vue-ssr-client-manifest.json`。 new VueSSRClientPlugin()]
})
/*** 服务端打包配置 */
const { merge } = require('webpack-merge')
const nodeExternals = require('webpack-node-externals')
const baseConfig = require('./webpack.base.config.js')
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')module.exports = merge(baseConfig, {// 将 entry 指向应用程序的 server entry 文件 entry: './src/entry-server.js',// 这允许 webpack 以 Node 适用方式处理模块加载 // 并且还会在编译 Vue 组件时, // 告知 `vue-loader` 输送面向服务器代码(server-oriented code)。target: 'node',output: {filename: 'server-bundle.js',// 此处告知 server bundle 使用 Node 风格导出模块(Node-style exports) libraryTarget: 'commonjs2'},// 不打包 node_modules 第三方包,而是保留 require 方式直接加载 externals: [nodeExternals({// 白名单中的资源依然正常打包 allowlist: [/\.css$/]})],plugins: [// 这是将服务器的整个输出构建为单个 JSON 文件的插件。 // 默认文件名为 `vue-ssr-server-bundle.json`new VueSSRServerPlugin()]
})
"scripts": {"build:client": "cross-env NODE_ENV=production webpack --config build/webpack.client.config.js","build:server": "cross-env NODE_ENV=production webpack --config build/webpack.server.config.js","build": "rimraf dist && npm run build:client && npm run build:server"},
npm run build:client
npm run build:server
npm run build
const Vue = require('vue')
const express = require('express')
const fs = require('fs')
const serverBundle = require('./dist/vue-ssr-server-bundle.json')
const clientManifest = require('./dist/vue-ssr-client-manifest.json')
const template = fs.readFileSync('./index.template.html', 'utf-8')
const renderer = require('vue-server-renderer').createBundleRenderer(serverBundle, {template,clientManifest
})const server = express()server.use('/dist', express.static('./dist'))server.get('/', (req, res) => {renderer.renderToString({title: '拉勾教育',meta: `<meta name="description" content="拉勾教育" />`}, (err, html) => {if (err) {return res.status(500).end('Internal Server Error')}res.setHeader('Content-Type', 'text/html;charset=utf8')res.end(html)})
})server.listen(3000, () => {console.log('server running at port 3000')
})
解析渲染流程
(1)服务端渲染
renderer.renderToString 渲染了什么? renderer 是如何拿到 entry-server 模块的?
createBundleRenderer 中的 serverBundle
server Bundle 是 Vue SSR 构建的一个特殊的 JSON 文件
entry:入口 files:所有构建结果资源列表 maps:源代码 source map 信息
server-bundle.js 就是通过 server.entry.js 构建出来的结果文件 最终把渲染结果注入到模板中
(2)客户端渲染 vue-ssr-client-manifest.json
publicPath:访问静态资源的根相对路径,与 webpack 配置中的 publicPath 一致 all:打包后的所有静态资源文件路径 initial:页面初始化时需要加载的文件,会在页面加载时配置到 preload 中 async:页面跳转时需要加载的文件,会在页面加载时配置到 prefetch 中 modules:项目的各个模块包含的文件的序号,对应 all 中文件的顺序;moduleIdentifier和 和all数组中文件的映射关系(modules对象是我们查找文件引用的重要数据)
构建开发模式
基本思路
生产模式
- npm run build 构建
- node server.js 启动应用
开发模式
- 监视代码变动自动构建,热更新等功能
- node server.js 启动应用
所以我们设计了这样的启动脚本:
"scripts": {...
// 启动开发服务
"dev": "node server.js",
// 启动生产服务"start": "cross-env NODE_ENV=production && node server.js"
}
服务端配置:
1
Part3-4-1 搭建自己的SSR相关推荐
- 8.4.1 搭建自己的SSR
本文为拉勾网大前端高薪训练营第一期笔记 心得体会 SSR是未来前端页面必不可少的一个组成成分,掌握了Vue SSR基本上其他框架都非常类似. 3-4-1 搭建自己的SSR Vue SSR 介绍 是什么 ...
- 理解vue ssr原理,自己搭建简单的ssr框架
理解vue ssr原理,自己搭建简单的ssr框架 前言 大多数Vue项目要支持SSR应该是为了SEO考虑,毕竟对于WEB应用来说,搜索引擎是一个很大的流量入口.Vue SSR现在已经比较成熟了,但是如 ...
- Vue.js 框架源码与进阶 - 搭建自己的SSR
文章目录 一.Vue SSR 介绍 1.1 Vue SSR 是什么 1.2 使用场景 1.3 如何实现 Vue SSR 二.Vue SSR 基本使用 2.1 渲染一个 Vue 实例 2.2 与服务器集 ...
- vue前端进阶之SSR篇 --- 搭建简单的SSR框架
目录 理解ssr SSR的重要性 非SSR SSR 了解vapper 制作简易版脚手架 vue框架 环境区分 目录结构 api router views head信息 打包运行 结束 理解ssr 博主 ...
- Vue 服务端渲染(SSR)、Nuxt.js - 从入门到实践
前言 10月初有幸接到公司官网改版需求,要求采用服务端渲染模式对原网站进行seo优化. 由于团队一直使用的vue技术栈,所以我第一时间想到的就是采用vue 服务端渲染(SSR)来实现该需求,即能减少团 ...
- IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/中后台/体验管理等)之详细攻略
IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/Node/IDE/中后台/体验管理/ ...
- 自定义vue SSR
项目源码地址 : https://github.com/qifutian/learngit/tree/main/vue-ssr 搭建自己的SSR mkdir vue-ssr cd vue-ssr np ...
- Nuxt.js(Vue SSR)创建项目到服务器(Nginx+PM2)部署详细流程
一.什么是 SSR ? SSR 就是 服务器渲染,什么是 服务器渲染?由 服务器 组装好 DOM 元素,生成 HTML 字符串给到浏览器,也就是在浏览器里面是可以看到整个页面的 DOM 源码的. SS ...
- umi ssr 之从入门到放弃
今年7月份的时候用umi搭建了react ssr,发现了不少问题,记录一下,作为后来人选型的参考,是真正的从入门到放弃.如果下面罗列的问题你们自己有办法解决,那可以考虑使用,当然,以下仅供参考,可能官 ...
最新文章
- 【组队学习】【35期】SQL编程语言
- VUE—从入门到飞起(一)
- android token机制_对Android 中的 ANR 进行详解
- 【OpenGL】Shader技巧集合
- 基于JAVA+SpringMVC+MYSQL的医院后勤管理系统
- 【POJ2259】Team Queue(队列,模拟)
- 好用小工具及文章推荐推荐
- 记录常用的chrome插件
- 三峡大学校赛----十万桃花图(线性基)
- cocos2d_x之AnySDK接入流程
- BIOS视频中断 10号中断详解
- 数学与物理桥梁下的鸟瞰
- 7-文件IO-阻塞与非阻塞IO
- html手机号输入框,手机号输入框自动格式化为344
- 基本数据类型 int操作 bool布尔操作 str字符串操作 for in 循环
- 获取mumu模拟器日志
- windows装linux
- 群辉查看硬盘存储占用的方式
- java新手案例_java初学者都要掌握的案例
- 飞链云版图-文字生成图片