经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
一个巧合,我把文档写进了代码里
来源:cnblogs  作者:飞灰同学  时间:2021/3/1 9:14:03  对本文有异议

最近因为公司业务的调整,项目需要开发大量的业务组件、高复用逻辑提供给客户使用。当各类组件、代码多了以后,加上团队内几个成员书写习惯、开发思想的不同,出现了好多问题。尤其两个问题最严重:

  1. 大量的业务组件/业务逻辑需要通过查源代码的方式,或者问写组件的人,才能知道组件是否有自己需要的属性/钩子方法
  2. 有些组件因为产品需求 + 口头沟通 + 需求妥协,只能应用于某一个特定的情况下,其他人看设计图或者逻辑差不多相似就直接拿过来用,结果发现用不了/各种问题

为了解决这两个问题,就开始要求组员在开发业务组件的同时,必须写对应的开发文档/代码注释。一开始还好,中后期开发文档的更新明显跟不上组件的迭代,逐渐地又回到了靠嘴问的情况,第2个问题也是随着时间推移又回到了起点。

某天通过VS Code调试代码的时候忽然发现,用鼠标在原生语法和react的方法上悬浮几秒钟,就会出现一个提示框,里面有一些节点/组件/方法的简单介绍,参数等。

对,这就是我想要的效果!

原生语法 (如document.getElementById):
document.getElementById

react的方法(如useState):
useState

通过ctrl + 鼠标左键点开类型定义,发现提示框里的内容其实是相关代码上方的注释。
类型定义
按照类型定义里面的注释,我在代码里输入/**的时候出现了如下图的提示。
JSDOC提示

拿着关键词我去VS Code的官网搜索了一番,在官网搜到了答案(点击此处)。

VS Code understands many standard JSDoc annotations, and uses these annotations to provide rich IntelliSense.

VS Code 可以理解标准的JSDoc代码注释,并使用这些注释提供丰富的智能感知(如智能代码完成,悬停信息和签名信息)

JSDoc的语法也非常简单,只需要保证注释的开头是/**即可,其他与多行注释没有什么差别。(更多语法:点击此处

  1. /** 这样便创建了一个代码提醒 */
  2. function remind() {}

上手写个组件试试效果!

  1. import React, { useEffect, useState } from 'react'
  2. interface KeywordInterface {
  3. /**
  4. * 关键词
  5. */
  6. keyword?: string;
  7. /**
  8. * 高亮显示的颜色,支持hex、hsl、rgba、keywords
  9. */
  10. color?: string;
  11. children?: string;
  12. }
  13. /**
  14. * 关键词高亮组件
  15. *
  16. * @example <LightKeyword keyword="hello">Hello World</LightKeyword>
  17. *
  18. * @param { string } keyword - 关键词
  19. * @param { string } color - 高亮显示的颜色
  20. */
  21. const LightKeyword: React.FC<KeywordInterface> = ({
  22. color = '',
  23. keyword = '',
  24. children = ''
  25. }) => {
  26. const [ context, setContext ] = useState('')
  27. useEffect(() => {
  28. // 当关键词为空时,无需对内容做高亮显示
  29. if( !keyword ) {
  30. return setContext(children)
  31. }
  32. const pattern = new RegExp(keyword, 'gi')
  33. // 通过正则把关键词过滤出来并增加HTML节点
  34. const allword = (children as string).replace(pattern, (word) => `<i class="light-keyword-item" ${ color && `style="color: ${ color }"` }>${ word }</i>`)
  35. setContext(allword)
  36. }, [ keyword, color, children ])
  37. return (
  38. <span className="light-keyword" dangerouslySetInnerHTML={{ __html: context }}></span>
  39. )
  40. }
  41. export default LightKeyword

效果展示:

当鼠标悬浮在组件上时:
当鼠标悬浮在组件上时

当数据悬浮在组件属性上时:
当数据悬浮在组件属性上时

完美!这样只要按格式写好注释,就可以不用那么麻烦地去查文档了。(前提是得写)

