- 本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
- 这是源码共读的第36期,链接:传送门。
- 撰写日期 2023-07-30,源码 omit.js v2.0.2
查看源码库 README
安装 & 使用方式
npm i --save omit.js
var omit = require('omit.js');
omit({ name: 'Benjy', age: 18 }, [ 'name' ]); // => { age: 18 }
API
omit(obj: Object, fields: string[]): Object
只有一个方法,README 里 “Return a shallow copy which had dropped fields.” 这句话总结了其实现,就是对 obj
对象进行一层浅复制,然后遍历丢弃 fields
数组的属性。
查看 package.json
{
"main": "lib/index.js", // cjs 格式文件入口
"module": "es/index.js", // esm 格式文件入口
"types": "index.d.ts", // types
"scripts": {
"start": "father doc dev --storybook",
"build": "father doc build --storybook",
"compile": "father build",
"gh-pages": "father doc deploy",
"prepublishOnly": "npm run compile && np --yolo --no-publish",
"lint": "eslint .",
"test": "father test",
"coverage": "father test --coverage"
},
"devDependencies": {
"@umijs/fabric": "^2.2.2", // umijs 提供的 prettier、eslint、styelint 风格配置合集
"assert": "^1.4.1", // 单元测试断言
"eslint": "^7.4.0", // eslint 代码风格规范化
"father": "^2.29.5", // umijs的 npm 库开发工具,阿里系
"np": "^6.3.1", // 比官方 npm publish 更友好的 npm 包发布工具
"rc-tools": "^6.3.3" // ant-design 团队提供的 react-components 系列开发工具,维护已不活跃
}
}
father
从 package.json
的 scripts 可以看到,father 这个工具支撑了该仓库几乎全部 tasks,umijs 团队这个工具还是很强大的,最新版本(2023-07-30)具备以下特性:
![[Pasted image 20230730163813.png]]
我们执行 npm run compile
任务,会发现打包输出的产物,包含了 cjs 和 esm 两种模块化风格的产物(分别生成在 lib、es 目录),这些都是 father 工具内部支持的特性,只需要再 .fatherrc.js
文件添加配置即可
// .fatherrc.js
export default {
entry: ['src/index.js'], // 打包入口
cjs: 'babel', // cjs 模块风格打包
esm: { type: 'babel', importLibToEs: true }, // esm 模块风格打包
doc: { base: '/switch' }, // docz 文档配置
preCommit: {
eslint: true,
prettier: true,
},
};
单元测试用例
了解 omit.js 库的功能,可以先从其单元测试入手,因为这往往代表了这个库的 test-case 设计与边界场景,位于 tests/index.test.js
文件,使用 asserts 断言库进行单元测试:
import assert from 'assert';
import omit from '../src';
describe('omit', () => {
it('should create a shallow copy', () => {
const benjy = { name: 'Benjy' };
const copy = omit(benjy, []);
// 传递丢弃属性数组为空,判断是否原始对象与 omit 生成对象结构相同
assert.deepEqual(copy, benjy);
// 判断 omit 方法处理后,对象是否属于不同引用
assert.notEqual(copy, benjy);
});
it('should drop fields which are passed in', () => {
const benjy = { name: 'Benjy', age: 18 };
// 丢弃部部属性,判断是否原始对象与 omit 生成对象结构相同
assert.deepEqual(omit(benjy, ['age']), { name: 'Benjy' });
// 丢弃全部属性,判断是否原始对象与 omit 生成对象结构相同
assert.deepEqual(omit(benjy, ['name', 'age']), {});
});
});
omit 方法源码
function omit(obj, fields) {
// eslint-disable-next-line prefer-object-spread
const shallowCopy = Object.assign({}, obj)
for (let i = 0; i < fields.length; i += 1) {
const key = fields[i];
delete shallowCopy[key];
}
return shallowCopy;
}
代码是比较简单的,使用 Object.assign
进行对象的浅复制,然后遍历 fields
数组里的属性,在浅复制后的对象进行 delete 操作,从而将指定属性丢弃移除。但这个库是支持第一层的属性丢弃移除,嵌套深层次则无效。
总结
通过翻看 omit.js 源码库,学习了其代码构建实现,father 工具使用构建多模块化的产物,npm 包发布之前可以使用 prepublishOnly
钩子使用一些自定义任务, np 是更友好易用的 npm 包发布工具。