【浅尝辄止第一季】搞个开源库玩儿

750 阅读7分钟

Bk77gK_67Q.jpg

浅尝辄止系列,大前端世界那么大,我想去看看

一、前言

港真,这真不是一个真正的开源库,只是我的一次学习笔记,库里面放了两个函数,主要用于安全的从object对象中获取指定路径下的值,防止从undefined取值抛异常(页面白屏,服务异常,哇咔咔)。仓库地址 zzuwzj/get-set-obj (我的github荒草丛生,欢迎去践踏)。
本文将带你从头到尾搞一个开源库,小白教程,主要包括以下内容:

  • 建立代码仓库
  • 配置eslint代码检查
  • Rollup&Webpack构建
  • 自动生成文档
  • 自动化测试&测试覆盖率
  • Git提交钩子
  • 配置CI持续集成流程
  • 添加开源许可证
  • 美化你的库
  • 项目主页github pages
  • 发布到npm&同步到zodiac

如果你对开源感兴趣,想开发个自己的库,花两个小时走遍流程还是挺有趣的呢~

二、来不及了,快上车

其实还是很简单的,也就7、8步,和把大象装冰箱难度差不多~
但是麻雀虽小,五脏俱全哦~

0x0 占位符

这里啥也没有,就是从0开始

0x1 建立代码仓库

既然是开源的项目,那必须找一个地方托管代码,我选择了大名鼎鼎的github。
1. 到Github新建一个仓库,没有账号的可以先申请一下,建库过程和gitlab一样,填个名字和描述就行
2. 将新建的仓库clone到本地
3. 进入刚clone下来的仓库目录,执行npm init初始化仓库,按需作答即可,会生成package.json文件

npm init
Copy

0x2 配置ESLint代码检查

开源了,代码是给别人看的,需要赏心悦目,用eslint可以规范我们代码。
1.安装eslint依赖,执行如下命令:

npm i eslint -D
Copy

2.添加eslint配置文件,执行如下命令:

./node_modules/.bin/eslint --init
Copy

选择需要的eslint规则和文件格式,会在仓库目录下生成一个eslint配置文件,我选的airbnb的规则和js文件格式,生成了文件.eslintrc.js,我还做了一些配置,关掉了一些校验规则,某些真滴烦:

module.exports = {
    "extends": "airbnb-base",
    "rules": {
        "semi": ["off", "always"],
        "quotes": ["off", "double"],
        "arrow-parens": ["off"],
        "comma-dangle": ["off"]
    }
};
Copy

3.在package.json里面scripts下添加lint命令

"scripts": {
    "lint": "eslint src/*.js"
  }
Copy

4.控制台可以执行校验,会自动lint src下的js文件,也可以在执行的时候加--fix参数来自动修复一些错误:

npm run lint
Copy

0x3 Rollup&Webpack构建

发布的代码需要编译压缩,我用了Rollup和Webpack,前一个用于tree shaking,后一个用于编译ES6代码并压缩,为什么用两个,我只能回答就是想用!
我的编译步骤是用rollup编译输出到build目录,然后用webpack编译build目录下的文件,输出到lib目录下

1.安装rollup依赖

npm i rollup -D
Copy

2.设置rollup的配置文件rollup.config.js,如下:

export default {
  input: 'src/index.js',
  output: {
    file: 'build/index.js',
    format: 'cjs'
  }
}
Copy

3.安装webpack依赖,包括babel相关,源码使用ES6写的,需要babel-loader:

npm i babel-loader @babel/core @babel/preset-env webpack -D
Copy

4.设置webpack的配置文件webpack.config.js,如下,注意libraryTarget: 'umd',,导出所有类型定义的模块,CommonJS/AMD/全局变量,而且要exclude掉依赖的模块,避免打包exclude: /(node_modules|bower_components)/,

const path = require('path');

