开源 | UMajs框架vue-ssr同构最佳实践方案

原创
2021/11/09 09:02
阅读数 3.1K

01

简介

在6月底 ,UMajs发布了和React技术栈进行同构的插件方案(@umajs/plugin-react-ssr)。 使得开发者可以快速方便的使用UMajs快速构建web应用,而这次UMajs带来了和Vue结合使用的同构方案,支持SSR和CSR。使用方式也近乎100%保持和React插件一致 。对@umajs/plugin-react-ssr还不了 解的同学请查看末尾往期文章。 Umajs框架react-ssr同构最佳实践

02

插件介绍(@umajs/plugin-vue-ssr)

plugin-vue-ssr插件扩展了UMajs中提供的统一返回处理Result对象,新增了Result.vue页面组件渲染方法,可在controller自由调用,不限制服务端页面路由;使用类似传统模板引擎。也同时将方法挂载到了 koa 中间件中的ctx对象上;当一些公关的页面组件,比如 404、异常提示页面、登录或者需要在中间件中拦截跳转时可以在mid dleware中调用

特性

  • 不默认路由,不需区分前端路由和后端路由概念,且支持页面级组件 AB 测;灵活
  • 页面组件中没有__isBrowser__之类变量对ssr和csr模式进行特殊区分处理;统一。
  • 自定义HTML采用htmlWebpackPlugin,没有runtime,页面响应速度更高;高性能。
  • 支持html中支持模板插值,可实现特殊场景SEO;易上手。
  • 页面开发不依赖框架包装的任何模块,保持原生的vue开发体验;友好,易升级。
  • 数据获取提供服务端注入方式,页面视图渲染和数据加工分开处理;逻辑更清晰。
  • 支持SSR和CSR动态调整,支持SSR缓存,降级。高可用。
  • 支持其他koa开发框架使用。可扩展。
  • 支持 MPA,各页面组 件可单独构建,页面级更新。

插件使用

手动引入插件

1、插件安装
yarn add @umajs/plugin-vue-ssr --save
2、 打开 package.json 文件并添加 scripts 配置段:
start 启动你的 node 项目
  • build 运行npx ssr build构建用于生产环境的应用程序,项目支持多项目工程目录结构,可通过指定页面标识单独构建或者启动特定页面,命令为:npm run build xxx
  • analyzer 运行npx ssr analyzer 用于分析页面组件打包依赖分析 可通过 npm run analyzer xxx xxx 为页面组件标识,可指定分析某个页面组件打包结果
3、配置插件
4、创建Pages目录和页面组件
框架默认配置属性rootDir默认为根目录下web,pages 下是页面组件入口,比如index页面,vue 主入口文件为index/index.js,页面组件为index/App.vue。
└── web    └── pages        └── index            ├── App.vue            ├── index.js            ├── index.html (非必须)

cli工具初始化vue-ssr模板工程 【推荐】

在 cli 中支持快速创建umajs-vue-ssr模板工程。
安装和启动
cd umajs-vue-demoyarn installyarn start

路由使用

插件扩展了Umajs中提供的统一返回处理Result方法,新增了vue页面组件可在controller自由调用,方式类似传统模板引擎使用方法;也同时将方法挂载到了 koa 中间件中的ctx对象上;当一些公关的页面组件,比如 404、异常提示页面、登录或者需要在中间件中拦截跳转时可以在middleware中调用。

插件API

如果 options 参数传递为空 则默认会使用全局配置属性,全局配置采用插件集成时传递的 options 参数
注意 cache只在生产环境开启有效。
接下来介绍在Umajs同构方案中如何编写Vue的组件以及一些使用技巧。


03

页面组件

APP.vue主页面组件

indes.js主入口文件

Pages下按照文件夹名称定义 vue 页面组件,每一个页面组件必须包含inde.js主入口文件,文件必须导出组件App。如果使用vue-router,则将路由配置导出为Router对象;当使用vuex时,则将初始化配置导出为Store。
至此,我们就可以在Umajs服务端路由中通过插件提供的Result.vue api指定渲染到我新创建的App.vue。相信你还想继续了解下去…


04

数据获取

在Pages页面中,vue 页面组件获取数据有两种形式;我们分为服务端直出数据(Props 和 State)和 vue 组件静态方法asyncData获取两种形式。我们可以通过这两种方式对服务端渲染时首次页面渲染进行数据填充,使得服务端渲染时能返回完整的 DOM 结构,提高用户体验和更利于SEO。

服务端直出 Props[推荐]

