【会员源码共读】02 - arrify

107 阅读2分钟

「我正在参与掘金会员专属活动-源码共读第一期,点击参与

用途

转换任意value为数组

import arrify from 'arrify';

arrify('🦄');
//=> ['🦄']

arrify(['🦄']);
//=> ['🦄']

arrify(new Set(['🦄']));
//=> ['🦄']

arrify(null);
//=> []

arrify(undefined);
//=> []

准备工作

git clone <https://github.com/sindresorhus/arrify>

cd ./arrify && code .

npm i

查看package.json

首先查看几个重要的字段

"type": "module", //指定了本仓库为 es module
"exports": "./index.js", // 入口文件
"scripts": {
		"test": "xo && ava && tsd"
	},
"devDependencies": {
		"ava": "^3.15.0", // 代码测试
		"tsd": "^0.14.0", // ts测试
		"xo": "^0.39.1" // 基于 eslint 的 0 配置格式检测工具
	}

能执行的scripts只有test ,并且所有的依赖就在这条命令中

这里连续执行了3个任务,&& 是继发执行(前一个任务完成才能执行下一个)这是bash的功能

"scripts": {
		"test": "xo && ava && tsd"
	},

源码分析

根据package.json 找到入口文件index.js,所有的源码就在index.js 中,一共就十来行,短小精悍

//3.0.0-latest
export default function arrify(value) {
	if (value === null || value === undefined) { // #1
		return [];
	}

	if (Array.isArray(value)) { // #2
		return value;
	}

	if (typeof value === 'string') { // #3
		return [value];
	}

	if (typeof value[Symbol.iterator] === 'function') { // #4
		return [...value];
	}

	return [value]; // #5
}
  1. 特殊处理了nullundefined,返回空数组[]

  2. 如果value本身就是数组,直接返回

  3. 如果value是字符串类型,返回[value]

    1. 之所以要单独处理字符串,是因为字符串也部署了Symbol ,如果不处理,则会解构字符串,而不是预期的返回[value]
  4. 如果部署了Symbol ,则value是一个可迭代对象,通过 消费迭代器,返回结构化后的数组[…value]

  5. 其他情况返回[value]

查看 git提交记录

源码不多的同时,提交记录也不多,正好可以学习下开源的项目是如何演变的

根据提交记录可以看出:

  1. 2.0.0 的时候增加了迭代器的支持
  2. 2.0.1 增加了ts的类型提示
  3. 3.0.0 项目转为了es风格

1.0.0实现了基本功能后,再逐步完善项目

image.png

v1.0.1


//1.0.1
'use strict';
module.exports = function (val) {
if (val === null || val === undefined) {
		return [];
	}

	return Array.isArray(val) ? val : [val];
};

此时还未支持部署了Symbol的值,并且项目是commonjs 风格

v2.0.0

//2.0.0
'use strict';

const 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];
};

module.exports = arrify;

2.0.0 已经是现在所看到的样子了

<完>