在日常开发中,常常会遇到一些通用的逻辑,导致每次都须要复制粘贴。而咱们作为coder,能够将一些罕用业务逻辑封装成通用的函数库,并公布到npm中。
这样,每次遇到新的我的项目时,只须要 install一下即可
这里咱们曾经有了一个fe-utils 前端日常开发工具库,也是本文最初的产物,并且后续也会继续更新。如果你有一个开源的心,然而没信念去为大的我的项目提pr,无妨从这个封装日常通用逻辑的我的项目做起,咱们一起提高!!!
接下来咱们就尝试本人入手实现一个工具库
创立我的项目
首先在本人的github上创立一个我的项目,而后拉取。进入到该仓库中,执行yarn init
。一路enter上来。
次要目录构造
- .github - workflows - xx.yml- .husky- src - __test__ - index.ts - sum.ts- .editorconfig- .gitignore- .npmignore- commitlint.config.js- jest.config.mjs- package.json- rollup.config.js- tsconfig.json
配置我的项目
1. 装置rollup和ts
yarn add rollup typescript -D
2. 配置typescript配置文件
yarn tsc --init
生成一个默认的配置文件,而后依据咱们的我的项目,改成如下:
{ "compilerOptions": { "target": "es5" /* 编译指标 */, "module": "commonjs" /* 我的项目模块类型 */, "lib": ["ES2018", "DOM"], "allowJs": true /* 是否容许js代码 */, "checkJs": true /* 查看js代码谬误 */, "declaration": true /* 主动创立申明文件(.d.ts) */, "declarationDir": "./lib" /* 申明文件目录 */, "sourceMap": true /* 主动生成sourcemap文件 */, "outDir": "lib" /* 编译输入目录 */, "rootDir": "./src" /* 我的项目源码根目录,用来管制编译输入的目录构造 */, "strict": true /* 启用严格模式 */ }, "include": ["src/index.ts"], "exclude": ["node_modules", "lib"]}
3. 配置rollup.config.js
在配置之前,咱们须要装置几个rollup插件yarn add @rollup/plugin-node-resolve @rollup/plugin-typescript @rollup/plugin-commonjs rollup-plugin-terser -D
这几个别离是如下作用
- @rollup/plugin-node-resolve 解决门路
- @rollup/plugin-typescript 反对ts
- @rollup/plugin-commonjs 解决commonjs
- rollup-plugin-terser 压缩umd标准的输入文件
const resolve = require('@rollup/plugin-node-resolve');const typescript = require('@rollup/plugin-typescript');const commonjs = require('@rollup/plugin-commonjs');const { terser } = require('rollup-plugin-terser')module.exports = [ { input: './src/index.ts', output: [ { dir: 'lib', format: 'cjs', entryFileNames: '[name].cjs.js', sourcemap: false, // 是否输入sourcemap }, { dir: 'lib', format: 'esm', entryFileNames: '[name].esm.js', sourcemap: false, // 是否输入sourcemap }, { dir: 'lib', format: 'umd', entryFileNames: '[name].umd.js', name: 'FE_utils', // umd模块名称,相当于一个命名空间,会主动挂载到window上面 sourcemap: false, plugins: [terser()], }, ], plugins: [resolve(), commonjs(), typescript({ module: "ESNext"})], }]
4. 批改package.json
咱们间接看残缺的package.json
{ "name": "@lxnxbnq/utils", "version": "0.0.2-alpha", "main": "lib/index.cjs.js", "module": "lib/index.esm.js", "jsnext:main": "lib/index.esm.js", "browser": "lib/index.umd.js", "types": "lib/index.d.ts", "files": [ "lib" ], "repository": { "type": "git", "url": "git+https://github.com/SaebaRyoo/fe-utils.git" }, "author": "SaebaRyoo <yuanddmail@163.com>", "license": "MIT", "scripts": { "build": "rollup -c", "test": "jest" }, "devDependencies": { "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-commonjs": "^23.0.4", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-typescript": "^10.0.1", "@types/jest": "^29.2.4", "jest": "^29.3.1", "rollup": "^3.7.2", "rollup-plugin-terser": "^7.0.2", "ts-jest": "^29.0.3", "tslib": "^2.4.1", "typescript": "^4.9.4" }, "description": "前端业务代码工具库", "bugs": { "url": "https://github.com/SaebaRyoo/fe-utils/issues" }, "homepage": "https://github.com/SaebaRyoo/fe-utils#readme", "dependencies": {}}
其中须要留神的有如下几个字段
告知使用者不同的标准援用哪个文件
- "main": "lib/index.cjs.js", // 当应用commonjs标准时会应用这个包
- "module": "lib/index.esm.js", // 应用esm时,会应用这个包
- "jsnext:main": "lib/index.esm.js", //这个同上,不过这个是社区标准,下面是官网标准
- "browser": "lib/index.umd.js", // umd标准,当间接在浏览器中开发时,能够间接下载release包并在浏览器中应用script导入
ts类型文件
- "types": "lib/index.d.ts",
应用yarn run build
打包我的项目
- "scripts": {
"build": "rollup -c",
},
files 字段是用于约定在发包的时候NPM 会公布蕴含的文件和文件夹。
"files": [
"lib"
],
5. 装置jest + lint + prettier + husky + commit-msg对代码的品质进行束缚
首先是装置装置测试框架jest,因为我的项目时基于ts写的,所以须要配置jest来反对tsyarn add -D jest ts-jest @types/jest
- 创立配置文件
yarn jest --init
- 批改配置文件,残缺如下
jest的默认环境是node,然而咱们这个工具库是面向前端的,必定须要操作dom,所以须要装置yarn add jest-environment-jsdom -D
来反对DOM和BOM操作
而后就是在应用到DOM或者BOM对象的测试文件的顶部加上这一行正文即可运行
/** * @jest-environment jsdom */
或者在配置文件中批改运行环境为testEnvironment: 'jsdom'
/* * For a detailed explanation regarding each configuration property, visit: * https://jestjs.io/docs/configuration */export default { clearMocks: true, collectCoverage: true, coverageDirectory: 'coverage', coverageProvider: 'v8', preset: 'ts-jest', testEnvironment: 'jsdom', // 反对测试环境拜访dom // 配置测试环境ua testEnvironmentOptions: { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', },};
在package.json的script中增加cli命令
{ "scripts": { "test": "jest", "coveralls": "jest --coverage", }}
- 最初依照这篇文章的步骤来配置标准代码的文件
开发
咱们先在src的目录下写一个简略的sum办法以及一个单元测试
src/sum.ts
export function sum(...args: number[]): number { return args.reduce((prev, total) => total + prev, 0);}
在入口中导入并导出
src/index.ts
export { sum } from './sum';
写一个sum的单元测试
src/__test__/sum.test.ts
import {sum} from '../index'describe('sum', () => { it('should work', () => { expect(sum()).toEqual(0) })})
到这,基本上一个最简略的npm包就开发完了,接下来就是须要公布
npm包公布
1. 手动公布
首先须要筹备一个账号,而后进行登录,输出你的npm账号、明码、邮箱npm login
能够用npm logout
退出以后账号
npm who am i
查问以后登录的账号
登录胜利就能够通过npm publish
将包推送到服务器上
如果某版本的包有问题,能够应用npm unpublish [pkg]@[version]
将其撤回
留神:如果应用@[scope]/package
的命名模式,[scope]肯定要写你的账号名,不然公布的时候会提醒404
2. 应用github action 公布npm、创立release 以及解决一些工作流程
如果不理解github action的话, 倡议先学习一下github actions的一些概念
在根目录下创立.github/workflows/node.js.yml
CI配置文件(这里也能够在仓库上的tab栏中找到Actions生成)
留神:如果你须要不同的actions,能够在Marketplace中查找须要的action
指标
- 主动公布npm包
- 创立release并上传对应asset
- 跑单元测试,生成测试覆盖率提交到coveralls
筹备工作
- 在npm中生成token
- 而后复制token到github对应仓库的秘钥中
- 设置一个变量名,咱们这里设置的是
NPM_ACCESS_TOKEN
,前面能够在CI中通过secrets.NPM_ACCESS_TOKEN
获取到
整体代码
有了以上的思路来看上面的整体代码
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejsname: Node.js CIon: push: branches: [ "main" ]jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [18.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: 'yarn' - run: yarn # 测试,并生成测试覆盖率文件 - run: yarn run coveralls - run: yarn run build # 上报 - name: Coveralls uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} # publish-npm工作 publish-npm: # 在ubuntu最新版本的虚拟机执行 runs-on: ubuntu-latest # 设置变量 strategy: matrix: node-version: [ 18.x ] steps: # 查看并切换到main分支 - name: 查看main分支 # 应用actions/checkout插件 uses: actions/checkout@v3 # 初始化缓存 - name: 缓存 uses: actions/cache@v3 id: cache-dependencies with: path: node_modules key: ${{runner.OS}}-${{hashFiles('**/yarn.lock')}} # 装置node - name: 设置Node.js # 应用actions/setup-node插件 uses: actions/setup-node@v3 with: # node版本 node-version: ${{ matrix.node-version }} - run: yarn - run: yarn run build # 读取以后版本号 - name: 读取以后版本号 id: version uses: notiz-dev/github-action-json-property@release with: # 读取版本号 path: './package.json' prop_path: 'version' - run: echo ${{steps.version.outputs.prop}} # 创立Release - name: release # 本来应用的 actions/create-release@latest来发版, actions/upload-release-asset@v1上传release-asset # 不过这两个action官网曾经进行保护了,所以换成如下 uses: softprops/action-gh-release@v1 with: files: ./lib/index.umd.js name: v${{steps.version.outputs.prop}} tag_name: v${{steps.version.outputs.prop}} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # 公布NPM包 - name: 公布NPM包 # 执行公布代码 run: | npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN npm publish env: # 配置 npm access token 环境变量 NPM_TOKEN: ${{secrets.NPM_ACCESS_TOKEN}} # 刷新缓存 - name: 刷新缓存 run: | curl https://purge.jsdelivr.net/npm/iemotion-pic@latest/lib/name.json
为readme增加badge(徽章)
咱们会发现在一个开源我的项目中,readme通常都会写的很好,而且还有很多的badge,如ant-design的readme
那么这一切都是怎么实现的呢?一些简略的badge能够间接在shields中输出仓库名即可生成。
比方:
workflow工作流状态:
npm包版本:
license:
咱们也能够依据本人须要来创立不同的badge
不过要增加测试覆盖率的badge会稍稍有些麻烦。
- 首先进入coveralls官网,进去后须要通过github的受权
- 受权后点击左侧侧边栏的 ADD REPOS 会进入如下页面
而后咱们将须要生成badge徽章的库设置为on即可
- 前面的流程就是在CI中执行测试脚本并生成测试覆盖率的文件而后上传到coveralls就能够了