🔨揭秘vue-sfc-cli: 组件研发利器

前言

本文将揭示vue单文件组件的工具 vue-sfc-cli 的内涵,说明它是如何在整个组件研发流程中提升效率的。

本文可以看成是 📦vue组件发布npm最佳实践 的成长篇,是 🤖打造自动化的Github Workflow 的姐妹篇,是团队最佳实践的落地产物,涉及的背景知识有点多,需要花点时间消化🤔

使用教程

快速开始

npx vue-sfc-cli

# 接下来会有一串的提示,请务必填写
# 推荐kebab-case风格,小写字母,多个单词用-(dash)分隔,如my-component

# 填充完提示后
cd my-component

# 使用git初始化,这样可以使用commit hook
git init

# 安装依赖
yarn

# 开始开发
yarn dev

# 打包
yarn build

# 可以发布了!
yarn publish

参数选项

-u, --upgrade
根据 template目录下模板,生成新的文件,更新到当前组件中。使用的是覆盖策略,默认覆盖的文件定义在 update-files.js。常用于使用最新版本vue-sfc-cli对旧组件的配置进行升级

# cd my-component
npx vue-sfc-cli -u

--files
如果想更新额外的文件,可以传此选项,后接文件名,多个文件使用 , 分隔

npx vue-sfc-cli -u --files package.json,.babelrc.js

--test
生成一个测试的组件模板,常用于ci环境测试。

npx vue-sfc-cli --test

示例文档

在docs目录下,新建 md 文件,建议命名同样是kebab-case

以上传组件upload-to-ali的 docs/draggable.md 文档为例

image.png
image.png

yarn dev 时会转这个markdown文件就会换成demo,可以看到实际代码,还可以实时修改代码,让demo刷新

image.png
image.png

API文档

在vue文件里,编写注释,即可生成API文档。

props

在props里使用多行注释


image.png
image.png

slot

在slot上一行,使用 @slot 开头的注释


image.png
image.png

event

在emit事件上方,使用多行注释


image.png
image.png

methods

在要公开显示的方法上方,使用多行注释,并添加 @public


image.png
image.png

效果预览


image.png
image.png

image.png
image.png

引入第三方库

Element-UI为例

yarn add element-ui

新增一个文件:styleguide/element.js

import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(Element)

修改配置文件:styleguide.config.js

image.png
image.png

环境变量

如果需要使用环境变量,推荐使用 dotenv

yarn add dotenv --dev
image.png
image.png

prettier and husky

组件模板内置prettier, 可以在提交代码时格式化。

注意的是需要先执行 git init 命令,之后再执行 yarn 安装依赖,否则提交钩子不生效。

注意

不建议在Windows下生成组件,因为.sh可能没有执行权限。

技术详解

技术概览

  • vue-styleguidist 本地开发demo与生成文档
  • jest 单元测试
  • prettier + husky 代码格式化
  • rollup 打包
  • standard-version 自动生成changelog
  • github-release-notes 生成github release
  • auto-badge 为pr自动添加label
  • netlify 预览pr
  • travis ci 发布npm/github pages
  • shell + dingtalk api 发布成功后发送钉钉消息
  • all-contributors 显示贡献者
  • 内置README.md模板,包括目录结构、返回顶部以及一些常见的badge

模板目录

以下是生成的组件默认模板配置

├── .all-contributorsrc  # all-contributors配置
├── .babelrc 
├── .editorconfig
├── .github
│   └── badge.yml        # github app auto-badge配置,用于给pr自动打标签
├── .gitignore
├── .grenrc.js           # github-release-notes配置
├── .prettierignore      # prettier配置
├── .prettierrc          # prettier配置
├── .travis.yml          # travis ci配置
├── LICENSE              # MIT
├── README.md            # 自述文件
├── build                # rollup配置
│   └── rollup.config.js
├── build.sh             # ci相关文件
├── dist                 # 打包输出目录
├── docs                 # 使用文档,这些md会转换成demo
│   ├── basic.md 
├── notify.sh            # ci相关文件,用于钉钉通知
├── package.json
├── src                   # 源文件目录
│   ├── index.js
│   └── upload-to-ali.vue # 单文件组件
├── styleguide.config.js  # vue-styleguidist配置文件
└── yarn.lock 

开发

选用vue-styleguidist的原因是,好处是:书写md,既可以充当文档,又可以转换成可运行的demo。

这样的好处是,文档与demo一体化,不用同时维护两份代码。

修改md、修改源文件,demo是会hot reload的,非常方便。

测试

对于组件的测试,大家首先想到的是相关的工具集vue-test-utils,然后觉得,组件测试有点难写,或者说,不知道怎么写。

其实可以换个思路,先从简单的做起。做单元测试,更重要的是培养写测试的习惯,所以一开始建议只用jest对纯函数进行测试。

也即,把组件里的方法抽取出来,单独放到一个文件里,然后专门对这些函数进行测试。

这样的好处是,为了方便测试:

  • 开发者在写组件时,需要尽可能地写短小精悍的函数
  • 函数要写成纯函数,也即不依赖或影响到全局变量

