持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
1. 概览
老规矩,看包先看官网,一个是 github ,一个是 npm 。
先看github的readme.md:
1.1 简介
顾名思义,这是一个把值进行“数组化”的工具包。
如果是想把既包含单一值又包含多个值的复合数组转换成一维数组(即对数组进行降维),可以用flat()(言外之意是本工具包不负责这个功能)。
1.2 安装
这个是在项目中引用包的方法。一般如果是仅在开发时会用到的包,那么就加上“--save-dev”,如果生产时也要用到,那就只加“--save”;此时,项目中会在package.json文件中的devDependencies或dependencies中带上arrify这个工具包,以便于与其他开发者下载安装依赖。
1.3 用法
这里给出了 5 个小例子,ariify分别将 字符串、数组、set、null、undefined 转换成数组格式。
其中,null和undefined会被转换成一个空数组。
github的readme.md到这里就看完了,接下来简单看下npm上发布的内容。
1.4 版本及依赖
这个工具包最近一次发布是一年前,版本号为3.0.0,不需要依赖其它包,有773个已发布的npm包依赖于这个arrify。目前共迭代了5个版本。
点开 Dependencies,会发现在开发时需要用到三个依赖包:ava、tsd、xo,这三个包都是在测试时用到,此处不详细展开,若感兴趣可点击包名到其官网查看详细介绍。
1.5 文件大小及下载量
最近一周下载量为两万多,包的实际大小为3.5kB,总共只有5个文件,如图所示:
2. 源码
从github上下载源码包到本地后,建议用vscode打开项目:
- .git开头的文件都是与git相关的配置文件。
- 在控制台运行
npm install命令后会生成node_modules文件夹,里面包含了上述提到的三个测试相关的开发环境依赖包。 - .editorconfig是和代码编辑器有关的配置文件,主要是为了代码格式规范。
- .ts文件是为了使用typescript的项目可以调用这些ts文件来进行类型检查。
- npmrc即npm running configuration, 即npm运行时配置文件。
上述都不是重点。
因为 readme 文件我们在github上已看过,这里只需关注 package.json、index.js、test.js这三个文件。
2.1 package.json
关于package.json配置的说明文档可以在官网上查阅👉:docs.npmjs.com/cli/v8/conf… & nodejs.org/api/package… 。
首先,打开这个文件后先看看有没有定义入口文件。常见入口文件定义字段有:main、module、exports等,这里是exports:
"exports": "./index.js",
如果是用VS Code打开项目,可以看到如下图所示的“▹调试”或“▹Debug”:
先执行 npm install ,安装完依赖包后,再移动鼠标到上述“▹调试”上,点击它,终端会自动执行命令 npm run test:
2.2 test.js
test.js是测试文件,具体方法参考ava的api👉:github.com/avajs/ava-d…
这里只有一个名为main的测试用例:
test('main', t => {
t.deepEqual(arrify('foo'), ['foo']);
t.deepEqual(arrify(new Map([[1, 2], ['a', 'b']])), [[1, 2], ['a', 'b']]);
t.deepEqual(arrify(new Set([1, 2])), [1, 2]);
t.deepEqual(arrify(null), []);
t.deepEqual(arrify(undefined), []);
const fooArray = ['foo'];
t.is(arrify(fooArray), fooArray);
});
- test():调用test方法来创建一个测试实例;
- deepEqual():“深相等”,类似深拷贝,进行的是值比较;
- is():两个值是否相同,这里比较的是fooArray是否指向同一个对象。
上述断言语句会顺序执行,如果有一个fail,则控制台就会输出difference,并终止测试。
在2.1节中我们运行了 npm run test 之后,可以看到控制台输出:
说明这个main的测试成功通过了。
2.3 index.js
这个文件里就是实现arrify的所有源码了,非常短:
export default function arrify(value) {
if (value === null || value === undefined) {
return [];
}
if (Array.isArray(value)) {
return value;
}
if (typeof value === 'string') {
return [value];
}
if (typeof value[Symbol.iterator] === 'function') {
return [...value];
}
return [value];
}
对于传入arrify的参数value,进行以下5种分类讨论:
- 如果是
null或undefined,则返回一个空数组; - 如果是Array类型数组,则返回value本身;
- 如果是字符串类型,则给这个字符串外面套一层,转为数组再返回;
- 如果value包含Symbol.iterator方法,说明其可迭代,比如一个可迭代对象,此时可将其元素迭代入一个数组种再返回;
- 除以上四种,直接在value外面套一层转数组返回。
⚠ 注意,这里的处理顺序不要轻易改变,否则可能出错,如可能出现typeof undefined[Symbol.iterator]的情景,此时会报错。
3. 总结
arrify的源码可以说是非常之少,只有短短十来行,非常新手友好。
通过本次源码学习,我们了解到了arrify的实现原理,是对传入参数进行5种类型判断,再对应进行数组化处理;同时,了解了可以在npm上直观地查看到与此相关的依赖包信息,以及源码的体积、版本、文件数等信息;了解了源码项目的大致结构;一般先看源码的Readme文件,作者会在这里对包进行必要的说明,比如功能、用法等;了解了package.json的入口文件、测试工具ava的基础用例写法等。