那如果是业务逻辑呢?因此我写了一段基于业务封装的异步请求代码。

  1. import qs from 'qs'
  2. import { message } from 'antd'
  3. import axios, { AxiosRequestConfig } from 'axios'
  4. interface configInterface {
  5. /**
  6. * 请求地址
  7. */
  8. url: string;
  9. /**
  10. * 请求方式
  11. */
  12. method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
  13. /**
  14. * 请求参数
  15. */
  16. data?: any;
  17. /**
  18. * 其他配置参数
  19. *
  20. * @param { Object } headers 请求头配置
  21. * @param { boolean } errorMessage 是否启用错误提醒
  22. * @param { string } responseType 请求类型,默认为json
  23. * @param { boolean } withCredentials 是否携带跨域凭证
  24. */
  25. options?: {
  26. /**
  27. * 请求头配置
  28. */
  29. headers?: any;
  30. /**
  31. * 是否启用错误提醒
  32. */
  33. errorMessage?: boolean;
  34. /**
  35. * 请求类型,默认为json
  36. */
  37. responseType?: 'json' | 'arraybuffer' | 'blob' | 'document' | 'text' | 'stream';
  38. /**
  39. * 是否携带跨域凭证
  40. */
  41. withCredentials?: boolean
  42. }
  43. }
  44. // axios全局配置
  45. const $axios = axios.create({
  46. // 请求接口地址
  47. baseURL: 'https://demo.com',
  48. // 超时时间
  49. timeout: 60 * 1000
  50. })
  51. /**
  52. * 异步请求
  53. *
  54. * @description 基于现有业务封装,自动处理GET请求序列化/错误码处理反馈/跨域配置等操作
  55. * @example useRequest<T>({ url: 'api/weather', method: 'GET', data: { date: '2021-02-30' }, options: {} })
  56. * @typedef requestConfig 请求参数
  57. * @param { string } requestConfig.url 请求地址
  58. * @param { string } requestConfig.method 请求方式
  59. * @param { any } requestConfig.data 请求参数
  60. * @param { object } requestConfig.options 其他配置参数
  61. */
  62. const useRequest = async <T>(requestConfig: configInterface): Promise<T> => {
  63. const requestOptions = requestConfig.options || {}
  64. const axiosConfig: AxiosRequestConfig = {
  65. url: requestConfig.url,
  66. method: requestConfig.method || 'GET',
  67. headers: requestOptions.headers || {},
  68. responseType: requestOptions.responseType || 'json',
  69. withCredentials: requestOptions.withCredentials !== false
  70. }
  71. // 请求方式为GET时,对参数进行序列化处理
  72. if( axiosConfig.method === 'GET' ) {
  73. axiosConfig.params = requestConfig.data || {}
  74. axiosConfig.paramsSerializer = (params) => qs.stringify(params, { arrayFormat: 'brackets' })
  75. } else {
  76. axiosConfig.data = requestConfig.data || {}
  77. }
  78. try {
  79. const { data: response } = await $axios(axiosConfig)
  80. // 如后端返回错误码,将错误推入catch句柄执行
  81. if( response.code !== 0 ) {
  82. // 错误提醒
  83. if( requestOptions.errorMessage !== false ) {
  84. message.error(response.message || '未知错误')
  85. }
  86. return Promise.reject(response)
  87. }
  88. return Promise.resolve(response)
  89. } catch(e) {
  90. // 错误提醒
  91. if( requestOptions.errorMessage !== false ) {
  92. message.error('请求错误,请稍后重试')
  93. }
  94. return Promise.reject(e)
  95. }
  96. }
  97. export default useRequest

实际效果:
悬停提示
(基本用法及参数提醒)
额外配置提醒
(额外配置提醒)

配合Typescript,几乎就是把文档写进了代码里!!!

然而当我兴致勃勃地搭建vue 3的开发环境,想尝试一下vue的智能提示。经过多轮测试,JSDoc的智能提示只支持在js/ts/tsx这几类的文件,并不支持.vue格式的文件。
vue文件不支持jsdoc的智能提示
vue文件不支持jsdoc的智能提示)

如果希望在vue文件中也有类似的智能提示,可以通过VS Code安装vetur插件,然后在项目根目录下创建名为vetur的文件夹,并新建tags.jsonattributes.json两个文件,然后在package.json中引入两者的路径 。

  1. // package.json
  2. {
  3. "name": "demo",
  4. "version": "0.1.0",
  5. "vetur": {
  6. "tags": "./vetur/tags.json",
  7. "attributes": "./vetur/attributes.json"
  8. }
  9. }
  10. // vetur/tags.json
  11. {
  12. "light-keyword": {
  13. "attributes": ["keyword", "content", "color"],
  14. "description": "关键词高亮组件"
  15. }
  16. }
  17. // vetur/attributes.json
  18. {
  19. "color": {
  20. "type": "string",
  21. "description": "高亮显示的颜色,支持hex、hsl、rgba、keywords"
  22. },
  23. "content": {
  24. "type": "string",
  25. "description": "文本内容"
  26. },
  27. "keyword": {
  28. "type": "string",
  29. "description": "关键词"
  30. }
  31. }

最后的实现效果
组件智能提示
(组件智能提示)
组件描述
(组件描述)
属性描述
(属性描述)

好处是不受vue版本的限制,2和3都可以用;坏处是json文件的限制,没有办法像JSDoc一样显示丰富的格式和代码片段,希望vetur能够加强这方面的优化吧。

原文链接:http://www.cnblogs.com/fei-hui/p/14426794.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号