前言
随着前端技术的不断发展,前端渲染的方式也越来越多样化。其中,服务端渲染(Server-Side Rendering,简称 SSR)因其能够提高页面的首屏渲染速度、SEO 友好等优点,受到越来越多的关注。
在 SSR 中,前端代码通过 node.js 等环境在服务器端执行,生成 HTML 字符串返回给客户端。而 @schibstedspain/ssr
这个 npm 包,就是一个能够帮助我们快速实现 SSR 的工具库。本篇文章就是要为大家介绍该工具库的基本使用方法。
安装
首先,我们需要在项目中引入 @schibstedspain/ssr
包。可以通过 npm 或者 yarn 安装:
npm install @schibstedspain/ssr --save
或
yarn add @schibstedspain/ssr
基本用法
创建服务器
为了能够实现 SSR,我们需要在服务器端执行 JavaScript 代码。因此,我们需要创建一个服务器,来承载我们的 SSR 应用。
在 @schibstedspain/ssr
包中提供了一个 createServer
函数,可以方便地创建服务器。例如:
-- -------------------- ---- ------- ----- - ------------ - - ------------------------------ ----- ------ - -------------- ------- - - ----- ---- ---------- -------- -- - ----- -------------- ---------- ---------- - - -- ------------------- -- -- - ------------------- ------- -- ---- ------ --
其中,createServer
函数接收一个配置对象参数。其中,routes
是必需参数,用来指定各个路由对应的页面组件。
创建页面组件
在 SSR 中,页面组件应该被设计成「无状态纯函数」的形式,接收一个 props
对象作为参数,返回一个虚拟节点对象(例如使用 React 的开发者,可以返回 JSX 元素)。
例如,下面就是一个简单的无状态组件:
-- -------------------- ---- ------- -------- --------------- - ----- - ------ ------- - - ----- ------ - ------ ------ ---------------------- ------- ------ ---- -------------------------- ------- ------- -- -- ------- ------- - -
在服务器中渲染组件
有了服务器和页面组件之后,我们就可以开始进行 SSR 了。
在 createServer
的回调函数中,我们可以通过 render
函数,将组件转换成 HTML 字符串,并发送给客户端。例如:
server.use(async (req, res) => { const { component, params } = server.getMatchedRoute(req) const data = await fetchData(params.id) const html = render(component, { ...data, ...params }) res.writeHead(200, { 'Content-Type': 'text/html' }) res.end(html) })
其中,server.getMatchedRoute
函数用来获取当前请求路径所匹配的路由信息。fetchData
函数则是用来获取组件所需数据的操作。
最后,通过 res.writeHead
和 res.end
函数,将生成的 HTML 字符串发送给客户端。
高级用法
使用插件
@schibstedspain/ssr
提供了插件的机制,可以帮助我们实现更加灵活的 SSR。例如,我们可以使用 @schibstedspain/ssr-plugin-react
这个插件来支持在 React 组件中使用的一些特殊语法(比如props.children
),从而方便我们进行 React 的 SSR。
安装插件:
npm install @schibstedspain/ssr-plugin-react --save
或
yarn add @schibstedspain/ssr-plugin-react
在 createServer
中引入插件:
const { createServer } = require('@schibstedspain/ssr') const reactPlugin = require('@schibstedspain/ssr-plugin-react') const server = createServer({ // ... plugins: [reactPlugin] })
使用 Webpack
在使用 SSR 的时候,我们有时候需要使用像 vue、react 这样的框架,同时还向这些框架中引入 css、image 之类的静态资源。这时候,我们可以使用 Webpack 来帮助我们打包这些资源。
首先,在项目中安装 webpack 相关的包:
npm install webpack webpack-dev-server webpack-cli html-webpack-plugin --save-dev
或
yarn add webpack webpack-dev-server webpack-cli html-webpack-plugin --dev
然后,创建一个 webpack.config.js
文件,配置 webpack。例如:
-- -------------------- ---- ------- ----- ---- - --------------- ----- ----------------- - ------------------------------ -------------- - - ----- ------------- ------ ------------------------ ------- - --------- ------------ ----- ----------------------- -------- ----------- -------- -- ------- - ------ - - ----- -------- -------- --------------- ---- -------------- - - -- -------- ---- -------------------- -
其中,entry
是入口文件,也就是我们编写的客户端代码(比如通过 React 编写的页面)的入口;output
是输出目录和文件名;publicPath
用于指定生成的静态资源文件在项目中的路径;module.rules
用于指定 webpack 在打包过程中的处理规则(例如使用 babel-loader 工具将 ES6 代码转换成 ES5 代码);plugins
用于指定一些 webpack 插件(例如使用 HtmlWebpackPlugin 生成 HTML 文件)。
最后,我们就可以在服务器中使用 Webpack 了。例如:
-- -------------------- ---- ------- ----- ------- - ------------------ ----- -------------------- - --------------------------------- ----- ------ - --------------------------- -- --- -- --------------------- --- -------------- - ----- -------- - --------------- ----------------------------------------- - ----------- --- --- - -- ---
示例代码
下面是一个完整的示例,演示了如何使用 @schibstedspain/ssr
实现一个使用 React 编写的 SSR 应用:
服务端主文件 server.js
-- -------------------- ---- ------- ----- - ------------- ------ - - ------------------------------ ----- ----------- - ------------------------------------------- ----- -------- - ------------------------------- ----- ------ - -------------- ------- -- ----- ---- ---------- -------- --- -------- ------------- -- ---------------- ----- ---- -- - ----- - --------- - - --------------------------- ----- ---- - ----------------- --- ------------------ - --------------- ----------- -- ------------- -- ------------------- -- -- - ------------------- ------- -- ---- ------ --
客户端主文件 src/client/index.js
import React from 'react' import ReactDOM from 'react-dom' import HomePage from '../pages/HomePage' ReactDOM.hydrate(<HomePage />, document.getElementById('root'))
页面组件 src/pages/HomePage.js
-- -------------------- ---- ------- ------ ----- ---- ------- -------- ---------- - ------ - ------ ------ --------- ---- ---- - ----------- ------- ------ --------- ---- --------- ------- ------- - - ------ ------- --------
Webpack 配置文件 webpack.config.js
-- -------------------- ---- ------- ----- ---- - --------------- ----- ----------------- - ------------------------------ -------------- - - ----- ------------- ------ ------------------------ ------- - --------- ------------ ----- ----------------------- -------- ----------- -------- -- ------- - ------ - - ----- -------- -------- --------------- ---- -------------- - - -- -------- ---- -------------------- -
注意,这个示例中,我们只提供了一个路由和一个简单的页面组件,仅供参考。实际中,我们通常会在路由中定义多个页面,利用 API 来获取数据等等。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/60055c2181e8991b448d9be7