在日常开发中,经常会遇到一些通用的逻辑,每次都需要复制粘贴。作为coder,我们可以将一些常用的业务逻辑封装成一个通用的函数库,发布到npm。这样,每次遇到新项目,只需要安装即可,这里我们已经有了一个fe-utils前端日常开发工具库,也是本文的收官之作,会持续更新将来。如果你有一颗开源的心,但又没有信心为大项目提pr,不妨从这个封装了日常通用逻辑的项目入手,一起进步!!!接下来,我们将尝试自己实现一个工具库创建项目。先在我们自己的github上创建一个项目,然后拉取。进入仓库,执行yarninit。一直往下输入。主要目录结构-.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和tsyarnaddrolluptypescript-D2。配置typescript配置文件yarntsc--init生成默认配置文件,然后改成如下:{"compilerOptions":{"target":"es5"/*compiletarget*/,"module":"commonjs"/*项目模块类型*/,"lib":["ES2018","DOM"],"allowJs":true/*是否允许js代码*/,"checkJs":true/*检查js代码errors*/,"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添加@rollup/plugin-node-resolve@rollup/plugin-typescript@rollup/plugin-commonjsrollup-plugin-terser-D下面是@rollup/plugin-node-resolve处理路径@rollup/plugin-typescript支持的函数ts@rollup/plugin-commonjs处理commonjsrollup-plugin-terser压缩umd规范的输出文件constresolve=require('@rollup/plugin-node-resolve');consttypescript=require('@rollup/plugin-typescript');constcommonjs=require('@rollup/plugin-commonjs');const{terser}=require('rollup-plugin-terser')module.exports=[{输入:'./src/index.ts',输出:[{dir:'lib',格式:'cjs',entryFileNames:'[name].cjs.js',sourcemap:false,//是否输出sourcemap},{dir:'lib',format:'esm',entryFileNames:'[name].esm.js',sourcemap:false,//是否输出sourceemap},{dir:'lib',format:'umd',entryFileNames:'[name].umd.js',name:'FE_utils',//umd模块名,相当于一个命名空间,会自动挂载Go到窗口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",“模块”:“lib/index.esm.js”,“jsnext:main”:“lib/index.esm.js”,“浏览器”:“lib/index.umd.js”,“类型”:“lib/index.d.ts","files":["lib"],"repository":{"type":"git","url":"git+https://github.com/SaebaRyoo/fe-utils.git"},"author":"SaebaRyoo","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":"Front-结束业务代码工具库","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包浏览使用脚本在浏览器中导入ts类型文件"types":"lib/index.d.ts",使用yarnrunbuild打包项目"scripts":{"build":"rollup-c",},files字段是为了约定npm在发布包时发布包含的文件和文件夹"files":["lib"],5.安装jest+lint+prettier+husky+commit-msg来约束代码质量首先安装安装测试框架jest,因为项目是基于ts写的,所以需要配置jest来支持tsyarnadd-Djestts-jest@types/jest创建配置文件yarnjest--init修改配置文件,完成如下。jest默认环境是node,但是我们的工具库是面向前端的,必须操作dom。所以需要安装yarnaddjest-environment-jsdom-D来支持DOM和BOM操作,然后在使用DOM或BOM对象运行的测试文件顶部添加这行注释/***@jest-environmentjsdom*/或者修改配置文件中的运行环境为testEnvironment:'jsdom'/**各个配置属性的详细解释请访问:*https://jestjs.io/docs/configuration*/exportdefault{clearMocks:true,collectCoverage:true,coverageDirectory:'coverage',coverageProvider:'v8',preset:'ts-jest',testEnvironment:'jsdom',//支持测试环境访问dom//配置测试环境uatestEnvironmentOptions:{userAgent:'Mozilla/5.0(Macintosh;IntelMacOSX10_15_7)AppleWebKit/537.36(KHTML,likeGecko)Chrome/108.0.0.0Safari/537.36',},};在package.json的脚本中添加cli命令{"scripts":{"test":"jest","coveralls":"jest--coverage",}}最后按照本文的步骤配置规范代码的文件开发,我们先写一个简单的sum方法和单元测试src/sum在src目录.tsexportfunctionsum(...args:number[]):number{returnargs.reduce((prev,total)=>total+prev,0);}在入口src/index.tsexport{sum}from'./sum';为sumsrc/__test__/sum.test.tsimport{sum}from'../index'describe('sum',()=>{it('shouldwork',()=>{expect(sum()).toEqual(0)})})至此,基本上最简单的npm包开发完成,接下来就是发布npm包Publish1.先手动发布需要准备一个账号,然后登录,输入你的npm账号,密码,邮箱,npmlogin可以使用npmlogout退出当前账号,npmwhoami可以查询当前登录的账号,登录成功后,可以通过npmpublish将包推送到服务器,如果版本包有问题,可以使用npmunpublish[pkg]@[version]撤回注意:如果使用@[scope]/package命名形式,[scope]必须写你的账号名,否则会发布Prompt4042。使用githubaction发布npm,创建release,处理一些工作流。如果不知道githubaction,建议学习githubactions的一些概念,在根目录下创建.github/workflows/node.js.ymlCI配置文件(这里也可以在tab中找到Actions生成仓库上列)注意:如果需要不同的action,可以在Marketplace中找到需要的actiontarget自动发布npm包创建release并上传对应的asset运行单元测试生成测试覆盖率submittocoveralls准备:在npm中生成一个token,然后将token复制到github中对应仓库的secretkey中,设置一个变量名。这里我们设置了NPM_ACCESS_TOKEN。后面我们可以通过CI中的secrets.NPM_ACCESS_TOKEN获取整体代码。有了上面的想法,请看下面的整体代码#这个工作流将干净地安装节点依赖项,缓存/恢复它们,构建源代码并在不同版本的节点上运行测试#有关更多信息,请参见:https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejsname:Node.jsCIon:push:branches:["main"]jobs:build:runs-on:ubuntu-lateststrategy:matrix:node-version:[18.x]#在https://nodejs.org/en/about/releases/查看支持的Node.js发布计划步骤:-uses:actions/checkout@v3-name:UseNode.js${{matrix.node-version}}使用:actions/setup-node@v3with:node-version:${{matrix.node-version}}cache:'yarn'-run:yarn#测试和生成测试覆盖率文件-运行:yarnruncoveralls-运行:yarnrunbuild#Report-name:Coverallsuses:coverallsapp/github-action@masterwith:github-token:${{secrets.GITHUB_TOKEN}}#publish-npmtaskpublish-npm:#在最新的虚拟机上执行runs-versionofubuntuon:ubuntu-latest#设置变量strategy:matrix:node-version:[18.x]steps:#检查并切换到主分支-name:Checkmainbranch#Useactions/checkoutpluginuses:actions/checkout@v3#初始化缓存-name:cacheuses:actions/cache@v3id:cache-dependencieswith:path:node_moduleskey:${{runner.OS}}-${{hashFiles('**/yarn.lock')}}#安装节点-name:SetupNode.js#使用actions/setup-node插件uses:actions/setup-node@v3with:#nodeversionnode-version:${{matrix.node-version}}-run:yarn-run:yarnrunbuild#读取当前版本号-name:读取当前版本号id:versionuses:notiz-dev/github-action-json-property@releasewith:#读取版本号path:'./package.json'prop_path:'version'-run:echo${{steps.version.outputs.prop}}#创建Release-name:release#原来使用的actions/create-release@最新发布版本,actions/upload-release-asset@v1uploadrelease-asset#不过这两个action官方已经停止维护了,所以换成下面的uses:softprops/action-gh-release@v1与:文件:./lib/index.umd.js名称:v${{steps.version.outputs.prop}}tag_name:v${{steps.version.outputs.prop}}env:GITHUB_TOKEN:${{secrets.GITHUB_TOKEN}}#PublishNPMpackage-name:PublishNPMpackage#执行发布代码run:|npmconfigset//registry.npmjs.org/:_authToken=$NPM_TOKENnpmpublishenv:#配置npm访问令牌环境变量NPM_TOKEN:${{secrets.NPM_ACCESS_TOKEN}}#刷新缓存-name:refreshcacherun:|curlhttps://purge.jsdelivr.net/npm/iemotion-pic@latest/lib/name.jsonaddbadgetoreadme我们会在一个开源项目中找到,readmepass往往写的很好,还有很多徽章,比如ant-design的readme。那么这一切是如何完成的呢?一些简单的徽章可以直接在shields中输入仓库名生成。例如:workflowworkflowstatus:npmpackageversion:license:我们也可以根据需要创建不同的徽章,但是需要添加测试覆盖率的徽章会略有不同麻烦。首先,进入工作服官网。进入后需要通过github授权。点击左侧边栏的ADDREPOS后,会进入如下页面。然后我们将需要生成徽章徽章的库设置为on。下面的流程是在CIScript中执行测试并生成测试覆盖率文件上传到coveralls