速读《现代 JavaScript 库开发》,快速掌握前端基础库开发逻辑
序
这是一个专门讲解 前端库 开发的一本书,如果你想要开发一个属于自己的库,或者想要了解库开发的技术,那么这本书肯定可以帮助到你。
前言
Hello
,各位小伙伴大家好,我是 Sunday
。
在现在的技术团队之中,我们普遍觉得,能够在 github
上开发和维护各种 库 的工程师都是 高手。
毕竟能够对企业项目提供底层支持的人,在技术领域总会存在一定的优越感。
那么开发一个库真的很难吗?其实不是的。
只要我们掌握了一定的 “方式和技巧” ,那么任何一名开发者都可以开发出属于自己的库。
《现代 JavaScript
库开发》是今年 1月(2023 年 1 月)
,最新发布的一本教我们如何开发一个 前端库 的书籍,作者是 颜海镜、候策。
作者在书中提到: “每一个开发者都拥有两个世界:1. 业务世界、 2. 开源世界。”
很多开发者非常熟悉业务世界,但是对开源世界却非常陌生。其实开源世界并没有那么神秘,我们只需要花费一点时间,就可以掌握进入开源世界大门的钥匙,甚至可以在里面自由翱翔。
那么下面,就让我们进入到 《现代 JavaScript
库开发》之中,一起来看看,开源世界是什么样子。
正文
对于整本书中的内容而言,我们先把第十二章排除在外。这样的话,整本书中内容共分为三个大部分,共十一个章节。
- 首先是第一大部分 原理:这一部分包含第一到第五章的内容,主要是讲解了我们应该如何 从零到一开发一个库。在这一块内容里面,作者从一个 深拷贝的
clone
库 开始,为我们讲解了一个库如何 开发、构建、测试、开源以及维护 的详细流程,以及注意事项。这一块内容,也是我们这次所讲解的一个重点。 - 第二大部分 技术:这一部分主要包含 第六、第七 两个章节,在这两个章节中,作者为我们介绍了
JavaScript 库
中 设计的最佳实践 以及 安全的最佳实践。整本书中内容也开始 从原理讲解逐步转化为实战操作。 - 第三大部分 实战:包含了从 第八章到第十一章 四个章节,这里就是一个纯实战环节,里面提供了 九个 不同类型的基础库构建代码,比如
jslib-base
,template.js
等等。里面会涉及到大量的代码,所以不在咱们这次的重点讲解范围之内。
最后就是 第十二章 ,这一章其实可以理解为 后置的前言。为什么这么说呢?因为在十二章中,作者提供了 知识全景图 和 技术全景图 这两个东西:
其中知识全景图,为我们描述了整本书中所涉及到的所有知识点。如图所示,我们可以知道整本书中所设计到的所有知识大体可以分为 4
类:
- 最佳实践
- 工程化
- 技术方案
- 开源
其中每一大类都分成了若干小类,而在每一个小类的前面都有一个数字,这个数字表示了 涉及到这一块知识点的章节。 比如:兼容性就分别在第二章和第六章中进行了涉猎。
接下来是技术全景图,在咱们的 脑图 中,我为每一个技术库都附上了对应的链接,大家可以直接点击链接跳转。整本书中涉及到的技术库也是分成了四大块:
- 构建
- 环境语言
- 测试
- 工具链
这些技术库在本书中会多次出现,所以我在这里截个图,把它钉在右上角位置。大家可以对照着来去看。
第一章:从零开发一个 JavaScript 库
那么明确好了,整个书中一个大体的逻辑之后,接下来咱们就来看一下 《第一章:从零开发一个 JavaScript 库》。
中国有句古话,叫做万事开头难,所以如果大家想要开发一个自己的 JavaScript 库
的话,那么开始的时候是最难的。
为此,作者为我们指定了 4
个步骤,来告诉我们应该如何开始构建一个自己的库:
想法
首先第一步叫做 我有一个想法:我们回忆自己到目前为止的职场生涯,有没有出现过 “我有一个想法” 这样的场景。
我相信大多数的小伙伴应该都会时不时的冒出过各种各样的想法,只不过可能很多想法冒出来之后,又被放弃掉了。放弃掉的原因可能有很多,但是 一个好的想法就是一个好的开始。
那么构建库同样如此,一个好的库一定是从一个好的想法开始的,所以当你有了一个好的想法之后,别着急放弃它,也许它可能帮助你走上职业的巅峰。
目标
当我们有了一个想法之后,那么我们其实就已经迈出了第一步了。接下来要做的就是 把这个想法,变成一个可以具体实现的目标。
这个目标并非要是 一成不变 的,它也并不一定要是一个多么宏大的目标。
它可以很小,也可以不断进行调整。就像 facebook
的创始人扎克伯克,在一开始创建 facebook(最初叫做 the facebook)
的时候,也只是想要做一个哈佛大学内部通讯系统。尤大(尤雨溪)在一开始构建 vue
的时候,也只是想做一个内部的小型视图渲染工具。
但是无论如何,这个目标一定要存在,因为只有有了目标之后,我们才可以有前进的动力。
设计
那么,当我们有了目标之后,接下来就是如何实现这个目标,也就是 设计。
所谓的设计,指的是 把目标进行拆解多个可以实现的小目标,让我们可以一步一步的往前走。通过设计,我们可以把一个朦胧的大目标变成多个可以具体落地的小目标。
这样的小目标,不光可以让我们对今后要做的事情认知更加清晰,还可以增强我们的信心,让我们不至于轻易放弃。
编码
万事具备之后,最后剩下的就是 编写代码 。
很多小伙伴,因为没有库开发经验,所以可能会 以写业务代码的逻辑去编写库代码。那么编写库代码有什么不同的地方,和注意事项呢?
这正是咱们后面要做的内容。
开发一个深拷贝的库
那么现在让我们从一个 深拷贝的库 做实验。
大家假想一下,现在我们有了一个 想法: 要做一个深拷贝的工具库。
同时我们为这个想法指定了 目标: 该库可以完成复杂数据类型的深拷贝。
然后我们针对该目标,进行了对应的 设计: 第一步要创建一个 clone
的函数,接收一个复杂数据类型作为参数,返回深拷贝之后的数据。
那么根据我们的设计,得出了如下代码:
function type(data) {
return Object.prototype.toString.call(data).slice(8, -1).toLowerCase()
}
function clone(source) {
const t = type(source);
if (t !== 'object' && t !== 'array') {
return source;
}
let target ;
if (t === 'object') {
target = {};
for(let i in source) {
if (source.hasOwnProperty(i)) {
target[i] = clone(source[i]); // 注意这里
}
}
} else {
target = [];
for(let i = 0; i < source.length; i++) {
target[i] = clone(source[i]); // 注意这里
}
}
return target;
}
那么现在,代码已经有了,并且代码是完全可用的。
但是大家要记住,现在我们要开发的是一个基础工具库,而这个库是要给其他的开发者进行使用的。
所以,如果代码仅仅只是如此的话,那么很快我们就会遇到一些问题:
- 小
A
使用了CommonJS
模块,但是不知道该如何引用这个库 - 小
B
说这个库在IE
浏览器上面会报错
这就是我们在实际库开发中,经常会遇到的 issue
身为库的开发者,那么这样的 issue
是我们必须要解决的。但是具体应该怎么做呢?
第二章:构建
出现以上两个问题的原因,本质上是因为库的构建方式导致的。所以想要让我们的代码可以被开发者成功引用,那么我们必须要了解一定的构建方案。
作者在第二章中,描述了前端库构建必备的基础知识,让我们从 模块化 开始来看一下。
模块化
目前的前端模块化分为两大类:
-
UMD
:UMD
内部主要包含两种AMD
:异步模块定义,适用于RequireJS
等模块加载器(用的已经不多了)CJS
:适用于Node
环境和其他打包工具
-
ESM(ES Module)
:主要适用于浏览器端环境
通常情况下以上两大类的模块化方案,可以适用于大多数的模块化场景。
除此之外,还有一个叫做 iife
的,它主要用来构建自执行函数,可以适用于 <script> 标签
导入的形式。
打包体系
明确好了现在常用的几种前端模块化方案之后,那么下面咱们来看下如何把项目打包成对应的模块化代码,也就是 打包体系。
现在常见的打包体系一共有三种 传统体系、Node
体系、工程化体系。
对于这三种体系而言,作者给出了具体的对比图:
Rollup
在实际的库开发中,最常用的就是 Rollup
进行打包。
作者在书中列举出了使用 Rollup
进行打包的流程,但是因为 Rollup
这种库存在升级的情况。所以为了避免在未来出现 Rollup
打包方式变化的问题,我在脑图中放了官网的文档链接,大家可以根据文档链接来查看最新的 Rollup
打包方式。
对于 Rollup
而言,除了可以完成基础的打包功能之外,还可以实现其他的功能。
比如,添加 banner 、treeshaking、以及 配合 babel 实现 ES5 兼容 。
以上四种书中提到的注意事项,我都为大家提供了对应的官方文档链接。大家可以按需进行查看。
第二章总结
那么到目前为止,我们已经把一个想法,变成了一个可以被开发者使用的基础库了。
但是大家需要注意的是,像我们这种基础库,将来可能会在很多的项目中被使用,所以为了自身的声誉考虑,我们必须要能够保证我们代码的严格质量。
那么这就要求,我们的代码需要通过多维度的单元测试才可以。那么单元测试怎么做呢?
第三章:测试
作者在第三章中提供了测试方案,其中主要以单元测试为主。内容大体为 如何设计测试用例、如何验证测试覆盖率、如何在浏览器环境中进行测试、已经如何进行自动化测试 这四部分。咱们来看一下。
首先,咱们先来了解下单元测试。单元测试可以被分为两大类:
TDD(测试驱动开发)
:所谓测试驱动开发,指的 是一种软件开发过程中的应用方法。 以 “戴两顶帽子” 作为开发方式:先戴上实现功能的帽子,在测试的辅助下,快速实现其功能;再戴上重构的帽子,在测试的保护下,通过去除冗余的代码,提高代码品质。
3.
BDD(行为驱动开发)
:而行为驱动开发指的 是一种敏捷软件开发的技术,它鼓励软件项目中的开发者、QA和非技术人员或商业参与者之间的协作。 BDD
的重点是 通过与利益相关者的讨论取得对预期的软件行为的清醒认识。
而我们接下来要说的就是 BDD(行为驱动开发)
的方案。
要完成 BDD(行为驱动开发)
书中为我们介绍了两个依赖库 1. 测试库 Mocha@3.5.3
、2. 断言库 expect.js@0.3.1
,为了避免库升级带来的不兼容性,我们在这里指定了对应的库版本。
Mocha 和 expect.js
基本使用流程,咱们这里不做过多介绍,官网和书上有详细的文档。
所以接下来咱们主要来看下保证质量的问题。作者在书中提到了测试质量保证的问题,主要分为 4
部分:
- 如何设计测试用例
- 如何验证测试覆盖率
- 如何在浏览器环境中进行测试
- 如何进行自动化测试
如何设计测试用例
测试用例的设计逻辑分为三部分:设计思路、编码方式、通过测试。
首先咱们先来看设计思路。当我们去设计一个测试用例时,需要遵循 以参数为组进行测试 的方案。
比如下面这段代码:
这段代码中包含三个参数,所以我们在设计测试用例的时候,就可以分成三组来进行测试,每个参数一组,在对一个参数进行测试时,保证其他参数无影响:
同样的道理,在我们之前的 clone 库
中,因为只包含一个参数,所以设计测试用例只需要分为一组即可:
明确好了设计思路之后,下面就可以写对应的编码内容:
var expect = require("expect.js");
var clone = require("../src/index.js").clone;
describe("function clone", function () {
describe("param data", function () {
it("正确用例", function () {
// 基本数据类型
expect(clone("abc")).to.equal("abc");
// 数组
var arr = [1, [2]];
var cloneArr = clone(arr);
expect(cloneArr).not.to.equal(arr);
expect(cloneArr).to.eql(arr);
// 对象
var obj = { a: { b: 1 } };
var cloneObj = clone(obj);
expect(cloneObj).not.to.equal(obj);
expect(cloneObj).to.eql(obj);
});
it("边界值用例", function () {
expect(clone(1)).to.equal(undefined);
expect(clone(undefined)).to.equal(undefined);
expect(clone(null)).to.equal(null);
});
});
});
这个代码是我从随书代码中截取下来的,给大家作为参考,代码内容咱们这里不做讨论。
有了代码之后,最后执行测试代码逻辑就可以了。
如何验证测试覆盖率
在设计完基础的测试用例之后,接下来我们还需要做一件非常重要的事情,那就是验证 单元测试覆盖率。因为对于单元测试而言,它的目的是 测试代码的运行情况。 所以我们必须要尽量保证 项目中的每行代码最好都被测试过一次,即覆盖率尽量去靠近100%
那么想要实现这一点,作者给我们推荐了一个工具 nyc(Istanbul) ,利用它可以帮助我们完成代码覆盖率测试。
其中每个维度代表的含义:
File
:文件Stmts
:语句覆盖率Branch
:分支覆盖率Funcs
:函数覆盖率Line
:行覆盖率uncovered line
:未覆盖的行号
如何在浏览器环境中进行测试
在前面的测试中主要是针对 Node.js
的环境进行的测试。但是很多时候我们可能需要借助浏览器环境来进行一些兼容性测试。
那么想要针对浏览器环境进行测试主要有两种方式:
-
第一种是 模拟浏览器场景:想要模拟浏览器场景测试,那么可以通过
mocha-jsdom
来完成。 -
第二章是 真实浏览器场景:
Mocha
支持在浏览器环境下运行,但是我们需要做一些事情才可以:- 首先,我们需要创建一个
index.html
文件,以方便在浏览器环境中运行 - 其次,因为浏览器环境中不包含
CJS
的require
方法,所以我们需要手动加上这个 “垫子”,即:添加一个require
函数,以防止出现require is not defined
的错误
- 首先,我们需要创建一个
如何进行自动化测试
到目前为止,其实我们已经拥有了一个完善的测试方案,但是美中不足的是 目前我们仍需人工在浏览器中打开并查看结果。
而对于 Chrome
浏览器而言,它提供了 Chrome Headless
的特性,我们可以在 Node
中借助 Puppeteer
工具,来直接启动 Chrome Headless
,以实现 自动化测试 的效果。从而无需人工在浏览器中打开并查看结果。
第三章总结
这一章,主要讲解了测试相关的逻辑,里面涉及到了很多测试相关的库或者工具。
针对于目前的前端测试场景而言,除了作者所提到的工具之外,还是一些其他的工具也有了很高的使用率,比如 单元测试库:Jest、UI 自动化测试框架:Cypress 等等......
对于没有测试经验的同学来说,这一章的内容可能会有些晦涩难懂。但是好处在于我们并不需要一次性的掌握作者所提到的所有内容,只需要关注自己当下的测试用例场景即可。
第四章:开源
代码写好了,测试通过了。那么接下来就是:发布自己的库,也就是 开源。
目前开源所指的主要有两部分:
- 将你的代码发布到
Github
上,以供开发者查阅和贡献源代码 - 将打包后的代码发布到
npm
上,以供开发者使用
但是当我们决定把代码进行开源时,也有一些坑,一个不慎可能也会给我们带来一些损失。作者在本章中,主要通过 4
个方面,来为我们介绍了开源的注意事项。
协议
首先第一个就是 开源协议。目前市面上常用的开源协议主要有三种 MIT、BSD、Apache
,这三协议的对比如下:
目前这三种协议都有很多开源库在使用,下面是影响力比较大的项目以及它们的开源协议:
对于我们的库而言,通常情况下选择 MIT
协议即可。
文档
除了协议之外,第二个是文档,文档主要分为 4
类:
- 首先是
README.md
:README.md
文档应该是大家最为熟悉的了。每一个Github
或npm
的库中,对当前库的介绍部分,就是README.md
文档 - 其次是
TODO.md
待办清单:它表示未来要添加的新功能和已经完成的新功能添加 - 然后是
变更日志:CHANGELOG.md
:它表示库更新的记录,每个版本的发布日期以及对应变化 - 最后就是
API 文档
:它介绍了当前库的一些基本用法。如果你的库比较简单,那么也可以把API 文档
合并在README.md
中
发布
当我们准备好协议、文档之后,下面我们就可以发布项目到 github
和 npm
了。
把项目发布到 github
的流程和我们平时提交 git
其实是一样的,如果大家不知道如何提交 git
的话,那么可以搜索一下对应的文档,咱们这里就不去多说了。
第二个是 npm
,把项目发布到 npm
的流程可能有很多小伙伴没有操作过,所以我在这里给大家放了一个 链接,在书中作者也对这个发布进行了介绍。
统计
整个开源最后一块是统计。当我们发布了一个库之后,其实都会非常关心开发者对它的使用情况。就像我发布了一个视频之后,也会经常来看看播放量一样。
因为我们在发布的时候,其实是发布到了 github
和 npm
两个不同的平台,所以在查看统计的时候,也需要根据不同的平台来进行查看。
首先是 github
,在 github
不存在使用率这样的情况,衡量一个库好不好的指标只有一个,那就是 star
。star 才是王道。
而对于 npm
而言,则存在下载量的概念。但是对于 npm
来说,它默认的统计只会统计从 npm i
的下载量。但是在国内很多小伙伴是使用淘宝镜像(cnpm
)来下载的,这部分流量它是统计不上去的。
所以说如果想要统计一个准确的下载数据,那么作者为我们提供了一种方式,就是 自定义统计。
npm
为每个命令都提供了两个钩子pre
和post
。比如,当我们使用
npm install
时,就存在preinstall
和postinstall
两个钩子,分别表示install
之前和install
之后。那么我们就可以依据这个钩子,来实现自定义统计:
- 在
postinstall
钩子中,指定执行文件
2. 在
postinstall.js
中通过axios
完成统计
那么按照如上方式,当开发者
npm install 库
之后,我们就可以手动记录一次下载数据。
第四章总结
在这一章中,作者主要讲解了我们去开源项目时的一些注意事项。整体算是比较简单。
那么到现在为止,我们就已经完成了 开发、构建、测试、发布 这四步流程了,也就是说,现在我们已经拥有了一个属于自己的基础库。
但是开源库发布成功,并不代表就万事大吉了。库的开源并不是一个一劳永逸的事情,它需要我们持续的迭代和维护。
所以接下来我们就来看看,我们应该如何维护一个开源库。
第五章:维护
整个库的维护,作者从 4
个方面进行了阐述。
社区协作
首先是社区协作,这里的社区主要指的就是 github
。而在 github
上的社区协作主要就是分为 3
种:
issue
- 代码贡献
- 捐赠
首先是 issue
,这个应该是大多数开发者最了解的一个东西了。它是 当前库的问题集合,大体可以分为三类 求助类:help wanted、故障类:bug、建议类:enhancement
。
身为库的开发者,对于 issue
必须要及时处理才可以。
当你的库在行业内拥有了一定的影响力之后,那么可能会有很多人为你的库贡献代码。贡献代码的人员可以大致被分为两类:非库开发人员 和 库开发人员。 非库开发人员主要通过 Fork + Pull Request
的方式进行代码贡献。而库开发人员则不需要那么麻烦。
最后是捐赠,这个一般很少,大家最好不要寄予过高的希望。
编码规范
在刚才我们说过,当你的库拥有一定的影响力之后,可能会有很多人为你的库进行代码贡献。
那么一旦涉及到多人的合作开发,那么我们就需要控制编码规范。书中为我们提到了很多编码规范的处理方案,其中会涉及到大量的代码和逻辑。所以我们在这里就不去说了。
在这里顺道给我在慕课网上的课程打一个广告,我在慕课网上发布过 全新升级,基于Vue3新标准,打造后台综合解决方案 这样一门课程,在这门课程中也详细了编码规范的问题,大家可以根据需要进行查看。
持续集成
完全依靠 Git hook
进行编码规范处理,有的时候可能并没有那么可靠。所以作者也在书中提到了持续集成的概念。
目前在开源社区中常用的持续集成工具主要有三款 Github Actions、CircleCI、Travis CI
。这三款都可以满足我们的开源需求,大家可以自行选择。
分支处理
最后就是 git
分支处理。
作者根据功能,把分支分为三类,分别是:
- 主分支:稳定、没有
bug
的代码,并保证随时可以发布的状态 - 功能分支:新功能开发时
- 故障分支:出现
bug
时
除此之外,还有两种特殊情况:
- 第一种是
Pull request
:它表示其他人给开源项目提交的代码。 在Github
上会提示我们如何进行操作,大多数时候确认无误,直接合并即可。 - 第二种是
创建标签与历史
:这个主要针对于发布新版本,或者特殊版本时的场景。主要用来记录当前的版本意义。
第五章总结
那么到这里为止,我们就已经讲完了从零开发一个库的流程以及注意事项,其中涉及到 开发、构建、测试、发布、维护 的一整套流程。
那么掌握到这里为止,其实大家就已经可以利用上述知识完成一个基础库的开发了。
但是如果你想要做的更好,并且可以及时规避一些风险的话,那么可以继续往下看。
第六章:设计更好的JavaScript库
从这一章开始,我们将会去讲解 开源库中的注意事项与风险点,以帮助大家更好地规避风险,从而设计更好的JavaScript
库,取得最大收益。
那么首先咱们来看一下,如何构建出一个更好地 JS
库。想要构建出一个更好的 JS
库,那么作者给出了 4
个方向 函数化、健壮性、兼容性、TS ,咱们一个一个来说。
函数很重要
其实我们在之前的时候说过很多次,函数在 JS
中被称之为第一公民。那么想要构建出一个可维护性更强的 JS
库,咱们就需要好好利用函数。
作者从两个维度对函数进行了介绍。
- 首先是 命名:函数的命名以 见名知意 为第一要素,尽量不要使用 “少为人知”的缩写,如果不知道如何为函数命名,可以试用下 CodeIf (速度可能会有点慢)
- 其次是 参数:作者在书中提到,参数的个数最好不要超过三个。如果你确实需要很多参数的话,那么可以使用
options
的模式,这种方式我们之前在 JavaScript 语言精粹 中也提到过
提高健壮性
开源库和业务代码的一个很大的不同在于 开源库会被很多人使用,会在各种各样业务场景中运行。根据使用者的不同,开源库的代码会比普通的业务代码存在更多的健壮性问题。
这个健壮性指的是:程序在遇到规范以外的输入,错误和异常时,仍能正常运行。
在这一小节中,作者分别从 参数防御、副作用处理、异常捕获 三个方面进行了描述。
参数防御
所谓参数防御指的是 使用者,未按照约定,传入了预料之外的参数。 那么在这种情况下,作为开源库的开发者就要通过 参数防御 的形式,保证程序不会出现崩溃的问题。
副作用处理
所谓副作用指的是:会引起副作用的代码。比如:
let name = '张三'
function setName (newName) {
name = newName
}
在这段代码中,setName
方法的触发就会修改 全局变量 name
的值。此时的 setName
就被叫做会引起副作用的代码,也就是一个 副作用函数
。
而对于库中的代码而言,如果会引起大量的副作用,那么就会给使用者带来很大的麻烦。
异常捕获
程序在运行的过程中出现异常是非常正常的事情。但是这些异常的报错需要给用户明确的提示才可以。
浏览器兼容
再往后是浏览器兼容的问题。作者在这里给出了一个推荐的浏览器兼容目标,这个兼容目标是非常低的。大家可以根据自己的情况来选择。
TypeScript
最后就是 TypeScript
。在现在的库开发中,个人建议大家都应该使用 TypeScript
,因为它可以在维护时,带来更高的可维护性。
第七章:安全防护
第七章主要介绍了安全防护的问题。这里的安全防护指的是 库代码的安全性。
作者在这一章中,举了一个例子:
2019 年的时候
Lodash
库爆出过一个原型污染漏洞,叫做CEV-2019-10744
。这个漏洞主要存在于
Lodash
的defaultsDeep
方法中,这个方法会将第二个参数的可枚举属性合并到第一个参数的属性上。但是如果我们按照这样的方式传递参数的话,就会出现原型污染的问题
而要想理解什么是原型污染,大家需要首先搞清楚
JS
中原型链的概念,我在这里截了一张图:
这张图描述了 JS
中原型链的逻辑。
由此可知一旦我们修改了顶层的原型对象,那么就会响应到所有的底层对象实例。
而如果想要避免这种问题的出现,那么作者给出了 4
种方案:
- 利用
Object.freeze
冻结Object.prototype
- 规避不安全的递归
- 利用
Object.create(null)
规避,因为这样实例不会连接到Object.prototype
. - 利用
Map
代替{}
,从而避免原型链接的问题
除此之外,作者还在本章中提到了 依赖的安全性问题 的问题,所谓的依赖安全性指的是 你的库所依赖的其他库,是否是安全的。
作者给我们提供了 4 个维度,来尽量保证依赖安全性:
- 首先第一点是:尽量选择
star 多
、issue 少,且处理及时
的库,进行依赖。 - 第二是:对库依赖的区分,主要说明了 dependencies:生产与开发环境、devDependencies:开发环境、peerDependencies:库依赖于其他的库 三者之间的区别
- 第三是版本区分:依赖库版本号和前缀的概念
- 最后是一个安全检查的命令
安全检查:npm audit
最后在本章中,作者还介绍了一些 防护意外 的处理逻辑,所谓的意外防护指的是 避免使用者修改库内部的属性,大体分为三类:
- 不相关的功能不应该对外暴露
- 最小的参数设计
- 属性冻结
第七章总结
那么到这里为止,库开发的注意事项与风险点,咱们就说的差不多了。
第八章 - 第十一章
在第八章到第十一章的内容中,作者主要介绍了 9
个基础库的实现,所以这 4 个章节可以被叫做 实战 环节。
实战环节中,涉及到了大量的代码内容,其中理论相关的东西就比较少了。
如果大家对这一块的代码比较感兴趣的话,那么可以看一下具体书中所写的内容。
总结
OK
,那么到这里咱们整个的《现代 JavaScript
库开发》就已经全部说完了。
《现代 JavaScript
库开发》 是一个非常适合想要开发开源库的同学进行学习的书籍。里面涉及到的很多内容,会让刚进入该领域的同学少走很多的弯路。
转载自:https://juejin.cn/post/7206732474113409079