详解如何发布TypeScript编写的npm包

2022-12-05 34阅读 0评论

?=前言

在这篇文章中,我们将使用TypeScriptjest从头开始构建和发布一个npm

我们将初始化一个项目,设置TypeScript,用Jest编写测试,并将其发布到NPM。

项目

我们的称为DIgx。它允许从嵌套对象中根据路径找出值,似于lodash中的Get函数

比如说:

const source = { my: { nested: [1, 2, 3] } } digx(source, "my.nested[1]") //=> 2 

就本文而言,只要它是简洁的和可测试的,它做什么并不那么重要。

npm包可以在这里找到。github仓库地址在这里。

初始化项目

让我们从创建目录并初始化它开始。

mkdir digx cd digx npm init --yes 

npm init --yes命令将为你创建package.JSon文件,并填充一些默认值。

让我们也在同一文件夹中设置一个git仓库。

Git init echo "node_modules" >> .gitignore echo "dist" >> .gitignore git add . git commit -m "initial" 

构建库

这里会用到typeScript,我们来安装它。

npm i -D Typescript 

使用下面的配置创建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": true, "strictPropertyInitialization": true, "noImplicitthis": true, "alwaysStrict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitreturns": true, "noFallthroughCasesInSwitch": true, "noUncheckedIndexedAccess": true, "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模式。

"declaration": true - 因为我们想要自动生成d.ts声明文件。我们的TypeScript用户将需要这些声明文件。

其他大部分选项只是各种可选的TypeScript检查,我更喜欢开启这些检查。

打开package.json,更新scripts的内容:

"scripts": {   "bUIld": "tsc" } 

现在我们可以用npm run build运行构建...这样会失败的,因为我们还没有任何可以构建的代码

我们从另一端开始。

添加测试

作为一名负责任的开发,我们将从测试开始。我们将使用jest,因为它简单且好用。

npm i -D jest @types/jest ts-jest 

ts-jest包是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,填入如下代码:

import dg from "./index"; test("works with a shallow object", () => {   expect(dg({ param: 1 }, "param")).toBe(1); }); test("works with a shallow array", () => {   expect(dg([1, 2, 3], "[2]")).toBe(3); }); test("works with a shallow array when shouldThrow is true", () => {   expect(dg([1, 2, 3], "[2]", true)).toBe(3); }); test("works with a nested object", () => {   const source = { param: [{}, { test: "A" }] };   expect(dg(source, "param[1].test")).toBe("A"); }); test("returns undefined when source is null", () => {   expect(dg(null, "param[1].test")).toBeUndefined(); }); test("returns undefined when path is wrong", () => {   expect(dg({ param: [] }, "param[1].test")).toBeUndefined(); }); test("throws an exception when path is wrong and shouldThrow is true", () => {   expect(() => dg({ param: [] }, "param[1].test", true)).toThrow(); }); test("works tranparently with Sets and Maps", () => {   const source = new map([ ["param", new Set()], ["innerSet", new Set([new Map(), new Map([["innerKey", "value"]])])],   ]);   expect(dg(source, "innerSet[1].innerKey")).toBe("value"); }); 

这些单元测试让我们对正在构建的东西有一个直观的了解。

我们的模块导出一个单一函数,digx。它接收任意对象,字符串参数path,以及可选参数shouldThrow,该参数使得提供的路径在源对象的嵌套结构中不被允许时,抛出一个异常

嵌套结构可以是对象和数组,也可以是Map和Set。

使用npm t运行测试,当然,不出意外会失败。

现在打开src/index.ts文件,并写入下面内容:

export default dig; /**  * A dig function that takes any object with a nested Structure and a path,  * and returns the value under that path or undefined when no value is found.  *  * @param {any} source - A nested objects.  * @param {string}  path - A path string, for example `my[1].test.field`  * @param {boolean} [shouldThrow=false] - Optionally throw an exception when nothing found  *  */ function dig(source: any, path: string, shouldThrow: boolean = false) {   if (source === null || source === undefined) { return undefined;   }   // split path: "param[3].test" => ["param", 3, "test"]   const parts = splitPath(path);   return parts.reduce((acc, el) => { if (acc === undefined) {   if (shouldThrow) { throw new Error(`Could not dig the value using path: ${path}`);   } else { return undefined;   } } if (isNum(el)) {   // array getter [3]   const arrIndex = parseInt(el);   if (acc instanceof Set) { return Array.from(acc)[arrIndex];   } else { return acc[arrIndex];   } } else {   // object getter   if (acc instanceof Map) { return acc.get(el);   } else { return acc[el];   } }   }, source); } const ALL_DIGITS_REGEX = /^\d+$/; function isNum(str: string) {   return str.match(ALL_DIGITS_REGEX); } const PATH_SPLIT_REGEX = /\.|\]|\[/; function splitPath(str: string) {   return ( str   .split(PATH_SPLIT_REGEX)   // remove empty strings   .filter((x) => !!x)   ); } 

这个实现可以更好,但对我们来说重要的是,现在测试通过了。自己用npm t试试吧。

现在,如果运行npm run build,可以看到dist目录下会有两个文件,index.jsindex.d.ts

接下来就来发布吧。

发布

如果你还没有在npm上注册,就先注册。

注册成功后,通过你的终端用npm login登录

我们离发布我们的新包只有一步之遥。不过,还有几件事情需要处理

首先,确保我们的package.json中拥有正确的元数据

确保main属性设置为打包的文件"main": "dist/index.js"。为TypeScript用户添加"types": "dist/index.d.ts"。因为我们的库会作为ES Module被使用,因此需要指定"type": "module"nameDescription也应填写。

接着,我们应该处理好我们希望发布的文件。我不觉得要发布任何配置文件,也不觉得要发布源文件和测试文件。

我们可以做的一件事是使用.npmignore,列出所有我们不想发布的文件。我更希望有一个"白名单",所以让我们使用package.json中的files字段来指定我们想要包含的文件。

{   // ...   "files": ["dist", "LICENSE", "README.md", "package.json"],   // ... } 

终于,我们已经准备好发包了。

运行以下命令:

npm publish --dry-run 

并确保只包括所需的文件。当一切准备就绪时,就可以运行:

npm publish 

测试一下

让我们创建一个全新的项目并安装我们的模块。

npm install --save digx 

现在,让我们写一个简单的程序来测试它。

import dg from "digx" console.log(dg({ test: [1, 2, 3] }, "test[0]")) 

结果非常棒!

详解如何发布TypeScript编写的npm包

然后运行node index.js,你会看到屏幕上打印1

总结

我们从头开始创建并发布了一个简单的npm包。

我们的库提供了一个ESM模块,TypeScript的类型,使用jest覆盖测试用例。

你可能会认为,这其实一点都不难,的确如此。

原文链接:www.strictmode.io/articles/bu…

以上就是详解如何发布TypeScript编写的npm包的详细内容,更多关于TypeScript npm包发布的资料请关注云初冀北其它相关文章!

免责声明
本站提供的资源,都来自网络,版权争议与本站无关,所有内容及软件的文章仅限用于学习和研究目的。不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负,我们不保证内容的长久可用性,通过使用本站内容随之而来的风险与本站无关,您必须在下载后的24个小时之内,从您的电脑/手机中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。侵删请致信E-mail:Goliszhou@gmail.com
$

发表评论

表情:
评论列表 (暂无评论,34人围观)

还没有评论,来说两句吧...