重庆网站建设c,合肥网络公司招聘,北京摇号网站维护,公司建设网站的服务费源宝导读#xff1a;为了向用户更好的传递ERP开放平台的价值与技术知识#xff0c;我们基于GitBook框架搭建了一个文档中心站点#xff0c;本文将介绍此站点的设计与实现过程。一、项目架构图因为文档会涉及到很多的产品线#xff0c;所以目前主要是通过拉取各个产品线的文… 源宝导读为了向用户更好的传递ERP开放平台的价值与技术知识我们基于GitBook框架搭建了一个文档中心站点本文将介绍此站点的设计与实现过程。一、项目架构图 因为文档会涉及到很多的产品线所以目前主要是通过拉取各个产品线的文档仓库进行合并编译生成方式构建处理整个的架构和执行流程如下1.1、收集阶段 首先产品需要按照约定好的目录格式建立文档仓库然后再新增markdown文件书写文档内容最后提交发布到远程。在服务器端会间隔一段时间周期性的获取远程仓库文档然后进行后续的编译与生成。1.2、 编译阶段 当用户将更新的文档推送到远程仓库后服务器拉取最新的仓库文档并且启动编译命令首先调用gitbook build命令来编译文档每次执行前都会安装最新的主题插件保证生成的文档都是最新的执行完毕后将在对应目录下生成编译后的html静态文件。完毕后再会执行npm run build-api来处理平台组件api以及后端接口事件的编译完毕后会生成可被重复使用的单个接口文件目的是便于后续查询更加快速。1.3、 生成阶段 上面数据编译完毕后会生成相对比较友好的数据格式此时就需要对这些生成的文件重新生成ElasticSearch的索引生成索引的目的是为了后续文档搜索调用ElasticSearch的webApi来对文章进行过滤获取搜索结果。索引完毕后可以安装elasticsearch-head插件完毕后可以通过浏览器打开页面在网页上查看生成的结果。1.4、 发布阶段 当文档和索引生成完毕之后最后会将文档生成的静态html文件拷贝到开放平台站点static/docs目录中同时重新启动站点至此完成站点文档的更新。二、技术栈Gitbook GitBook是一款文档编辑工具目前主要用来编写文档同时他还有一些很好的特性能够满足当前的需求如支持Git一个分布式的文档编辑工具。可多人共同编写文档。可以通过命令一键打包成静态站点部署到web服务器。由于采用的是md格式文件存储现在有许多比较成熟的可视化编辑器对于写作人员非常友好。可通过插件模式来自定义主题风格满足定制化诉求具体插件使用可参考http://gitbook.hushuang.me/plugins/create.html。Nuxt Nuxt是一个基于Vue.js的通用应用框架预设了利用Vue.js开发服务端渲染的应用所需要的各种配置。可以将html在服务端渲染合成完整的html文件再输出到浏览器。目前平台的主要使用的是vue开发应用所以上手比较容易内部易于沟通交流。JsDoc JSDoc是一个根据javascript文件中注释信息生成JavaScript应用程序或库、模块的API文档的工具。平台内部的组件库以及相关工具库接口都是按照JsDoc规范书写的集成方便可维护性高也是业内主流的方式之一。ElasticSearch Elasticsearch是一个开源的分布式、RESTful 风格的搜索和数据分析引擎他提供了许多的webApi接口对于前端开发使用很友好同时相关的文档也比较丰富学习起来不会很盲目同时部署也比较方便。 项目中还是用其他相关技术如nodejs、vue、grunt…在此不一一介绍了。三、生成文档 通过一系列的编译处理最终将用户书写的文档生成为内部可以持续使用的数据或者文件具体如下3.1、创建文档仓库 首先产品需要建立好自己的文档仓库然后按照Gitbook的书写规范(http://gitbook.hushuang.me/structure.html)编写自己的业务文档最后推送到仓库即可仓库目录结构如下SLXT // 产品目录名称src // 书写markdown文件的目录hello-world.md // 文档markdown文件book.json // gitbook配置文件通常不会调整package.json // 依赖包文件README.md // 帮助指引文件SUMMARY.md // 文档目录md文件
3.2、合并文档仓库 开放平台需要将所有的产品文档仓库拉取到本地并按照一定的策略进行合并处理最后在编译生成为静态文件进行同步更新目前主要合并两块内容3.2.1、合并文档目录 各个文档仓库按照约定好的目录结构在仓库根目录下书写正确的SUMMARY.md目录文件结构如下# Summary
* 成本系统* 标准扩展接口* [合同登记](/src/biao-zhun-kuo-zhan-jie-kou/he-tong-deng-ji.md)* [新增合同](/src/biao-zhun-kuo-zhan-jie-kou/he-tong-deng-ji/xin-zeng-he-tong.md)* [编辑合同](/src/biao-zhun-kuo-zhan-jie-kou/he-tong-deng-ji/bian-ji-he-tong.md)* [合同审批](/src/biao-zhun-kuo-zhan-jie-kou/he-tong-deng-ji/he-tong-shen-pi.md)* [合同审批中修改](/src/biao-zhun-kuo-zhan-jie-kou/he-tong-deng-ji/he-tong-shen-he-zhong-bian-ji.md)* [设计变更](/src/biao-zhun-kuo-zhan-jie-kou/she-ji-bian-geng.md)...由于开放平台的文档目录都是由平台管理的所以在平台的文档目录下面会约定好各个产品文档对应的目录位置如# Summary* 平台文档* 基础知识* [开发基础知识](/src/zi-yuan-yu-gui-fan/tong-yong-ji-shu.md)* DevOps概念及Git基本操作* [Git基本操作](https://open.mingyuanyun.com/docs/rdc/kuai-su-ru-men/git-ji-ben-cao-zuo.html)* 平台整体介绍* [开放平台技术白皮书](/src/ping-tai-zheng-ti-jie-shao/kai-fang-ping-tai-bai-pi-shu.md)....* [集成平台](mip)* [研发协同平台](rdc)* [流程中心](wd_lczx)* [工作流](gzl)
* 业务文档* [售楼系统](slxt)* [成本系统](cbxt)....上面类似[集成平台](mip)这样的标识会在编译的时候替换为产品文档目录SUMMARY.md中的内容并将产品目录内的/src路径替换成实际产品的简称如/src - /cbxt3.2.2、合并文档文件 合并完目录后我们还需要将产品的文档全部拷贝到临时的文档目录中暂且称为docs目录同时还需要将通用的gitbook的book.json以及刚刚合并的SUMMAYR.md拷贝进去合并后的临时docs目录如下 最后通过执行gitbook generate生成静态的html文档。 通过这种方式就可以有效的解决合并产品文档的问题也满足了平台管理整个开放平台文档目录的诉求。3.3、索引文档中的内容 现在有了大量的产品文档在实际使用的时候用户需要根据关键词去搜索文档基于这个场景引入了开源的ElasticSearch搜索引擎目前主要有两个步骤3.3.1、识别并索引静态文档中的特殊标记内容 借助于cheerio第三方库可以很容易的从已生成的文档html文档中拿到需要的标签内容如const cheerio require(cheerio)
...
// 读取静态html文件内容
const fileContent fs.readFileSync(options.filePath, utf8)
if (!fileContent) {return Promise.resolve()
}
let $ cheerio.load(div id_content_ fileContent /div)
// 匹配第一个h1的标签内容
const title
$(h1).first().text() ||
// 匹配blockquote标签内容
const description $(blockquote).text() ||
return {title,description
}提取到h1以及blockquote中的内容后可以给后续ElasticSearch生成索引使用。3.3.2、批量生成文档搜索索引 获取到文档提取的特征内容后调用ElasticSearch创建索引的接口完成对文档的索引代码片段如下ElasticSearchClientInstance.index({index: options[index],type: options[type],body: {title: 前端数值计算, // 文章标题system: 建模平台, // 所属系统url: , // 生成的url地址description: 日常开发中,我们经常遇到浮点数计算不准确问题,为此平台提供了mapnumber数值计算库,用来解决数值计算不准确的问题, // 文档描述尽量贴近关键词便于搜索content: ..., // 文章内容summary: ..., // 文章摘要},},function(error) {if (!error) {console.log(title 生成成功)}resolve()}
)当索引重新生成后后面用户在搜索文档的时候通过根据搜索关键词调用ElasticSearch提供的搜索API接口即可返回搜索后的结果数据集合相关代码如下function search ({ keyword, pageSize, pageIndex, index, system }) {let operator andif (keyword.match(/[\s ]/)) {operator or}// 查询条件let query {bool: {must: {multi_match: {...}},filter: {term: {system}}}}// 处理分页const from pageIndex * pageSize// 执行搜索const { hits } ElasticSearchClientInstance.search({size: pageSize,from,index,body: {query}})...
}最终用户使用的时候输入关键词即可完成搜索如图四、创建文档主题插件 GitBook插件是在NPM上发布的遵循定义的约定的节点包所以可以很好的满足我们多个产品文档同时应用同一个主题包的诉求下面简单说明如何创建以及发布Gitbook插件。 注意GitBook从3.0版本开始支持自定义主题。4.1、主题插件参考目录结构 开放平台GitBook主题插件的目录结构如下gitbook-plugin-theme-document_assets // 静态资源文件目录_layouts // 布局模板文件目录index.js // 主题入口配置文件package.json // 包描述文件README.md // 项目说明文件
4.2、定义插件package.json 标准的npm包描述文件注意如果是主题插件包名称需要以gitbook-plugin-theme作为前缀命名结构如下{name: gitbook-plugin-theme-doc,dependencies: {},description: 文档描述,license: ISC,main: index.js,readmeFilename: README.md,engines: {gitbook: 3.0.0},scripts: {test: echo \Error: no test specified\ exit 1},version: 1.0.0
}
4.3、主题插件运行时入口 主要是定义主题插件编译时的配置信息下面简单介绍常用的配置// index.js
module.exports {// 站点配置website: {assets: ./_assets/, // 插件静态资源目录地址js: [ // 站点引用的js文件相对assets目录xxxx.js],css: [xxxx.css // 站点引用的css文件相对assets目录]},// 后面还有关于插入自定义逻辑或增强插件的钩子以及块这里不做详细介绍具体可参阅http://gitbook.hushuang.me/plugins/create.html...
}
4.4、调整主题布局 有些场景下需要对生成的模板进行个性化调整如调整导航菜单的结构那么这个时候可以进入./_layouts/website/page.html模板进行相关的调整gitbook内置了很多的上下文变量来提供给模板使用如需要访问导航数据并对导航模板结构进行处理可参考如下处理...
ul classdoc-header-nav!--循环输出导航--{% for mainNav in book.navigation %}!--如果配置了链接输出A标签,否则输出SPAN标签--{% if mainNav.url %}a href{{mainNav.url}} target{{ mainNav.target}}{{ mainNav.text }}/a{% else %}span{{ mainNav.text }}/span{% endif %}!--如果是个菜单导航那么输出子级--{% if mainNav.children %}span classdoc_trangle/spanul classdoc-header-nav__sub{% for subNav in mainNav.children %}lia href{{subNav.url}} target{{ subNav.target}}{{ subNav.text }}/a/li{% endfor %}/ul{% endif %}/li{% endfor %}
/ul
...具体的模板变量可参考gitbook变量(http://gitbook.hushuang.me/ templating/variables.html)同理对于文档目录的个性化处理也可以参考这个方式去做。4.5、发布主题 通过以上步骤创建了自定义主题这个时候就可以发布主题了主题以theme-前缀插件方式发布。例如主题doc将从theme-doc插件加载然后从gitbook-plugin-theme-doc NPM包加载。4.6、使用自定义主题插件 发布主题后在创建gitbook的项目中通过更改book.json中的plugins来引入自定义的主题插件如下// book.jsontitle: 开放平台文档,plugins: [theme-doc // 增加theme-doc的插件依赖],pluginsConfig: {},....每次执行gitbook install命令后会自动安装主题插件并引用到当前文档项目中。五、自定义主页 门户站点使用Nuxtjs开发得益于Nuxtjs的机制可以很容易的实现产品定制化主页的开发诉求而且开发上手容易成本不高下面以MIP主页为例简单说明一下开发步骤5.1、新增主页页面 拉取开发平台仓库后在site目录下面新增产品主页目录及文件如图 这里新增了mip的文件夹同时在文件夹中新建了index.vue文件因为Nuxtjs的默认路由是根据目录结构定义好的所以刚刚新增的产品文件夹最终会生成/mip路由访问http://localhost: 3000/mip就能显示新增的主页。5.2、调整主页布局样式 Nuxtjs是基于vue的后端渲染引擎所以整个模板语法都是和Vue保持一致的并且也是支持单文件模式示例如下// ~ site/mip/index.vuetemplate!--在这里可以直接写页面的布局--div classpage-mipMIP主页/div
/template
script
// 此处写页面的逻辑
export default {name: PageMip,data () {return {...}},computed: {...},methods: {...}
}
/script
style
/*** 页面的样式
*/
.page-mip{...
}
/style注意因为Nuxtjs是默认根据pages里面的结构生成路由的所以pages里面都应该是页面维度的组件不能把页面拆分为多个细粒度的模块进行组合否则会生成不符合预期的路由遇到这种情况可以在sites下面创建components解决此问题。5.3、使用静态资源 页面中会使用大量的图片或者其它的媒体资源这个时候可以通过将资源文件放到sites/static/目录下通过绝对路径的方式访问如 在模板中可以通过以下方式使用templateimg src/images/conact_us/conact_us_1.svg
/template
style
.page-mip{background-image: url(/images/conact_us/conact_us_1.svg);
}
/style更多关于Nuxtjs的使用文档可参考Nuxtjs官方中文文档(https://zh.nuxtjs.org/guide/ #nuxt-js-%E6%98%AF%E4%BB%80%E4%B9%88-)。六、API生成机制 组件api文档采用的是现在流程的jsDoc生成它通过识别代码中约定好的注释生成可被后续重复使用的json数据最后通过编译生成html展现给用户阅读。6.1、约定注释规范 在写组件或者工具库的api时候都会带上符合jsDoc规范的注释下面列举一些常用的注释标记class标明函数是一个构造器函数意味着需要使用 new 关键字来返回一个实例
function作为对象的一个函数类型成员
event描述一个可触发的事件
param指定要描述参数的名称。还可以包含参数的数据类型
public标记是否是公开的
returns记录一个函数的返回值
实际使用示例如下/*** 格式化数字* public* function* param {Number} val 要格式化的数字* param {String} format 格式字符串,#,###.000保留三位小数,#,###没有小位数* example* utility.formatNumber(123123123.123, #,###.000) // 返回值123,123,123.123* utility.formatNumber(123123123.123, #,###.00) // 返回值123,123,123.12* return {String} 转换后的字符串*/function formatNumber () {...}想了解更多jsDoc的使用规范可以参考jsDoc中文文档(https://www.html.cn/doc/ jsdoc/tags-example.html)。6.2、编译生成API数据 借助jsDoc提供的编译库可以遍历项目中指定的文件进行解析最终会得到api.json的文件。文件的内容结构大致如下[{description: p设置模式/p, // 接口描述kind: function, // 接口类型可以为class、var、functionlongname: AddressSelect#setMode, // 接口完整名称name: setMode, // 接口名称memberof: AddressSelect, // 接口所属父类params: [{ // 接口参数type: {names: [Number]},description: p要设置的模式值/p,name: mode}],examples: [//设置编辑模式\rAddressSelect.setMode(2);\rAddressSelect.getMode(); //return 2;\r//设置查看模式\rAddressSelect.setMode(3);\rAddressSelect.getMode(); //return 3;] // 接口示例
},
...生成好数据后接下来可以对数据进行进一步处理。6.3、生成细粒度的API模块文件 jsDoc生成的api.json文件数据尺寸非常大在实际使用的时候需要根据当前api所属的类拆分为小的模块文件当请求某个组件的api接口列表的时候后台服务只需要根据请求的参数从api目录中获取到对应的文件同时将数据返回给前端生成的api数据文件如下 通过拆分大文件为小文件方式减轻实际请求中的解析性能问题加快前端用户使用的体验。6.4、API应用页面展示 根据上述步骤现在有了比较合理的api数据文件此时在前端界面中会显示api的菜单列如图 当用户点击接口时会将当前用户点击的接口信息发送给后端请求后端请求根据生成的api文件目录结构获取到对应的接口数据返回给前端前端再来渲染出来。 注意目前仅平台支持组件api文档产品暂不支持。七、如何跨应用组件公用 文档项目目前存在门户站点以及文档站点两个独立的应用其中文章反馈不仅在业务文档中使用了同时在api文档中也需要这个时候通过vue cli自动的组件lib打包方式可以将通用的组件发布为内部的npm包供两个应用使用在vue cli中的配置如下// vue.config.js
module.exports {// 修改 src 为 examples可以对组件进行测试pages: {index: {entry: examples/main.js,template: public/index.html,filename: index.html}},// 强制内联CSScss: {extract: false},...
}// package.json
{name: doc-platform-component,...scripts: {serve: vue-cli-service serve,build: vue-cli-service build,lint: vue-cli-service lint,lib: vue-cli-service build --target lib --name docComponent --dest lib packages/index.js // 指定打包方式为lib方式},...
}后面执行npm run build生成组件lib文件结果如图 编译完毕后在通过npm publish 发布内部组件包供其他应用使用。 关于编译配置具体的使用方式参见构建目标-库(https://cli.vuejs.org/zh/guide/build-targets.html#%E5%BC%82%E6%AD%A5-web-components-%E7%BB%84%E4%BB%B6)这种方式的好处是配置简单上手容易且为官方提供的方式不需要额外的依赖项对于简单的应用维护成本也低。八、收集用户反馈 文档的持续优化和更新需要用户的及时反馈在每篇文档中提供了用户提交反馈的表单同时这个组件也是跨应用的通用组件最终效果如图 用户点击提交后实际上是在jira系统中针对开发平台项目登记了一条反馈此时管理人员通过登录jira系统即可对这个反馈进行相关的处理在实现层面只需要如下方式即可接入jira系统提供的api// 生成请求的token
const token xxxxxbbbbbcccccddddd
// 调用jira开放的新增issue接口
const request({method: POST,url: https://jira.mingyuanyun.com/rest/api/2/issue,headers: {cache-control: no-cache,Authorization: Basic ${token},Content-Type: application/json},body: JSON.stringify({fields: {project: {id: xxxx},issuetype: {id: xxxx},components: [{id: xxxx}],customfield_10204: xxxx,summary: 反馈标题,description: 反馈内容}})
})注意使用jira的接口需要生成好token并且写入请求的headers里面。总结 使用Gitbook以及nuxtjs方式打包构建生成静态站点通过git来管理文档的提交以及用户权限目前来看主要的优势是开发成本比较低对于前端开发也比较友好很多的知识点也再可接受的范围内后续扩展功能相对比较容易比如后续增加的几个产品页面都是基于nuxt良好的机制很快的开发完毕的。 随着文档的数量越来越多每次全量打包编译导致整个构建环节时间逐渐增加也是后面需要优化的环节可以通过拉取git变更集分析出需要重新编译的文件进行增量更新提升这块的性能。 在文档搜索这块由于前期对ElasticSearch这块经验的不足有些文章并不能很好的被精准搜索到后续可以通过以下几个方式进行一定优化如加强对文章的书写规范要求文章的描述和子标题中应尽可能的多带有和当前文章贴近的语义关键词。针对文章不同的片段在过滤时增加不同级别的权重可以为主标题权重最高、子标题其次、再就是描述中的关键词最后是文章内容通过增加不同的权重设置可以对搜素结果进行按权重排序。针对中文可以安装中文的分词插件优化中文分词规则使搜索结果更友好。 未来在文档这块可以采取线上编写以及发布更新方式这样的好处是用户不需要在本地安装一些开发工具来编写以及预览文档了同时所有用户的体验也是一致性当然最主要的是文档的更新也是实时的不需要再定时去构建了相信随着后面的不断优化文档这块能越来越好。------ END ------作者简介杨同学 研发工程师目前负责ERP建模平台的设计与开发工作。也许您还想看从案例角度解析建模平台动态规则引擎WEB页面前端性能诊断方法与实践TypeScriptvue使用与迁移经验总结Web页面适配移动端方案研究前端异步对象的原理与使用方法