这样的方法,也很适合对一个完全没有测试的组件,逐步补充测试用例。

下面是el-data-table对纯函数测试的代码示例

image.png
image.png
image.png
image.png

附上相关文章:✅使用jest进行测试驱动开发

构建

yarn build 即可构建生成三个文件:

  • upload-to-ali.esm.js
  • upload-to-ali.min.js
  • upload-to-ali.umd.js

使用者import组件时,默认import进来的是 upload-to-ali.umd.js。 关于三个文件的相关描述,📦vue组件发布npm最佳实践已阐述过,就不重复了。

rollup的一个特点是,默认不会把组件的依赖一起打包进去,这个特性有利于减少组件的分发体积。

下面是个示例:

// src/index.js
const crypto = require('crypto')
const axios = require('axios')

执行 yarn build , 会得到以下信息

image.png
image.png

请不用担心这个警告,这是有意而为之的,因为不想把依赖把打包进dist进去了。

commit规范

在继续下面的内容之前,再复习一下Conventional Commits

摘取重点如下,格式为:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

其中<type>: <subject> 是必须的。

type的类型有:

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
  • refactor: A code change that neither fixes a bug nor adds a feature
  • perf: A code change that improves performance
  • test: Adding missing or correcting existing tests
  • chore: Changes to the build process or auxiliary tools and libraries such as documentation generation

另外约定,更新依赖使用 chore(deps),这也是github官方的做法

PR自动打标签

由于github-release-notes生成的release notes只对打上了label的Pull Request才有效,因此给github仓库添加一个自动添加label的机器人,避免重复劳动。

流程详解

[图片上传失败...(image-f9ba8e-1562495642226)]

.grenrc.js

.grenrc.js是github release notes 的配置, 这是参考了nuxt、github以及其他流行仓库后得到的配置,可以拿来即用


image.png
image.png

badge.yml

.github/badge.yml是 auto-badge 的配置文件,需要放到隐藏文件夹 .github 下。以下配置与上面的 .grenrc.js 相对应,同样可以拿来即用

image.png
image.png

自动发布

Travis CI

主要利用Travis CI做到自动化,先看下面的 .travis.yml 配置:

image.png
image.png

上面参数的具体说明,可以参考教程:🚀Github集成TravisCI:自动发布

流程详解

其主要流程如下图所示:

[图片上传失败...(image-e116f-1562495642226)]

build.sh

build.sh内容如下:

#!/bin/sh
yarn stdver

yarn build

git remote add github https://$GITHUB_TOKEN@github.com/FEMessage/upload-to-ali.git > /dev/null 2>&1
git push github HEAD:master --follow-tags

与之相对应的,package.json里scipts需要有以下字段:

"stdver": "standard-version -m '[skip ci] chore(release): v%s'",
"release": "gren release --override"

notify.sh内容如下:

#!/bin/sh
if [ "$TRAVIS_TEST_RESULT" != "0" ]
then
echo "build not success, bye"
exit 1
fi

url=https://api.github.com/repos/FEMessage/upload-to-ali/releases/latest
resp_tmp_file=resp.tmp

curl -H "Authorization: token $GITHUB_TOKEN" $url > $resp_tmp_file

html_url=`cat $resp_tmp_file | sed -n 5p | sed 's/\"html_url\"://g' | awk -F '"' '{print $2}'`
body=`cat $resp_tmp_file | grep body | sed 's/\"body\"://g;s/\"//g'`

msg='{"msgtype": "markdown", "markdown": {"title": "upload-to-ali更新", "text": "@所有人\n# [upload-to-ali]('$html_url')\n'$body'"}}'

curl -X POST https://oapi.dingtalk.com/robot/send\?access_token\=$DINGTALK_ROBOT_TOKEN -H 'Content-Type: application/json' -d "$msg"

rm $resp_tmp_file

这里有两个关键点:

  • 构建失败,不发送消息
  • 调用github api获取最新release时,带上github token

README.md

参考了优秀开源项目后,我们搜索出了一套README.md模板,内置在初始化工程里了


image.png
image.png

还有常见的badge


image.png
image.png

以及contributors

image.png
image.png

相关emoji代表的意思,可以看官方文档

结语

最后,欢迎大家使用https://github.com/FEMessage/vue-sfc-cli开发vue组件~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,252评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,886评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,814评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,869评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,888评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,475评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,010评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,924评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,469评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,552评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,680评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,362评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,037评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,519评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,621评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,099评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,691评论 2 361

推荐阅读更多精彩内容

  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    王喂马_阅读 6,455评论 1 77
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    小姜先森o0O阅读 9,515评论 0 72
  • 简说Vue (组件库) https://github.com/ElemeFE/element" 饿了么出品的VUE...
    Estrus丶阅读 1,687评论 0 1
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    柴东啊阅读 15,862评论 2 140
  • “可以帮我拿个东西吗?” “什么” “手”
    青绾阅读 165评论 1 1