有必要说说我为什么要开始写这个
我最近忙于公司的项目,一直没有抽出时间来写文章。本来想每个月写一片文章,保质保量,无奈上个月没有坚持。
这段时间有点忙,主要是由于公司业务调整,我从原来的广告项目中调整到新业务线的前台页面开发了,和以前一样,还是带着3、4个兄弟姐妹。不同的是以前的项目周期普遍偏长,可以让每个同学有时间从头到尾的把项目吃透,而现在做C端的前台页面往往开发时间非常的短,比如我们就要在1、2个月完成业务线所有前台页面的开发、联调、测试、部署,以及下一步的迭代。由于是从零开始,不存在基于一个“现成的”去做“另一个”。这就要所有的东西一起开发,但是这种联调成本就会不小。但是新的几个前台项目又不会一起确定需求,只会一个一个的需求评审、设计出图、交互、确认再交由前端。server端还好,可以在一开始确认需求后就开工,前端却要等UI、UE的定稿。由于人手不够,我已经不能像以前那样让每个同学负责一个项目了,一方面,每个项目安排一个同学的话我们人不够,另一方面每个项目不是一起定稿,晚出设计的项目对应的同学就会一直闲置。而最终专人负责也是在联调这个关键环节让尽量少的人同时开发,增加稳定性。
最终我们选择前期“协同开发”后期“专人负责”的方式,打个比方这就像是打篮球防守,“人盯人”不行就得“联防”。当一个项目确认,设计定稿,我们大家一起上,分别开发这个项目的不同模块。对于前端来说,前台项目切页面是一个比较大的工作量,比较适合大家一起开发,而后期联调又不太时候太多的人一起开发。我们打算这段时间每当有一个项目定稿后,我们大家一起把切页面和基本交互的工作开发到80%(除联调的都差不多了),就正好可以赶上继续下一个项目的定稿,我们再一起切页面。这样等这几个新项目的切页面完成后,server端同学也达到了差不多可以联调的程度了。我们再把同学分散到各自项目中去和server端同学联调。
这次我不打算写本地mock,原因是对于新业务线的新项目,server和产品需求的不确定性太强,每一天都会收到需求调整的群邮件,一旦我们今天约定了接口格式,我按照现有结构开发了,明天就有可能改,我第二天的工作是继续我未完成的功能还是根据新调整的接口从新改一遍。这种成本对于一个要赶在年前上线的项目来说,会造成严重的delay。最终我打算等接口相对稳定了再联调。当然二期迭代的时候服务端框架基本稳定,接口格式也稳定了,我们再选择mock假数据的方式,就比较有利于前后端开发的解耦。
以上是我简单介绍的业务场景,下面是我要做的事情。解决问题的核心点在于如何让前期的“协同开发”能够让所有同学一起上各自模块互不干扰,后期专人联调部署方便快捷。我们需要搭一套前端的工程,说的牛B一点就是写一套前端架构。但是刚刚我说过我们要这段时间做好几个项目,不能说每个项目都拷贝一套项目吧,而且一旦在开发的过程中发现我们有考虑不足需要改的地方,就要每个项目改一遍,但是这时第二个项目已经开发过半,也许项目结构也都被实际的开发人员修改。
我最终考虑的方案是“开发工具”+“业务代码”的方式。“工具”负责模块的自动合并打包部署等操作,“业务代码”负责项目中大家一起开发的模块、切页面、和最终的联调。不同的项目只是业务不同,项目结构都是一致的,一旦项目结构调整,我就更新工具即可。对于新产生的项目,工具也应该提供脚手架,以方便新需求定稿后马上开始开发。如果使用过vue-cli的同学应该知道那就是一个基于vue的脚手架,可以让一个开发者在简单了解vue的文档后,快速开始业务开发。可以更关注业务。但是我们是C端的前台页面,考虑到兼容性和服务端结构以及运维部署方式。我们要写一套适合自身业务特点的“开发工具”。
不过我们可以借鉴这种思路开发一套可以模块开发、合并、打包、部署的前端工具,发布在npm平台上。大家只要上平台上去install就可以了,更新也可以更方便。
介绍完为什么要有这套工具,下面就是开发这套工具。本文只会讲到npm的发布,具体的工具开发会放到后面的文章。我在整理了一下我自己在摸索中发现的一些问题,详细描述一下。
我们都知道,在npm平台上发布的npm包可以供大家在平台上下载安装,最方便的地方是可以在项目中通过命令更新,也就是说我在组内使用npm平台管理我的开发工具,就可以在我优化工具的时候,让其他同学update一下就好了,来实现技术框架和业务代码的解藕。
npm包说的简单一点就是就是一个满足npm规范的文件夹,里面要有一些必要的文件。只要满足了规范,就可以让别人使用你的npm包了。那么npm包里面都要有什么呢?下面我一步一步的介绍一下(作为配置介绍,我可能写的有点儿细,会显得啰嗦):
1、首先我要有一个npm账号
将来我们文件写好了改发布了,基本的文件都加进去了,我们要发布就要有个平台账号才行。首先在npm官网注册https://www.npmjs.com/ ,这个是我们的npm账号(建议小写),有两个地方会用到:1、登陆npm网站管理名下的npm包,比如添加删除(比如将来哪一个很牛逼的包需要在npm上发布,但是这名字一致被你占用着,经过讨论,你为了全人类让出来)2、在本机的npm配置中加入用户,发布的时候用。我相信如果你用过git,这一切都不是事儿。
2、起一个好名字?
举个例子,coodev 是我打算做的一个用来协作开发的工具。我打算在npm平台上发布,在github上维护。
我要建一个叫coodev的包(要现在npm平台搜一下,是否有人已经占用了这个名字了)。我一开始起名字的时候叫codev,发布了好几回log都显示失败了,说是我没有权限更新codev。我查了半天,担心是自己账号有问题。最终发现改个名就好了。所以建议大家先在平台上搜一下,是不是有名字冲突的,想我这么干就有点儿二了。
3、创建项目coodev
这一步不一定要按照我的方法来做,因为我打算在github上维护,在npm上发布,所以我是先在github上创建工程。其实创建npm的过程是差不多的,github的好处是会给我们创建好多默认的文件,比如licenses、生成package.json时的git 相关信息等。不过npm本身并不依赖git。
我git clone自己的coodev后就直接进入自己的仓库,此时应该只有.gitignore 、LECENSE、README.md文件,这些都嗨不是npm发布所必要的(不打算用git管理的同学,从这后面开始就行了)。我们要想让别人用我们的npm包,就要遵循npm的规范,这个规范就是package.json。用你的npm包就得先看说明书,package.json就是说明书。过去我对package.json的理解就是标明依赖和npm script脚本,对其他的字段还没怎么看过。下面开始package.json的创建
进去之后直接npm init创建一个package.json 因为这是一个npm包被外界识别的配置文件,我们先按照向导生成package.json文件,我们会发现如果先使用管理,好多的字段都读取到了git信息。
4、体现一下存在感(写个能跑通的小例子)
有几个比较重要的字段:name,version,main,bin。name是表示包发布的名字;version是每次发布的时候要修改版本好才能生效(供npm识别),因为每次都要修改,所以建议自动化处理;main是项目的入口(别人以npm或commonJS方式来使用),bin是生成的文件(往往打包成独立文件,供其他的方式直接引用独立文件);其他的我就先不介绍了。
我们要跑一遍体现一下存在感,一方面验证一下流程作为技术调查的一部分,另一方面是赶紧把名给占上。既然要发布,就得听个响儿。我们把“coodev”在命令行打印出来。
我们在这个文件夹下放一个index.js文件,里面随意的写一句console.log("coodev 运行的妥妥的")用来检测我们的包是否能执行。
当然只是加这一句是不能在mac上全局安装是使用的,我就遇到这个坑了,我一开始是用window写的,log也能打印出来,我用mac写的时候就出问题了:会自动给文件的代码中加上字符串,并没有把我的代码当作语句来识别,而是无法直接运行这个字符串,我后来看了一下webpack的写法才知道,我们要在文件第一行加一句
#!/usr/bin/env node
接下来就比较重要了,我们要将这个index.js(也可以在别的文件夹,叫别的名)设置为npm包的入口,要不然别人无法通过package.json知道哪一个是入口文件,我们需要分别为了举例子,我就把main和bin都指向刚刚的index.js文件(我偷懒了),package.json文件如下。
1 { 2 "name": "coodev", 3 "version": "0.0.9", 4 "description": "前端写作开发流程的脚手架", 5 "main": "index.js", 6 "bin": "index.js", 7 "scripts": { 8 "test": "echo \"Error: no test specified\" && exit 1" 9 }, 10 "repository": { 11 "type": "git", 12 "url": "git+https://github.com/grARM/coodev.git" 13 }, 14 "engines": { 15 "node": ">=0.6" 16 }, 17 "author": "grarm", 18 "licenses": [ 19 { 20 "type": "MIT", 21 "url": "http://www.opensource.org/licenses/mit-license.php" 22 } 23 ], 24 "bugs": { 25 "url": "https://github.com/grARM/coodev/issues" 26 }, 27 "homepage": "https://github.com/grARM/coodev#readme" 28 }
5、发布到平台(npm publish)
按理来说我们应该一早配好npm的账户设置,不过我打算把配置和发布放在一起看。首先请准备好刚刚注册的npm账号,确保账号是对的,能登录。
我们打开你平时用的终端控制台(能用npm命令的地方),我就用最常用git bash,输入命令npm adduser。
1 $ npm adduser 2 Username: your name 3 Password: your password 4 Email: yourmail[@gmail](/user/gmail).com
按照你注册的账号配置好,这时候看一下package.json中author尽量与npm账户一致。我们就算基本配好了(只要配一次就行了)。
我们每次写好npm包的代码后就可以准备发布了,注意更新package.json中的version,不然npm平台不能识别这是一个更新的包。输入如下命令:
$ npm publish
如果成功就会出现显示进度条,并最终显示如下log:
如果不成功也会有对用的错误提示,基本上是包名字冲突、账户有误,或配置不全等。
我们验证一下是否成功,我们可以登录npm平台自己账户名下,看是不是更新了版本号,如下图:
如果更新了,我们就试一下。激动人心的时刻到来了,我们找一个别的文件夹,全局安装我们的coodev或更新, $ npm install -g coodev (mac记得sudo),如下图:
安装成功后运行一下: $ coodev ,会显示下面的内容:
我还要加个参数,毕竟别的包在运行的时候都可以加参数,我也得能读得到啊。更新index.js如下:
1 #!/usr/bin/env node 2 3 /* 4 MIT License http://www.opensource.org/licenses/mit-license.php 5 Author @grarm 6 */ 7 var path = require(‘path‘); 8 9 console.log("coodev");//注意这回没写妥妥的 10 11 var arguments = process.argv.splice(2); 12 13 console.log("arguments:", arguments);
同样的更新version到 "version": "0.0.10" ,再 $ npm publish 我们再全局更新运行一下就能看到参数了,如下图:
那么我的例子就算是跑通了,也算万里长征的第一步。
总结:
以上是我在开发一个前端工具的第一部分:npm发布的介绍,我后续会继续分享我在开发前端工具的过程中遇到的问题和解决方案,整理成专题。还希望大家看了以后能指点指点,我也好少走点儿弯路。分享我近期听到的一段话:走出森林的两种办法,一种是拿着地图,按图走。方便直接,但是随着沧海桑田,过去的方案不一定适应今天的问题,一旦地图不符就有可能迷路;另一种方法是沿着河流走,坏处是河流蜿蜒我们会走一些弯路也许很慢,好处是基于这个真理,一定能走出去,还能在路上结识更多认同这一真理的同伴,相互鼓励。