什么是前端服务端渲染 SSR
前端服务端渲染(Server-Side Rendering,SSR)指的是将前端组件在服务端进行渲染,生成 HTML 内容,然后再将其发送给浏览器端,浏览器端只需要渲染服务端返回的内容即可。相对于传统的前端渲染(Client-Side Rendering,CSR),SSR 的最大优势在于它可以减少浏览器端的内存和 CPU 占用,提升初次加载的速度,降低浏览器的网络延迟,提供更好的用户体验。
Webpack 搭建 SSR 的优势
Webpack 是一款非常强大的前端打包工具,它除了可以帮我们打包前端的 JavaScript、CSS、图片等资源之外,还可以帮助我们打包服务端端代码,实现对于前后端分离项目的整合。搭建 SSR 最大的优势在于我们可以共用前端的组件库,避免了前后端大量的代码冗余。
基础准备
在开始搭建 SSR 之前,有几个基础的要求需要完成:
- 确保安装了 Node.js 环境。
- 确保安装了 Webpack 和相关的依赖模块。
创建 SSR 项目目录结构
SSR 的项目结构需要和传统的前端项目有所区分,我们需要将服务端代码和前端代码分别存放在不同的目录中。下面是一个标准的 SSR 项目结构示例:
-- -------------------- ---- ------- --------- -- ------- -- --------- -- --------- -- ------- -- -------- -- ------- -- --------- -- ------------ -- -----------------
其中,server/
目录是服务端代码存放的位置,client/
目录是前端代码(即客户端代码)存放的位置。
完成 Webpack 配置文件
首先我们需要新建一个 webpack.config.js
文件,来存放我们的 Webpack 配置。
-- -------------------- ---- ------- ----- ---- - ---------------- -------------- - - ----- ------------- ------- ------- ------ - ---- --------------------- -- ------- - ----- -------------------- --------------- --------- ------------ -- ------- - ------ - - ----- -------- ------- --------------- -------- --------------- -- - ----- --------- ------- ------------- -- - ----- ------------------------- ------- ------------- -------- - ------ ------ ----- ------------------------- ------------------------- -- -- - ----- --------------------------------- ------- ------------- -------- - ------ ------ ----- ------------------------- ------------------------- -- -- -- -- --
在 Webpack 的配置中,我们需要指定 mode
为 production
,并且指定 target
为 node
,因为服务端运行的环境是 Node.js。entry
用于指定入口文件,这里是 server.js
。output
用于指定打包后的文件存放位置和文件名。
在 module.rules
中,我们需要指定项目中使用到的 babel-loader
、vue-loader
和 url-loader
等模块的相关配置。需要注意的是,Vue.js
项目需要借助 vue-loader
来将 vue
文件转为 JavaScript
代码。
编写服务端代码
服务端代码入口文件 server.js
主要完成以下任务:
- 通过
express
搭建服务端的 HTTP 环境。 - 使用
vue-server-renderer
库来渲染前端组件并返回给浏览器端。
首先需要在 server.js
文件中完成以下依赖模块的引入。
const express = require('express'); const vueServerRenderer = require('vue-server-renderer'); const fs = require('fs'); const path = require('path'); const { createBundleRenderer } = require('vue-server-renderer');
接着创建一个 express
实例,并指定监听的端口号。
const app = express(); const port = process.env.PORT || 8080;
然后获取打包好的 bundle
文件。
const clientManifest = require('./client-dist/vue-ssr-client-manifest.json'); const serverBundle = require('./server-dist/app.js');
接下来,我们还需要完成一个比较常见的操作 —— 托管服务端的静态文件。这一步非常重要,因为 SSR 在服务端进行渲染,所以我们需要在服务端获取相关的资源,一般情况下就是 Vue 打包出来的 JavaScript 和 CSS 文件。
app.use('/static', express.static(path.join(__dirname, './client-dist/static')));
接下来,我们需要使用 createBundleRenderer
函数创建一个 renderer
对象,这个对象包含了渲染 Vue 多页面应用所需要的所有信息,也就是说我们可以通过这个对象来实现服务端渲染。
const renderer = createBundleRenderer(serverBundle, { runInNewContext: false, template: fs.readFileSync(path.join(__dirname, './index.template.html'), 'utf-8'), clientManifest, });
在 createBundleRenderer
函数中,我们需要指定打包好的 serverBundle
和 clientManifest
文件的位置,这样我们才能相关文件的信息。runInNewContext
用于指定是否使用新的 V8 编译器,因为使用新的 V8 编译器会导致我们无法使用 server bundle 中的 module。
最后,我们需要将所有的请求都路由到服务端渲染函数中去处理。
-- -------------------- ---- ------- ------------ ----- ---- -- - ----- ------- - - ---- ------- -- -------------------------------- ----- ----- -- - -- ----- - ------------------- ----------------------------- ------ -------- ------- - -------------- --- ---
编写模板文件
模板文件 index.tamplate.html
主要是用来描述 SSR 生成的 HTML 结构,让浏览器端能够正常识别和渲染。
-- -------------------- ---- ------- --------- ----- ----- ---------- ------ ----- ---------------- ---------- ------------ ----- ---------------- --------------------------- ------- ------ ---- --------- --- ------------- --- ------ ------- -------------------------------------- ------- ------------------------------------ ------- --------------------------------- ------- -------
在模板文件中,我们需要手动引入所有的 JavaScript 和 CSS 文件,这样浏览器端才能顺利地请求到需要的资源。
启动服务
在所有的配置文件和代码编写好之后,我们可以使用 npm run server
来启动服务端进行服务端渲染。如果一切正常的话,我们就可以看到通过服务端渲染的页面了。
这里是启动服务的命令:
"scripts": { "server": "node server/server.js" },
总结
通过 Webpack 的帮助,我们可以非常方便地将前端组件库和服务端的代码整合在一起,实现前端服务端渲染。这不仅可以提升网站的性能和用户体验,还可以大幅减少代码量,避免出现大量代码冗余。希望本篇文章对大家有所帮助,也希望大家能够在实践中更深入地理解 Webpack 和前端服务端渲染的相关知识。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6489202e48841e989476ca44