從 vue-cli 源碼中,我發現了27行讀取 json 文件有趣的 npm 包

1. 前言

大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。已進行四個月了,很多小伙伴表示收獲頗豐。

想學源碼,極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。

本文倉庫 https://github.com/lxchuan12/read-pkg-analysis.git,求個star^_^[1]

源碼共讀活動?每周一期,已進行到15期。源碼群里有小伙伴提問,如何用?import?加載?json?文件。同時我之前看到了vue-cli 源碼?里有?read-pkg?這個包。源碼僅27行,非常值得我們學習。

閱讀本文,你將學到:

1.?如何學習調試源碼
2.?學會如何獲取?package.json
3.?學到?import.meta?
4.?學到引入?json?文件的提案
5.?JSON.parse?更友好的錯誤提示
6.?規范化?package?元數據
7.?等等

2. 場景

優雅的獲取 package.json 文件。

read-pkg[3]

vue-cli 源碼[4]

const?fs?=?require('fs')
const?path?=?require('path')
const?readPkg?=?require('read-pkg')exports.resolvePkg?=?function?(context)?{if?(fs.existsSync(path.join(context,?'package.json')))?{return?readPkg.sync({?cwd:?context?})}return?{}
}

封裝這個函數的commit 記錄[5]

你也許會想直接 require('package.json'); 不就可以了。但在ES模塊下,目前無法直接引入JSON文件。

在 stackoverflow 也有相關提問[6]

我們接著來看 阮一峰老師的 JSON 模塊[7]

import 命令目前只能用于加載 ES 模塊,現在有一個提案[8],允許加載 JSON 模塊。import 命令能夠直接加載 JSON 模塊以后,就可以像下面這樣寫。

import?configData?from?'./config.json'?assert?{?type:?"json"?};
console.log(configData.appName);

import 命令導入 JSON 模塊時,命令結尾的 assert {type: "json"} 不可缺 少。這叫做導入斷言,用來告訴 JavaScript 引擎,現在加載的是 JSON 模塊。

接下來我們學習 read-pkg 源碼[9]

3. 環境準備

3.1 克隆

#?推薦克隆我的項目,保證與文章同步
git?clone?https://github.com/lxchuan12/read-pkg-analysis.git
#?npm?i?-g?yarn
cd?read-pkg?&&?yarn
#?VSCode?直接打開當前項目
#?code?.#?或者克隆官方項目
git?clone?https://github.com/sindresorhus/read-pkg.git
#?npm?i?-g?yarn
cd?read-pkg?&&?yarn
#?VSCode?直接打開當前項目
#?code?.

看源碼一般先看 package.json,再看 script

3.2 package.json

{"name":?"scripts":?{"test":?"xo?&&?ava?&&?tsd"}
}

test命令有三個包,我們一一查閱了解。

xo[10]

JavaScript/TypeScript linter (ESLint wrapper) with great defaults JavaScript/TypeScript linter(ESLint 包裝器)具有很好的默認值

tsd[11]

Check TypeScript type definitions 檢查 TypeScript 類型定義

nodejs 測試工具 ava[12]

Node.js test runner that lets you develop with confidence

3.3 調試

提前在入口測試文件 test/test.js 和入口文件 index.js 打好斷點。

用最新的VSCode 打開項目,找到 package.jsonscripts 屬性中的 test 命令。鼠標停留在test命令上,會出現 運行命令調試命令 的選項,選擇 調試命令 即可。

調試如圖所示:

b97c94af1ca17f735dcdf59f9b4aafad.png
debugger

更多調試細節可以看我的這篇文章:新手向:前端程序員必學基本技能——調試JS代碼

我們跟著調試來看測試用例。

4. 測試用例

這個測試用例文件,主要就是主入口 index.js 導出的兩個方法 readPackage, readPackageSync。異步和同步的方法。

判斷讀取的 package.jsonname 屬性與測試用例的 name 屬性是否相等。

判斷讀取 package.json_id 是否是真值。

同時支持指定目錄。{ cwd }

