你还在想怎么提效吗?进来看看!

568

前言

在日常需求开发中,总是会需要一些重复性的手动操作,面对这种重复性劳动,你是会选择被动接受现状,还是选择主动改善现状?我相信,作为一个对效率有着严格追求的前端开发者,肯定是会选择后者!但是一个想法从发现到落地是需要一步步的去实践出来的。最近这段时间,刚好开发了一款自动化发布工具,可以和大家聊聊其中的过程和收获!

需求收集调研

现状

目前我们组内主要是做营销推广活动,这些活动皮肤经过开发、打包完成之后,按照开发规范,开发者需要将活动的打包源码,拷贝到公司的管理后台发布平台上,再经过选择一系列的业务配置,才能实现皮肤的发布。一旦有业务代码的更改,则需要重新打包再拷贝覆盖上一个版本的源码,并且需要确保没粘贴到别的皮肤上去。这种开发方式一方面增加手动复制源码创建皮肤的时间,同时也无法避免人工操作的失误带来的发布问题。

image.png

组内一个同学每隔两天就要开发上线一款皮肤,而从开发到上线,至少经过8-10次左右的代码更改发布操作,每次的复制粘贴操作平均耗时15s,如果把这个时间节省下来,一次皮肤的开发就能节约2分钟左右的时间,更重要的是能避免手动发布操作失误的问题。

目标

通过自动化发布工具,直接选择开发者需要的发布的皮肤,通过交互输入一些皮肤的配置信息,并能根据参数实现对应不同环境下的平台发布。而皮肤更新时,只需要重新打包再生成一份新的源码,工具就直接选择合并最新的源码更新到平台上,真正实现自动化发布。我们的工具主要是针对上面流程图的步骤2进行自动化优化。

开发

实现这个工具开发,需要解决几个问题:

  1. 因为平台发布的接口是需要用户的登录信息,需要携带放到请求头上做合法用户校验,如何在node环境去获取浏览器端用户登陆的cookie信息?
  2. 如何做到能适配并接入到组内其他工程中?
  3. 如何设计命令行式交互,为用户提供多元化的配置选择?
  4. 怎么实现命令式调用工具?

针对以上几个问题,来做一下分析认证。

node环境获取浏览器端的cookie

大概的思路就是通过http包创建一个http服务器,监听一个固定的端口,再通过open包打开目标管理后台的页面地址,当然前提是确保用户已经提前登陆成功,通过httpServer的请求头就可以拿到页面的登陆cookie信息了。然后在本地文件中缓存一份,下次就直接读取即可。

如何创建一个httpServer服务?代码如下所示:

const server = http.createServer((req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*') // 设置免跨域
  res.setHeader('Access-Control-Allow-Methods', '*')
  if (req.url) {
    process.env.SSP_COOKIE = (decodeURIComponent(parse(req.url.split('?')[1]).cookie)) // 将获取到的cookie赋值给全局的环境变量,方便其他地方调用
  }
  res.end('ok')
})
server.listen(port, () => { // 监听服务端口,回调打开目标页面
    open(url, { background: true })
})

其中的req.url.split('?')[1]).cookie就是目标页面发送的本地cookie,获取完成之后赋值给一个全局的环境变量,方便后续发请求的调用。

工具的适用性

目前这个工具开发主要是为了提效组内营销活动的皮肤开发,那如何应用到其他不同工程项目内呢?有一句话说的好,一切差异化的问题都可以通过自定义配置化的方式来解决。那应用到这个工具上来,就是需要增加一个适用于本工程的自定义发布配置文件,工具去读取这个配置信息才能做到横向适配。

本工具就默认需要用户增加一个工程根目录下的全局发布配置文件:deploy.config.js

module.exports = {
  entry: 'example/pages/**/index.vue',
  dist: 'dist',
  deployName: 'deploy.json',
  defType: 2,
  dataConfig: {}
}

上面的配置文件字段,比如entry就是工程下需要打包的活动皮肤源码对应的路径,根据这个入口来找到目标文件,dist就是活动皮肤打包后的源码文件夹名称,等等,根据你的需要可以增加各种配置字段即可,这样就可以做到针对不同工程目录结构和打包方式的使用适配性。

命令行式交互

皮肤代码的发布,肯定是需要一些特定的皮肤发布自定义配置,比如皮肤的唯一性标识,名称,配置开关的开启状态等等,这些是需要用户手动输入交互信息,而这个交互工具,一般是通过inquirer来实现:

const answer = await inquirer.prompt([
    {
      name: 'activityTemplateType',
      message: '选择皮肤子类型',
      type: 'list',
      choices: data.map(item => item.name)
    },
    {
      name: 'skinName',
      message: '输入皮肤名称',
      type: 'input'
    },
    {
      name: 'skinType',
      message: '输入皮肤唯一标识(不可更改)',
      type: 'input'
    }
])

最终的展示效果如下:

image.png

终端命令式调用工具

npm的package.json文件中有一个bin字段,主要是用于npm包在初始化安装的时候,将对应的脚本命令同步到工程的路径变量中,如下图所示:

{
    "bin": {
        "tuia-deploy": "bin/main"
    }
}

其中的tuia-deploy就是可以直接调用的命令名,bin/main对应的执行文件路径。

#! /usr/bin/env node 
// **使用node作为脚本的解释程序**

require('../lib/main')

通过commander包来创建一个交互命令:

import { createCommand } from 'commander'

const program = createCommand()
// 注册命令
program
    .option('--env <string>', '环境:test/pre/prod', 'test')

调用方式:

tuia-deploy --env test

上面的问题解决完之后,基本上功能就能完成了,在本地自测完成之后,就可以直接发包了,哇哦,完美~

image.png

推广和优化

工具做出来之后难道就结束了吗?

image.png

当然不是,做出来之后需要落地到实际的项目中应用,同时根据使用者在真正使用过程中暴露出的一些问题,进行使用体验上的优化和迭代,才能越做越好!

同时,好的工具必须要搭配一个完善的文档说明,才会吸引更多的用户群体。写好你的README很关键。大概的结构应该包含以下几个:

1、工具介绍
2、使用方式及注意事项说明
3、贡献源码的方式说明
4、感谢并希望使用者多提issue
5、开源协议

image.png

总结

虽然仅仅只是一个小工具,但是真正能从发现问题、工具开发,最好到落地,确实需要不间断的思考和总结,考验的是开发者的实践和协调能力。对于发现问题,我觉得可以从开发阶段的接口数据mock、到需求自动化测试、再到自动化发布以及代码的codeReview,甚至于低代码平台的搭建等等,不单单是为了追求自己的kpi指标,更多是希望自己的产出能为团队的效率提升带来帮助。所以你的发现的问题又是出现在哪一步呢?

从现在开始,多跳出现有的思维开发方式,多看多发现问题,并尝试去解决问题,提升开发效率,对个人的成长帮助还是很大的,与君共勉!