UDN-企业互联网技术人气社区

板块导航

浏览  : 1320
回复  : 4

[Nodejs] Web多文档页面 - 简单重复的事情变得更简单

[复制链接]
onvno的头像 楼主
发表于 2017-8-17 18:42:42 | 显示全部楼层 |阅读模式
本帖最后由 onvno 于 2017-8-17 18:54 编辑

项目中有相关页面是展示产品文档的,给到的文档资料的前情是:

  • 不同产品文档信息存储在各自仓库(各仓库使用了gitbook目录结构)
  • 生成页面形式为常规左导航,右内容
  • 生成页面需要局部刷新的交互效果
  • 文档资源需要存储在cdn上
  • 无后台介入,导航菜单数据需要从summary中提取

现有的md-to-html有gitbook类的静态页面方案,可以使用gitbook实现基本效果,但考虑到与页面设计不符,可扩展性又不够强,后续有增加数据请求的需求,未选择此方案。Pass掉gitbook后,基本就是自己实现一套页面生成方案,也是较为容易的。

  • 关心页面实现,MD编译,页面局部刷新更新两部分思路即可。
  • 考虑项目从文档更新到最终上线过程的优化,可了解下后边的脚本实现思路。

MD编译
根据给到的文档,基本思路如下:

  • 左导航:将原SUMMARY.md文档转为json数据
  • 右内容:部署CDN前统一将md内容编译为html标签形式

MD File.png
执行编译工作,SUMMARY.md转json文件伪代码:

var jsonObj = []

// readFile单行数据
var datas = fs.readFileLine('xxx.md','utf-8')

