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

本贴最后更新于 2079 天前,其中的信息可能已经事过景迁

前言

本文将揭示 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

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

image.png

API 文档

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

props

在 props 里使用多行注释
image.png

slot

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

event

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

methods

在要公开显示的方法上方,使用多行注释,并添加 @public
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

module.exports = { // ... require: [ './styleguide/element.js' ] }

环境变量

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

yarn add dotenv --dev
// styleguide.config.js const webpack = require('webpack') const dotenv = require('dotenv') module.exports = { webpackConfig: { // ... plugins: [ new webpack.DefinePlugin({ 'process.env': JSON.stringify(dotenv.config().parsed) }) ] } }

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 # 打包输出目录 │   ├── upload-to-ali.esm.js │   ├── upload-to-ali.min.js │   └── upload-to-ali.umd.js ├── docs # 使用文档,这些md会转换成demo │   ├── basic.md │   ├── draggable.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 对纯函数测试的代码示例

// 源文件 export function stringify( query, equal = valueSeparator, delimiter = paramSeparator ) { return Object.keys(query) .map(k => `${k}${equal}${encodeURIComponent(query[k])}`) .join(delimiter) }
// 测试文件 import { stringify, } from '../src/utils/query' describe('测试 stringify', () => { test('基本功能', () => { expect(stringify(query.obj)).toBe(query.str()) }) test('自定义 equal & delimiter', () => { const equal = '=' const delimiter = '&' const str = query.str(equal, delimiter) expect(stringify(query.obj, equal, delimiter)).toBe(str) }) })

附上相关文章:✅ 使用 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
请不用担心这个警告,这是有意而为之的,因为不想把依赖把打包进 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 的机器人,避免人为重复劳动。

流程详解

.grenrc.js

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

module.exports = { dataSource: 'prs', prefix: '', ignoreLabels: ['duplicate', 'help wanted', 'invalid', 'question', 'wontfix'], ignoreIssuesWith: [ 'duplicate', 'help wanted', 'invalid', 'question', 'wontfix' ], onlyMilestones: false, changelogFilename: 'CHANGELOG.md', template: { issue: '- {{name}} [{{text}}]({{url}})', group: "\n### {{heading}}\n" }, // https://github.com/nuxt/nuxt.js/releases // https://gitmoji.carloscuesta.me groupBy: { '✨ New Features:': ['enhancement'], '🐛 Bug Fixes:': ['bug'], '📖 Documentation:': ['documentation'], '💅 Refactors:': ['refactor'], '♻️ Tests:': ['test'], '🚀 Performance:': ['performance'], '⚓ Dependency upgrades:': ['dependencies'], '🏡 Chore:': ['chore'] } }

badge.yml

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

types: feat: 'enhancement' fix: 'bug' docs: 'documentation' refactor: 'refactor' test: 'test' perf: 'performance' chore: deps: 'dependencies' default: 'chore'

自动发布

Travis CI

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

branches: only: - master language: node_js node_js: - lts/* git: depth: 3 install: - yarn --frozen-lockfile script: - ./build.sh after_success: - GREN_GITHUB_TOKEN=$GITHUB_TOKEN yarn release after_script: - ./notify.sh cache: yarn deploy: - provider: pages local-dir: docs github-token: $GITHUB_TOKEN skip-cleanup: true keep-history: true - provider: npm email: your@mail.com api_key: $NPM_TOKEN skip-cleanup: true

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

流程详解

其主要流程如下图所示:

脚本解析

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

还有常见的 badge
image.png

以及 contributors
image.png
相关 emoji 代表的意思,可以看官方文档

结语

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

  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    267 引用 • 666 回帖 • 1 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    409 引用 • 3585 回帖 • 1 关注
  • 组件
    10 引用 • 28 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...