//?read-pkg/test/test.js
import?{fileURLToPath}?from?'url';
import?path?from?'path';
import?test?from?'ava';
import?{readPackage,?readPackageSync}?from?'../index.js';const?dirname?=?path.dirname(fileURLToPath(import.meta.url));
process.chdir(dirname);
const?rootCwd?=?path.join(dirname,?'..');test('async',?async?t?=>?{const?package_?=?await?readPackage();t.is(package_.name,?'unicorn');t.truthy(package_._id);
});test('async?-?cwd?option',?async?t?=>?{const?package_?=?await?readPackage({cwd:?rootCwd});t.is(package_.name,?'read-pkg');
});test('sync',?t?=>?{const?package_?=?readPackageSync();t.is(package_.name,?'unicorn');t.truthy(package_._id);
});test('sync?-?cwd?option',?t?=>?{const?package_?=?readPackageSync({cwd:?rootCwd});t.is(package_.name,?'read-pkg');
});

這個測試用例文件,涉及到一些值得一提的知識點。接下來就簡單講述下。

4.1 url 模塊

url 模塊提供用于網址處理和解析的實用工具。

url 中文文檔[13]

url.fileURLToPath(url)

url|要轉換為路徑的文件網址字符串或網址對象。返回:完全解析的特定于平臺的 Node.js 文件路徑。此函數可確保正確解碼百分比編碼字符,并確保跨平臺有效的絕對路徑字符串。

4.2 import.meta.url

import.meta.url[14]

(1)import.meta.url import.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[15] 解析 json 文件。

用 npm 官方庫 normalize-package-data[16] 規范化 package 元數據。

import?process?from?'node:process';
import?fs,?{promises?as?fsPromises}?from?'node:fs';
import?path?from?'node:path';
import?parseJson?from?'parse-json';
import?normalizePackageData?from?'normalize-package-data';export?async?function?readPackage({cwd?=?process.cwd(),?normalize?=?true}?=?{})?{const?filePath?=?path.resolve(cwd,?'package.json');const?json?=?parseJson(await?fsPromises.readFile(filePath,?'utf8'));if?(normalize)?{normalizePackageData(json);}return?json;
}export?function?readPackageSync({cwd?=?process.cwd(),?normalize?=?true}?=?{})?{const?filePath?=?path.resolve(cwd,?'package.json');const?json?=?parseJson(fs.readFileSync(filePath,?'utf8'));if?(normalize)?{normalizePackageData(json);}return?json;
}

5.1 process 進程模塊

很常用的模塊。

process 中文文檔[17]

process 對象提供有關當前 Node.js 進程的信息并對其進行控制。雖然它作為全局可用,但是建議通過 require 或 import 顯式地訪問它:

import?process?from?'node:process';

Node 文檔[18]

也就是說引用 node 原生庫可以加 node: 前綴,比如 import util from 'node:util'

5.2 path 路徑模塊

很常用的模塊。

path 中文文檔[19]

path 模塊提供了用于處理文件和目錄的路徑的實用工具。

5.3 fs 文件模塊

很常用的模塊。

fs 中文文檔[20]

5.4 parseJson 解析 JSON

parse-json[21]

文檔介紹:

Parse JSON with more helpful errors

更多有用的錯誤提示。

