从 vue-cli 源码中,我发现了 27 行读取 json 文件有趣的 npm 包
1. 前言
大家好,我是若川。为了能帮助到更多对源码感兴趣、想学会看源码、提升自己前端技术能力的同学。我倾力组织了源码共读活动,已进行 4 个月,每周大家一起学习 200 行左右的源码,共同进步,很多人都表示收获颇丰。
想学源码,极力推荐关注我写的专栏(目前 1.8K 人关注)《学习源码整体架构系列》 包含jQuery
、underscore
、lodash
、vuex
、sentry
、axios
、redux
、koa
、vue-devtools
、vuex4
、koa-compose
、vue 3.2 发布
、vue-this
、create-vue
、玩具vite
等 20 余篇源码文章。
本文仓库 https://github.com/lxchuan12/read-pkg-analysis.git,求个star^_^
源码共读活动 每周一期,已进行到 15 期。源码群里有小伙伴提问,如何用 import
加载 json
文件。同时我之前看到了vue-cli 源码 里有 read-pkg 这个包。源码仅 27 行,非常值得我们学习。
阅读本文,你将学到:
2. 场景
优雅的获取 package.json
文件。
封装这个函数的commit 记录
你也许会想直接 require('package.json');
不就可以了。但在ES模块
下,目前无法直接引入 JSON 文件。
我们接着来看 阮一峰老师的 JSON 模块
import 命令目前只能用于加载 ES 模块,现在有一个提案,允许加载 JSON 模块。import 命令能够直接加载 JSON 模块以后,就可以像下面这样写。
import
命令导入JSON
模块时,命令结尾的assert {type: "json"}
不可缺少。这叫做导入断言,用来告诉JavaScript
引擎,现在加载的是JSON
模块。
接下来我们学习 read-pkg 源码。
3. 环境准备
3.1 克隆
看源码一般先看 package.json
,再看 script
。
3.2 package.json
test 命令有三个包,我们一一查阅了解。
JavaScript/TypeScript linter (ESLint wrapper) with great defaultsJavaScript/TypeScript linter(ESLint 包装器)具有很好的默认值
Check TypeScript type definitions 检查 TypeScript 类型定义
Node.js test runner that lets you develop with confidence
3.3 调试
提前在入口测试文件 test/test.js
和入口文件 index.js
打好断点。
用最新的VSCode
打开项目,找到 package.json
的 scripts
属性中的 test
命令。鼠标停留在test
命令上,会出现 运行命令
和 调试命令
的选项,选择 调试命令
即可。
调试如图所示:
更多调试细节可以看我的这篇文章:新手向:前端程序员必学基本技能——调试JS代码
我们跟着调试来看测试用例。
4. 测试用例
这个测试用例文件,主要就是主入口 index.js
导出的两个方法 readPackage
, readPackageSync
。异步和同步的方法。
判断读取的 package.json
的 name
属性与测试用例的 name
属性是否相等。
判断读取 package.json
的 _id
是否是真值。
同时支持指定目录。{ cwd }
这个测试用例文件,涉及到一些值得一提的知识点。接下来就简单讲述下。
4.1 url 模块
url 模块提供用于网址处理和解析的实用工具。
url.fileURLToPath(url)
url <URL> | <string> 要转换为路径的文件网址字符串或网址对象。返回: <string> 完全解析的特定于平台的 Node.js 文件路径。此函数可确保正确解码百分比编码字符,并确保跨平台有效的绝对路径字符串。
4.2 import.meta.url
(1)import.meta.urlimport.meta.url 返回当前模块的 URL 路径。举例来说,当前模块主文件的路径是
https://foo.com/main.js
,import.meta.url 就返回这个路径。如果模块里面还有一个数据文件data.txt
,那么就可以用下面的代码,获取这个数据文件的路径。new URL('data.txt', import.meta.url)注意,Node.js 环境中,import.meta.url
返回的总是本地路径,即是 file:URL 协议的字符串,比如file:///home/user/foo.js
。
4.3 process.chdir
process.chdir()
方法更改 Node.js
进程的当前工作目录,如果失败则抛出异常(例如,如果指定的 directory
不存在)。
5. 27 行主入口源码
导出异步和同步的两个方法,支持传递参数对象,cwd
默认是 process.cwd()
,normalize
默认标准化。
分别是用 fsPromises.readFile
fs.readFileSync
读取 package.json
文件。
用 parse-json 解析 json 文件。
用 npm 官方库 normalize-package-data 规范化 package
元数据。
5.1 process 进程模块
很常用的模块。
process 对象提供有关当前 Node.js 进程的信息并对其进行控制。 虽然它作为全局可用,但是建议通过 require 或 import 显式地访问它:
也就是说引用 node
原生库可以加 node:
前缀,比如 import util from 'node:util'
5.2 path 路径模块
很常用的模块。
path 模块提供了用于处理文件和目录的路径的实用工具。
5.3 fs 文件模块
很常用的模块。
5.4 parseJson 解析 JSON
文档介绍:
Parse JSON with more helpful errors
更多有用的错误提示。
5.5 normalizePackageData 规范化包元数据
npm 官方库 normalize-package-data
normalizes package metadata, typically found in package.json file.
规范化包元数据
这也就是为啥测试用例中用了t.truthy(package_._id);
来检测 _id
属性是否为真值。
6. 总结
最后总结下我们学到了如下知识:
read-pkg 源码 整体而言相对比较简单,但是也有很多可以学习深挖的学习的知识点。
作为一个 npm 包,拥有完善的测试用例。
学 Node.js
可以多找找简单的 npm
包学习。比直接看官方文档有趣多了。不懂的就去查官方文档。查的多了,自然常用的就熟练了。
建议读者克隆 我的仓库 动手实践调试源码学习。
版权声明: 本文为 InfoQ 作者【若川】的原创文章。
原文链接:【http://xie.infoq.cn/article/d2f0b0c26a30fedb14787c8d1】。文章转载请联系作者。
评论