module.exports = {
  mode: 'production',
  entry: './build/index.js',
  output: {
    libraryTarget: 'umd',
    path: path.resolve(__dirname, 'lib'),
    filename: 'index.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
}
Copy

0x4 自动生成文档

光有代码可不行,最好有一份文档,手写太累,更新不及时,用JSDoc自动将注释生成文档就好了。
1.安装jsdoc依赖:

npm i jsdoc -D
Copy

2.在package.json中添加jsdoc命令,我是把src下的所有js文件的注释生成文档到docs/developer目录下:

"scripts": {
    "doc": "jsdoc src/*.js -d ./docs/developer"
  }
Copy

3.控制台可以执行jsdoc命令,注释文档就自动生成了,html格式的,很清爽:

npm run jsdoc
Copy

源码:
image.png
文档:
image.png

0x5 自动化测试&测试覆盖率

不经过测试的代码是不可靠的,尤其类库型,自动化测试不可或缺,我选择的是Jest,配置简单,开箱即用。

1.安装Jest依赖:

npm i jest -D
Copy

2.生成jest配置文件jest.config.js,执行命令jest init或者手工配置,文件内容如下:

module.exports = {
  testURL: "http://localhost",
  testMatch: ["<rootDir>/test/*.js"], // 测试文件匹配路径(拿到根目录下test文件夹里的所有JS文件)
  coverageDirectory: "<rootDir>/test/coverage", // 测试覆盖率文档生成路径
  coverageThreshold: {
    // 测试覆盖率通过阈值
    global: {
      branches: 90,
      functions: 90,
      lines: 90,
      statements: 90
    }
  }
}
Copy

3.编写测试脚本,以下举个栗子:

const GetSetObj = require("../lib/index.js")
const { safeGet } = GetSetObj

describe("test a.b.c", () => {
  test("test null", () => {
    const obj = null
    expect(safeGet(obj, "a.b.c")).toBe(undefined)
  })
})

describe("test a.b", () => {
    test("test {a: {b: {c: 1}}}", () => {
      const obj = { a: { b: { c: 1 } } }
      expect(safeGet(obj, "a.b")).toEqual({c: 1})
    })
  })

describe("test a.b.c", () => {
    test("test {a: {b: {c: 1}}}", () => {
      const obj = { a: { b: { c: 1 } } }
      expect(safeGet(obj, "a.b.c")).toBe(1)
    })
  })
Copy

4.在package.json中配置test命令:

"scripts": {
    "test": "jest"
  }
Copy

5.执行test命令,可以用快捷命令npm t

npm t
Copy

6.结果如下图:
image.png

0x6 Git提交钩子

使用husky可以设置git命令钩子,在执行git commit命令时自动触发自动化测试和lint的命令:

1.安装依赖:

npm i husky -D
Copy

2.在package.json中配置husky:

"husky": {
    "hooks": {
      "pre-commit": "npm run lint && npm test",
      "pre-push": "npm test",
      "...": "..."
    }
  }
Copy

0x7 配置CI持续集成流程

我们希望每次修改的代码可以安全可持续的集成到仓库中,Travis CI可以帮我们,每次提交代码,它会自动拉取,然后提供一个虚拟环境,执行测试、构建,部署动作,同时反馈运行结果,全部通过,自动合并代码到主干。

1.登录Travis CI,绑定github账号,开启你github里面指定仓库的CI开关:
image.png

2.添加.travis.yml配置文件,如下:

language: node_js           # 项目语言, nodejs
node_js:
- 8.11.2                    # 项目环境, jest要求4+
cache:
  directories:
  - node_modules
after_success:              # 构建成功后的自定义操作
- npm run codecov           # 生成 Github 首页的 codecov 图标
Copy

3.push代码,触发Travis CI,可以实时看到运行结果:
image.png

4.每次构建的记录也会保存:
image.png

0x8 添加开源许可证

开源库需要配置一份合适的开源许可证告诉其他人如何使用你的库,可以参考文章 如何选择开源许可证?
image.png

1.打开我们的开源项目并切换至 Insights 面板
2.点击 Community 标签
3.如果您的项目没有添加 License,在 Checklist 里会提示您添加许可证,点击 Add 按钮就进入可视化操作流程了,主要是按照模板生成一份LICENCE文件在你的仓库中,我选择的是MIT协议,最宽松的那种~

0x9 美化你的库

这里说的是仓库里一些标签,比如构建结果、代码测试覆盖率、npm版本、开源许可证、语言等:
image.png

1.shields.io选择一些标签,直接copy md格式的到README文件即可,需要替换为你的库名
2.修改README文件,以我的仓库举例:

![Travis (.org)](https://img.shields.io/travis/zzuwzj/get-set-obj.svg)  [![codecov](https://codecov.io/gh/zzuwzj/safe-object/branch/master/graph/badge.svg)](https://codecov.io/gh/zzuwzj/safe-object)  [![npm](https://img.shields.io/npm/v/get-set-obj.svg)](https://www.npmjs.com/package/get-set-obj)  ![GitHub](https://img.shields.io/github/license/zzuwzj/get-set-obj.svg)  ![GitHub language count](https://img.shields.io/badge/language-JavaScript-yellow.svg)
Copy

0xa 项目主页github pages

仓库开发完了,想要一个网站来宣传怎么办?用GitHub Pages! 这个是github自带的一个功能,可以帮你的仓库生成一个静态网站。

1.进入你的仓库,点击Settings tab,在下方找到GitHub Pages:
image.png

2.选择一个主题:
image.png

3.仓库专属的静态网站就生成了:
zzuwzj.github.io/get-set-obj…
image.png

还是挺好看的,展示的是README的内容:
image.png

0xb 发布到npm&同步到zodiac

1.开发完成后发布库到npm,没有发布过的话需要先去npm注册个账号
2.登录npm,输入用户名和密码:

npm login
Copy

3.执行publish命令:

npm publish
Copy

Tips:
如果遇到401错误,可能是因为没有登录,如果遇到403错误,可能是你的库名字别人已经占用了,需要换个名字

4.同步到Zodiac,就可以在saga style应用中使用了

三、完整的目录结构

image.png

四、参考

【掘金】开源库架构实战——从0到1搭建属于你自己的开源库
【Rollup】
【Webpack】
【Jest】
【ESLint】
【Travis CI】
【Code coverage】
【JSDoc】
【husky】

五、附:浅尝辄止系列