框架在服务端提供了页面组件的渲染函数Result.vue,在调用函数渲染时我们可以在 initProps 参数中传递初始化的数据对象;这些数据可以在创建 vue 实例时会注册为组件实例的 Props 参数。在页面组件中我们可以将其定义为 Props。 了解 vue 组件 Props。
在服务端路由插件调用vue时:
Result.vue('index', {  title: 'xxx',  keywords: 'xxx',  description: 'xxxx',  say: 'hi!',})
在页面组件中我们可以直接通过 Props 将服务端直出的数据在 vue 模板中使用。
**特别说明:**在initProps参数中,title,keywords,description还会默认被解析为 web 网页头中的 标题,关键字,描述填充。

asyncData 静态方法

asyncData是页面组件数据获取的钩子,只能作用于页面。其接收对象参数默认是vuex的store和当前router,通过router可以获取到当前路由的参数等数据,然后调用异步请求获取 http 类型的数据,然后通过store触发状态管理的更新,也可直接改写操作store.state属性。框架会合并到store数据上下文state中。
asyncData灵感来自官方vue-ssr 示例和nuxtjs


05

HTML和SEO

框架内置HTMLWebpackPlugin插件,开发者在页面组件同级目录下可以覆盖默认 html 模板自定义引入第三方资源和脚本。自定义 html 文件名为页面下的index.html。

页面TDK

插件传值initProps中默认接收title,keywords,description作为页面标题,关键字,网页描述填充字段。
Result.vue('index', { title: 'xxx', keywords: 'xxx', description: 'xxxx' })

模板插值

在 html 模板中,还可以使用模板插值。服务端渲染初始化时传递的initProps数据在服务端渲染时会被注入为渲染上下文对象。



06

VUEX

当项目比较复杂时,我们可以在页面组件入口文件中导出 Vuex store 对象。框架会自动从根页面组件注入 vue 子组件中,通过$store 访问到实例化后的 store。

框架接收到 Store 对象后,会实例化 vuex。并且初始化到 vue 实例中,通过 vue.use 注入到全局。对于初始化的 state 数据,如果在 initProps 中也传入同名的属性,则 initProps.state 将会覆盖主入口文件传入 store.state 中的属性值。
Result.vue(ctx, 'vuex', { state: { count: 200 } })
在页面组件中获取初始state。
最后展示到页面上的count初始值为:200


07

嵌套路由(vue-router)

本身项目是没有引入vue-router的,各个页面组件之间是完全独立的两个项目。 当 vue 页面组件需要和 vue-router 结合开发单页面应用时,在入口文件中我们也可以通过 Router 属性导出路由配置。
在App.vue中导出路由配置
注意:服务端渲染模式下不支持使用 import 动态导入组件方式进行路由懒加载
  • 服务端路由
    对于服务端我们需要保持客户端和服务端路由一致,否则会出现子路由页面刷新404现象。
  • 页面路由获取数据
    在页面组件中页面数据获取方式和普通页面组件保持一致,我们可以使用服务端渲染 props 直出和 asyncData 钩子函数两种方式获取,具体使用参考数据获取章节。


08

内置css支持

框架内置了vue-style-loader以及 css 预处理器 loader,支持*.vue单个文件组件内的 <style>提取为单独 css 样式文件。也支持 CSS Modules。以下示例均开箱即用,无需额外配置。

  • Scoped CSS
  • 预处理器 less/scss
  • CSS Modules
    对于css modules除了支持vue官方style module方式之外,框架内置了基于less,scss预处理器的css module使用。
    如果你的样式是从 JavaScript 中导入的,那么你只需要将把文件命名为*.module.(less|scss|css)。


样例:

  • https://github.com/Umajs/umajs-vue-ssr
在线样例工程中包含了丰富的示例,包括vuex,vue-router,elementUI,Ant-design-vue,以及css-module的使用。

源码:

  • https://github.com/dazjean/srejs
  • https://github.com/Umajs/plugin-vue-ssr
  • https://github.com/Umajs/plugin-react-ssr


资源参考:

  • https://github.com/Umajs
  • https://cn.vuejs.org/v2/guide/components-props.html
  • https://ssr.vuejs.org/zh/guide/data.html#数据预取存储容器-data-store
  • https://zh.nuxtjs.org/docs/2.x/features/data-fetching#async-data
UMajs 是一个简单易用、扩展灵活,基于 TypeScript 的 Node.js Web 框架。从 2018 年立项至今,UMajs 团队持续的对框架打磨、迭代,在生产环境稳定运行近两年后,于 2020 年 8 月份开源。
  • 源码:https://github.com/Umajs
  • 官网:https://umajs.gitee.io/
欢迎大家start支持和参与贡献
往期文章推荐:

作者:

张佳佳,ABG资深前端开发工程师,目前专注于UMajs生态的建设和SSR。欢迎添加微信沟通交流:Da_ZJean(群二维码过期请添加微信拉进交流群)

本文分享自微信公众号 - 58技术(architects_58)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部