当前位置: 首页 > Web前端 > HTML

如何发布用TypeScript编写的npm包

时间:2023-03-28 16:13:19 HTML

前言在这篇文章中,我们将使用TypeScript和Jest从头开始??构建和发布NPM包。我们将初始化一个项目,设置TypeScript,使用Jest编写测试,并将它们发布到NPM。项目我们的库叫做digx。它允许根据路径从嵌套对象中找出值,类似于lodash中的get函数。例如:constsource={my:{nested:[1,2,3]}}digx(source,"my.nested[1]")//=>2对于本文的目的,只要它简洁且可测试,它做什么并不重要。npm包可以在这里找到。GitHub仓库地址在这里。初始化项目让我们首先创建一个空目录并对其进行初始化。mkdirdigxcddigxnpminit--yesnpminit--yes命令将为您创建package.json文件,并用一些默认值填充它。让我们在同一文件夹中设置一个git存储库。gitinitcho"node_modules">>.gitignoreecho"dist">>.gitignoregitadd.gitcommit-m"initial"构建库TypeScript将在这里使用,让我们安装它。npmi-Dtypescript使用下面的配置创建tsconfig.json文件:{"files":["src/index.ts"],"compilerOptions":{"target":"es2015","module":"es2015","declaration":true,"outDir":"./dist","noEmit":false,"strict":true,"noImplicitAny":true,"strictNullChecks":true,"strictFunctionTypes":true,"strictBindCallApply":真实,“strictPropertyInitialization”:真实,“noImplicitThis”:真实,“alwaysStrict”:真实,“noUnusedLocals”:真实,“noUnusedParameters”:真实,“noImplicitReturns”:真实,“noFallthroughCasesInSwitch”:真实,“noUncheckedIndexedAccess”:真实,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"esModuleInterop":true,"forceConsistentCasingInFileNames":true,"skipLibCheck":true}}最重要的设置是这些:库的主文件将位于src文件夹中,因此设置"files":["src/index.ts"]"target":"es2015"确保我们的库支持现代平台并且不携带不必要的垫片。"module":"es2015"。我们的模块将是一个标准的ES模块(默认是CommonJS)。ES模式有效在现代浏览器中没有任何问题;甚至Node从版本13开始支持ES-mode。"declaration":true-因为我们想自动生成d.ts声明文件。我们的TypeScript用户将需要这些声明文件。其他大多数选项是只是各种可选的TypeScript检查,我更喜欢打开它。打开package.json并更新脚本的内容:"scripts":{"build":"tsc"}现在我们可以使用npmrunbuild来运行构建。.这将失败,因为我们还没有任何代码要构建。我们将从另一端开始。添加测试作为负责任的开发人员,我们将从测试开始。我们将使用jest,因为它简单易行使用npmi-Djest@types/jestts-jestts-jestpackage是Jest需要了解TypeScript的包。另一种选择是使用babel,这将需要更多的配置和额外的模块。我们只是保持简单并使用ts-jest。使用以下命令初始化jest配置文件:./node_modules/.bin/jest--init一路按回车键,默认值即可。这将使用一些默认选项创建jest.config.js文件,并将"test":"jest"脚本添加到package.json。打开jest.config.js,找到以preset开头的行,并将其更新为:{//...preset:"ts-jest",//...}最后,创建src目录和测试文件src/digx.test.ts,填写如下代码:importdgfrom"./index";test("workswithashallowobject",()=>{expect(dg({param:1},"param")).toBe(1);});test("适用于浅数组",()=>{expect(dg([1,2,3],"[2]")).toBe(3);});test("当shouldThrow为真时使用浅数组",()=>{expect(dg([1,2,3],"[2]",true)).toBe(3);});test("workswithanestedobject",()=>{constsource={param:[{},{test:"A"}]};expect(dg(source,"param[1].test")).toBe("A");});test("当source为null时返回undefined",()=>{expect(dg(null,"param[1].test")).toBeUndefined();});test("当路径错误时返回undefined",()=>{expect(dg({param:[]},"param[1].test")).toBeUnddefined();});test("当路径错误且shouldThrow为真时抛出异常",()=>{expect(()=>dg({param:[]},"param[1].test",true)).toThrow();});test("与Sets和Maps一起工作",()=>{constsource=newMap([["param",newSet()],["innerSet",newSet([newMap(),newMap([["innerKey","value"]])])],]);expect(dg(source,"innerSet[1].innerKey")).toBe("值");});这些单元测试让我们对正在构建的内容有一个直观的认识。我们的模块导出一个函数digx。它接受任何对象、字符串参数路径和可选参数shouldThrow,如果提供的路径在源对象的嵌套结构中不允许,则会引发异常。嵌套结构可以是对象和数组,也可以是Maps和Set。使用npmt运行测试当然会毫无例外地失败。现在打开src/index.ts文件,并写入下面内容:exportdefaultdig;/***一个dig函数,它接受任何具有嵌套结构和路径的对象,*并返回该路径下的值,或者在没有时返回未定义的值值被发现。**@param{any}source-嵌套对象。*@param{string}path-路径字符串,例如`my[1].test.field`*@param{boolean}[shouldThrow=false]-可选地在没有找到时抛出异常**/functiondig(source:any,path:string,shouldThrow:boolean=false){if(source===null||source===undefined){返回未定义;}//拆分路径:"param[3].test"=>["param",3,"test"]constparts=splitPath(path);returnparts.reduce((acc,el)=>{if(acc===undefined){if(shouldThrow){thrownewError(`Couldnotdigthevalueusingpath:${path}`);}else{returnundefined;}}if(isNum(el)){//数组getter[3]constarrIndex=解析整数(EL);如果(accinstanceofSet){returnArray.from(acc)[arrIndex];}else{返回acc[arrIndex];}}else{//对象getterif(accinstanceofMap){returnacc.得到(EL);}else{返回acc[el];}}},source);}constALL_DIGITS_REGEX=/^\d+$/;functionisNum(str:string){returnstr.match(ALL_DIGITS_REGEX);}constPATH_SPLIT_REGEX=/\.|\]|\[/;函数splitPath(str:string){return(str.split(PATH_SPLIT_REGEX)//删除空字符串.filter((x)=>!!x));}这个实现可能会更好,但对我们来说重要的是现在测试通过并使用npmt自己尝试。现在,如果你运行npmrunbuild,你可以看到dist目录中将有两个文件,index.js和index.d.ts。接下来发布吧。如果您还没有,请在npm上发布注册。注册成功后,通过终端使用npmlogin登录。我们离发布新软件包又近了一步。但是,仍有一些事情需要注意。首先,确保我们的package.json中有正确的元数据。确保main属性设置为打包文件“main”:“dist/index.js”。为TypeScript用户添加"types":"dist/index.d.ts"。因为我们的库会作为一个ESModule来使用,所以我们需要指定"type":"module"。名称和描述也应填写。接下来,我们应该处理我们希望发布的文件。我不想发布任何配置文件,也不想发布源文件和测试文件。我们可以做的一件事是使用.npmignore,它列出了我们不想发布的所有文件。我宁愿有一个“白名单”,所以让我们使用package.json中的文件字段来指定我们想要包含的文件。{//..."files":["dist","LICENSE","README.md","package.json"],//...}最后,我们准备好发送包了。运行以下命令:npmpublish--dry-run并确保只包含所需的文件。一切就绪后,运行:npmpublishTest让我们创建一个全新的项目并安装我们的模块。npminstall--savedigx现在,让我们编写一个简单的程序来测试它。importdgfrom"digx"console.log(dg({test:[1,2,3]},"test[0]"))结果很棒!然后运行nodeindex.js,你会看到屏幕上打印出1。总结我们从头开始创建并发布了一个简单的npm包。我们的库提供了一个带有TypeScript类型的ESM模块,以覆盖使用jest的测试用例。您可能认为这一点也不难,事实确实如此。以上就是本文的全部内容。如果对你有帮助,欢迎收藏、点赞、转发~