for (var line in datas) {
  // 单行数据处理
  var regData = line.trim().replace(/^#+\s+(.*)/,'$1')

  // 写入json对象
  jsonObj.push(regData);
}

// 输出文件
var objStr = JSON.stringify(jsonObj,null, 4);
fs.writeFileSync('out/path',objStr,'utf-8')

md转html可选用marked库处理,基本思路如下:

// 引入依赖`marked`
const marked = require('marked');

// 读取`md`文件
const source = fs.readFileSync('product.md','utf-8');

// 编译
const marks = marked(source)

// 输出
fs.writeFileSync(outPath,marks,'utf-8');
页面局部刷新更新
本例使用了react,可使用react-router,设置导航目录NavLink,渲染用于显示内容的组件Article(其他框架也都有成熟的hash方案)。

<HashRouter>
    // 导航路由部分
    <ul>
        <li><NavLink to={linkURL1}>{tit1}</NavLink></li>
        <li><NavLink to={linkURL2}>{tit2}</NavLink></li>
        ...
    </ul>   
    // 内容展示部分   
    <Route path="/:id*" component={Article} />
</HashRouter>

页面渲染流程
  • ComponentDidMount页面渲染完毕,请求编译好的Summary.json,展现文档导航区域内容
  • 文档导航内容点击后,根据url的hash值更改,发起请求获取编译后的内容页product.md后,写入内容区域

Page Render.png

CDN发布
本地资源请求测试无误后,CDN部署静态资源,切换开发资源路径,小手一点发布,似乎没事了。真的没事了?
盘点
盘点下上线过程中,发现还有不少需要人为重复操作的环节:

  • 文档更新:逐一更新各仓库,缺乏集中管理
  • Web文档新页面:手动创建
  • 提交仓库:手动提交仓库静态资源发布CDN,没有增量更新匹配工作

产品上线后,维护的工作自然是少不了,能从代码上将后续这部分工作简化,岂不更好?行动,将手动过程通通更改为脚本批量执行。

文档统一管理更新
多产品的文档是在多个仓库管理中存储,项目上线后每次部署更新手动文档仓库,遂根据需求,利用git的子模块概念:主仓库下,通过添加子模块(如本例中的产品git仓库),批量更新子模块.
知识储备:git, shell脚本
Main repo.png
一键克隆
送佛送到西,我们将clone仓库这一步也完整考虑一下,得到如下clone.sh脚本,配置npm命令,实现一键clone产品a,b,c...注意此处使用了submodule - git的子模块概念,从而实现主(当前开发仓库)从(子产品的独立git仓库)仓库的一对多管理关系,便于统一维护更新。

#!/bin/sh

cdir=`pwd`

prodName=(
    "product_a"
    "product_b"
    "product_c"
)

for name in ${prodName[@]}
do
  git submodule add git@github.com:iuap3/${name}.git ./md/${name}
done

一键更新
以下命令写入适当脚本,指定简化命令即可一键更新:
git submodule foreach git pull origin master升级版CDN发布
发布CDN,使用的阿里oss,cdn发布只能实现文件逐一上传。文档的体量有1000+,遂思考:上传前,是否可以筛选只提交本次更新过的文件?整理需求如下:

  • 命令式一键发布CDN
  • 只提交更新处理过的文档

CDN UPDATE.png
自动发布CDN选择了jenkins部署,定时更新任务。
两次CDN如何区分提交的不同修改?答案是只要获取到上次CDN提交时的git版本,及本次提交的版本,利用git diff获取两次${gitLastRev},${gitRev}提交状态为:

  • M:修改
  • A:增加
  • R:重命名
  • C:拷贝

四种状态的文件(D - 删除的文件可忽略不计)。
git diff --name-status ${gitLastRev} ${gitRev}
利用OSS提供的NODE SDK,依次将需要提交的文件发送到CDN服务器上,整合到脚本中,实现一键发布CDN.

一键创建文档页面
文档上线html页面时,开发中的数据和组件做了彻底的分离解耦,模板只需传入产品名称,批量创建后执行正常编辑即可生成所需页面:

  • 创建模板html,js页面
  • 利用模板引擎handlebars,写入data,使用node创建不同产品data的待编译文件至此,文档从clone,到update更新,进行Markdown文档编译,批量模板生成web页面, 正常产出页面,发布CDN,均能正常通过一键命令执行。

PreCompile Page Build.png


# 初次更新仓库 - 克隆子模块
npm run clone

# 批量更新子模块
npm run update

# MD文档编译
npm run md

# 模板生成预编译Web文档页面
npm run doc

# 提交仓库更新后,发布cdn
npm run cdn

# build产出页面
npm run build

项目的一个需求,实现的几处优化:
[td]
优化前
优化后
实际效果
数据和内容耦合度高解耦数据CDN发布即实现页面内容更新,避免文档更新需要多次部署
静态资源批量上传比较cdn资源,只上传更新后文件上传时间由20min左右,缩减为按秒计算
各功能模块单独手动该处理实现一键命令更新减少手动更新维护,增加易用性
手动发布CDN使用自动构建工具定时发布减少手动更新维护

项目中实现的小功能:
  • cdnfilter - cdn上传准确筛选,调用SDK完成一键上传
  • md2json.js - 特定markdown转为json文件(md文档要求的特殊性,单独发布)
  • pathJoin.js - 实现前端字符串url及文件路径拼接,自动处理连接符,在线demo

    • 1.处理文件结尾路径的冗余连接符'/'
    • 2.处理合并中间冗余的连接符'/'
    • 3.处理合并中缺失的连接符'/'






发表于 2017-8-24 14:36:10 | 显示全部楼层
鄙视楼下的顶帖没我快,哈哈
使用道具 举报

回复

发表于 2017-8-24 14:36:12 来自手机 | 显示全部楼层
JavaScript依赖于浏览器本身,与操作环境无关,只要计算机能运行浏览器,并支持JavaScript的浏览器,就可正确执行,从而实现了“编写一次,走遍天下”的梦想。
使用道具 举报

回复

发表于 2017-8-29 10:41:53 | 显示全部楼层
楼主分享得很棒棒 ,学习到了
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部