//?源碼有刪減
const?fallback?=?require('json-parse-even-better-errors');
const?parseJson?=?(string,?reviver,?filename)?=>?{if?(typeof?reviver?===?'string')?{filename?=?reviver;reviver?=?null;}try?{try?{return?JSON.parse(string,?reviver);}?catch?(error)?{fallback(string,?reviver);throw?error;}}?catch?(error)?{//?省略}
}

5.5 normalizePackageData 規范化包元數據

npm 官方庫 normalize-package-data[22]

normalizes package metadata, typically found in package.json file.

規范化包元數據

module.exports?=?normalize
function?normalize?(data,?warn,?strict)?{//?省略若干代碼data._id?=?data.name?+?'@'?+?data.version
}

這也就是為啥測試用例中用了t.truthy(package_._id); 來檢測 _id 屬性是否為真值。

6. 總結

最后總結下我們學到了如下知識:

1.?如何學習調試源碼
2.?學會如何獲取?package.json
3.?學到?import.meta?
4.?學到引入?json?文件的提案
5.?JSON.parse?更友好的錯誤提示
6.?規范化?package?元數據
7.?等等

read-pkg 源碼[23] 整體而言相對比較簡單,但是也有很多可以學習深挖的學習的知識點。

作為一個 npm 包,擁有完善的測試用例。

Node.js 可以多找找簡單的 npm 包學習。比直接看官方文檔有趣多了。不懂的就去查官方文檔。查的多了,自然常用的就熟練了。

建議讀者克隆 我的倉庫[24] 動手實踐調試源碼學習。

最后可以持續關注我@若川。歡迎加我微信 ruochuan12 交流,參與 源碼共讀 活動,大家一起學習源碼,共同進步。

參考資料

[1]

本文倉庫 https://github.com/lxchuan12/read-pkg-analysis.git,求個star^_^: https://github.com/lxchuan12/read-pkg-analysis.git

[2]

read-pkg: https://npm.im/read-pkg

更多點擊閱讀原文查看


最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進群。

推薦閱讀

整整4個月了,盡全力組織了源碼共讀活動~
我歷時3年才寫了10余篇源碼文章,但收獲了100w+閱讀

老姚淺談:怎么學JavaScript?

我在阿里招前端,該怎么幫你(可進面試群)

44df9c902c49a880dd1a64140417bef7.gif

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》10余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助1000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。

a41daafa7be6f542d3ea5d066bbafa7d.png

識別方二維碼加我微信、拉你進源碼共讀

今日話題

略。分享、收藏、點贊、在看我的文章就是對我最大的支持~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/news/275142.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275142.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275142.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

自定義view示例_自定義404頁的10個示例(從最佳到最差)

自定義view示例自定義404頁面 (Custom 404 pages) To customize or not to customize your 404 page? I hope by now you know the answer is that, yes, under essentially all circumstances you should customize your 404 page. 404 errors occur when someone attempts t…

BTF:實踐指南

本文地址:BTF:實踐指南 | 深入淺出 eBPF 1. BPF 的常見限制 1.1 調試限制1.2 可移植性2. BTF 是什么?3. BTF 快速入門 3.1 BPF 快速入門3.1 BTF 和 CO-RE4. 結論 BPF 是 Linux 內核中基于寄存器的虛擬機,可安全、高效和事件驅動…

python 混入類MixIn

寫在前面 能把一件事情說的那么清楚明白,感謝廖雪峰的官方網站。 1.為什么要用混入類?(小白入門) 繼承是面向對象編程的一個重要的方式,因為通過繼承,子類就可以擴展父類的功能。 step1: 回憶一下Animal類層…

關于字符串流的學習(c++)

/* 字符串流 在字符數組中可以存放字符,也可以存放整數、浮點數以及其他類型的數據。在向字符數組存入數據之前,要先將數據從二進制形式轉換為ASCII代碼,然后存放在緩沖區,再從緩沖區送到字符數組。從字符數組讀數據時,先將字符數組中的數據送到緩沖區,在賦給變量前要先將ASCII…

估計很多前端都沒學過單元測試~

大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。已進行四個月了,很多小伙伴表示收獲頗豐。想學源碼,極力推薦訂閱我寫的《學習…

xd可以用ui動效效果嗎_通過動畫使UI設計栩栩如生:Adobe XD和After Effects

xd可以用ui動效效果嗎Note — If you don’t fancy splashing out on an Adobe license, you can trial their products for 14 days each. That should give you more than enough time to play, check it out.注意—如果您不愿意花錢購買Adobe許可證,則可以分別試…

BookMarklet:瑞士軍刀你用了嗎?

Bookmarklet 是一段隱藏在鏈接后面的js代碼,可以收藏在收藏夾。通過這段代碼,我們可以跨瀏覽器(當然,也跨平臺)實現一些工具。比起瀏覽器插件來說,使用更加方便。典型的,dict.cn 網站的工具和有…

第十二周編程總結

這個作業屬于那個課程C語言程序設計II這個作業要求在哪里https://pintia.cn/problem-sets/1127748174659035136/problems/1127749414029729792我在這個課程的目標是更好的學習函數這個作業在那個具體方面幫助我實現目鍛煉了我的編程能力參考文獻c語言程序設計26-1 計算最長的字…

可能是全網首個前端源碼共讀活動,誠邀加入學習

大家好,我是若川。從8月份到現在11月結束了。每周一期,一起讀200行左右的源碼,撰寫輔助文章,截止到現在整整4個月了。由寫有《學習源碼整體架構系列》20余篇的若川【若川視野公眾號號主】傾力組織,召集了各大廠對于源碼…

現代游戲中的UX趨勢

ux設計中的各種地圖游戲UX (GAMES UX) Even though websites and games have matured side-by-side over the past few decades, games have a long and detailed history of user experience. Sure, it was scrappy and fairly rudimentary initially, but the only way you c…

SQL Server 2008 安裝過程中遇到“性能計數器注冊表”..

Windows 2008 系統 SQL Server 2008 性能計數器注冊表作者: 來源: 時間:2010-6-13 完美集成、增強 KindEditor HTML 編輯器今天跟隨部門老大去現場學習,安裝 Windows208 下 SQL Server2008&#xff0c…

你提交代碼前沒有校驗?巧用gitHooks解決

大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。已進行四個月了,很多小伙伴表示收獲頗豐。想學源碼,極力推薦訂閱我寫的《學習…

Linux下自動化測試環境的搭建

1.安裝Linux虛擬機,詳情參考 https://blog.csdn.net/qq_22770715/article/details/78558374 https://www.cnblogs.com/Q277227/p/8176564.html 1.1 需要確定IP ,使用 ifconfig 1.2 linux的用戶名跟密碼; 1.3 確定可以遠程ssh登錄&…

code craft_以Craft.io為先—關于我們行業的實踐職業道路的系列

code craft重點 (Top highlight)For the past two decades, digital product design / UX has been shifting to become a more strategic discipline within organizations. Partially because business leaders have started to pay attention to how design-driven companie…

Nginx+httpd反代實現動靜分離

什么是動靜分離為了提高網站的響應速度,減輕程序服務器(apachephp,nginxphp等)的負載,對于靜態資源比如圖片,js,css,html等靜態文件,我們可以在反向代理服務器中設置&…

(建議收藏)前端面試必問的十六條HTTP網絡知識體系

大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。已進行四個月了,很多小伙伴表示收獲頗豐。想學源碼,極力推薦訂閱我寫的《學習…

了解 DB2 Version 9.5 中的全局變量(轉)

轉自:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0711zubiri/ 簡介 在關系數據庫系統內部,應用程序和實際數據庫之間的主要交互都是以會話或連接的 SQL 語句形式來實現的。過去,為了在相同會話中實現不同 SQL 語句之…

jQuery新版本加載json注意事項。

jQuery在1.4版本后,采用了更為嚴格的json解析方式,所以所有內容都必須要有雙引號。比如以前{key:”28CATEGORY”,status:”0″}是沒問題的。但升級成1.4后,都必須加上雙引號:{“key” : “28CATEGORY”,“status” : “0″}如果你…

多邊形的時針方向與法線方向

從相反的法線方向觀察,順時針還是逆時針是相反的。 多邊形的時針方向與法線方向的關系呈右手法則關系。 GoogleEarth中的面具有時針方向,法線方向為正向,反之為負向 GoogleEarth的垂面在法線方向為亮色,反向為暗色 GoogleEarth的水…

裂墻推薦!再也不用求后端給接口了...

大家好,我是若川。今天咱們來介紹一款強大的云服務平臺!MemFire Cloud注冊即享5GB存儲空間、每月100萬讀額度和每月10萬寫額度。平臺入口:https://memfiredb.com/今天(12月10號)還有限時的送書活動!感興趣的…