從 vue3 和 vite 源碼中,我學到了一行代碼統一規范團隊包管理器的神器

1. 前言

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

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

本文倉庫 only-allow-analysis,求個star^_^[1]

最近組織了源碼共讀活動,每周大家一起學習200行左右的源碼。每周一期,已進行到14期。于是搜尋各種值得我們學習,且代碼行數不多的源碼。

閱讀本文,你將學到:

1.?如何學習調試源碼
2.?學會?npm?鉤子
3.?學會?"preinstall":?"npx?only-allow?pnpm"?一行代碼統一規范包管理器
4.?學到?only-allow?原理
5.?等等

2. 場景

我們項目開發時,常需要安裝依賴,雖說一般用文檔可以說明。但不是比較強制的約束。是人就容易犯錯或者疏忽,假如規定是用的npm,而團隊里有人某一天不小心使用了其他包管理器安裝了的其他依賴,上傳了代碼,嚴重時可能導致線上問題。所以我們需要借助工具(代碼)來強制約束。

在源碼共讀第12期[2]中,我們學習了尤雨溪推薦神器 ni ,能替代 npm/yarn/pnpm ?簡單好用!源碼揭秘!根據鎖文件自動匹配相應的包管理器,運行相應的命令。

在源碼共讀第3期[3]中,我們學習了Vue 3.2 發布了,那尤雨溪是怎么發布 Vue.js 的?

其中 Vue3 源碼用了 npm 的 preinstall 鉤子[4] 約束,只能使用 pnpm 安裝依賴。我們接著來看其實現。

3. Vue3 源碼 && npm 命令鉤子

//?vue-next/package.json
{"private":?true,"version":?"3.2.22","scripts":?{"preinstall":?"node?./scripts/preinstall.js",}
}
依次執行
#?install?之前執行這個腳本
preinstall
#?執行?install?腳本
install
#?install?之后執行這個腳本
postinstall

當然也支持自定義的命令。

更多可以查看官方文檔鉤子[5]

接著我們來看 preinstall[6] 源碼。

//?vue-next/scripts/preinstall.jsif?(!/pnpm/.test(process.env.npm_execpath?||?''))?{console.warn(`\u001b[33mThis?repository?requires?using?pnpm?as?the?package?manager?`?+`?for?scripts?to?work?properly.\u001b[39m\n`)process.exit(1)
}

這段代碼也相對簡單,校驗如果不是 pnpm 執行腳本則報錯,退出進程。

關于 process 對象可以查看 阮一峰老師 process 對象[7]

process.argv 屬性返回一個數組,由命令行執行腳本時的各個參數組成。它的第一個成員總是 node,第二個成員是腳本文件名,其余成員是腳本文件的參數。

這段代碼能解決文章開頭場景提出的問題,但是總不能每個項目都復制粘貼這段代碼吧。我們是不是可以封裝成 npm 包使用。當時我也沒想太多,也沒有封裝 npm 包。直到我翻看 vite[8] 源碼發現了 only-allow[9] 這個包。一行代碼統一規范包管理器

{"scripts":?{"preinstall":?"npx?only-allow?pnpm?-y"}
}

當時看到這段代碼時,我就在想:他們咋知道這個的。當時依舊也沒想太多。直到有一天,發現 pnpm 文檔 Only allow pnpm 文檔[10] 上就有這個。好吧,吃了沒看文檔的虧。那時我打算分析下這個only-allow 包的源碼[11],打開一看驚喜萬分,才 36 行,寫它,于是寫了這篇文章。

按照慣例,看源碼前先準備環境。

4. 環境準備

先克隆代碼。

4.1 克隆代碼

#?推薦克隆我的源碼庫
git?clone?https://github.com/lxchuan12/only-allow-analysis.git
cd?only-allow-analysis/only-allow
#?npm?i?-g?pnpm
pnpm?i#?或者克隆官方倉庫
git?clone?https://github.com/pnpm/only-allow.git
cd?only-allow
#?npm?i?-g?pnpm
pnpm?i

開源項目一般先看README.md[12]

Force a specific package manager to be used on a project

強制在項目上使用特定的包管理器

Usage

Add a preinstall script to your project's package.json.

If you want to force yarn[13], add:

{"scripts":?{"preinstall":?"npx?only-allow?yarn"}
}

同理可得:強制使用 npmpnpm也是類似設置。

4.2 調試源碼

我們通過查看 package.json 文件。

//?only-allow/package.json
{"bin":?"bin.js",
}

確定主入口文件為 only-allow/bin.js

在最新版的 VSCode 中,auto attach 功能,默認支持智能調試,如果發現不支持,可以通過快捷鍵 ctrl + shift + p 查看是否啟用。

于是我們在 only-allow/package.json 文件中,添加如下命令。

//?only-allow/package.json
{"scripts":?{"preinstall":?"node?bin.js?pnpm"},
}

可以提前在 only-allow/bin.js 文件打上斷點 const usedPM = whichPMRuns()

按快捷鍵 ctrl + ` 快捷鍵打開終端。輸入如下 yarn add release-it -D 命令,即可調試 only-allow/bin.js

3765aa9c5feb908512584d4d60661af4.png

調試截圖

最終調試完會在終端報錯提示使用 pnpm install

如下圖所示:

92c761744ed79af76c0f4dd9f88e0c1a.png

終端報錯截圖

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

接著我們按調試來看源碼主流程。

5. only-allow 源碼

//?only-allow/bin.js
#!/usr/bin/env?node
const?whichPMRuns?=?require('which-pm-runs')
//?輸出邊框盒子
const?boxen?=?require('boxen')const?argv?=?process.argv.slice(2)
if?(argv.length?===?0)?{console.log('Please?specify?the?wanted?package?manager:?only-allow?<npm|pnpm|yarn>')process.exit(1)
}
//?第一個參數則是?用戶傳入的希望使用的包管理器
//?比如?npx?only-allow?pnpm?
//?這里調試是?node?bin.js?pnpm
const?wantedPM?=?argv[0]
//?npm?pnpm?yarn?都不是,則報錯
if?(wantedPM?!==?'npm'?&&?wantedPM?!==?'pnpm'?&&?wantedPM?!==?'yarn')?{console.log(`"${wantedPM}"?is?not?a?valid?package?manager.?Available?package?managers?are:?npm,?pnpm,?or?yarn.`)process.exit(1)
}
//?使用的包管理器
const?usedPM?=?whichPMRuns()
//?希望使用的包管理器?不相等,則報錯。
//?-?npm??提示使用?npm?install
//?-?pnpm?提示使用?pnpm?install
//?-?yarn?提示使用?yarn?install
//?最后退出進程
if?(usedPM?&&?usedPM.name?!==?wantedPM)?{const?boxenOpts?=?{?borderColor:?'red',?borderStyle:?'double',?padding:?1?}switch?(wantedPM)?{case?'npm':console.log(boxen('Use?"npm?install"?for?installation?in?this?project',?boxenOpts))breakcase?'pnpm':console.log(boxen(`Use?"pnpm?install"?for?installation?in?this?project.If?you?don't?have?pnpm,?install?it?via?"npm?i?-g?pnpm".
For?more?details,?go?to?https://pnpm.js.org/`,?boxenOpts))breakcase?'yarn':console.log(boxen(`Use?"yarn"?for?installation?in?this?project.If?you?don't?have?Yarn,?install?it?via?"npm?i?-g?yarn".
For?more?details,?go?to?https://yarnpkg.com/`,?boxenOpts))break}process.exit(1)
}

跟著斷點,我們可以查看到 which-pm-runs[15]

6. which-pm-runs 當前運行的是哪一個包管理器

最終返回包管理器和版本號。

根據調試可知,process.env.npm_config_user_agent 是類似這樣的字符串。

"yarn/1.22.10 npm/? node/v14.16.0 linux x64"

'use?strict'module.exports?=?function?()?{if?(!process.env.npm_config_user_agent)?{return?undefined}return?pmFromUserAgent(process.env.npm_config_user_agent)
}function?pmFromUserAgent?(userAgent)?{const?pmSpec?=?userAgent.split('?')[0]const?separatorPos?=?pmSpec.lastIndexOf('/')return?{name:?pmSpec.substr(0,?separatorPos),version:?pmSpec.substr(separatorPos?+?1)}
}

6.1 String.prototype.substr 截取字符串

順帶提下。我之前在 vue-next 源碼看到的 pull request => chore: remove deprecated String.prototype.substr[16]

String.prototype.substr is deprecated.

也就是說不推薦使用 substr。推薦使用 slice

ecma 規范[17]

7. 總結

我們通過從團隊需要規范統一包管理器的實際場景出發,講了 vue3 源碼中 preinstall 鉤子 約束只能使用 pnpm 。同時通過查看 vite[18] 源碼和 pnpm[19] 文檔,了解到 only-allow[20] 這個包。可以做到一行代碼統一規范包管理器"preinstall": "npx only-allow pnpm"

也學習了其原理。only-allow 期待的包管理器和運行的包管理器對比。匹配失敗,則報錯。而which-pm-runs 通過獲取 process.env.npm_config_user_agent 變量獲取到當前運行腳本的包管理器和版本號。

我們通過文檔和溝通約束,不如用工具(代碼)約束。

文章寫到這里,讓我想起我2018年寫的文章參加有贊前端技術開放日所感所想[21]

當時演講的大佬說過一句話。無比贊同。

技術(開源)項目本質上是:理念、套路、規范的工具化。

同時給我們的啟發也是要多看官方文檔和規范。

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

最后可以持續關注我@若川。歡迎加我微信 ruochuan12[23] 交流,參與 源碼共讀[24] 活動,每周大家一起學習200行左右的源碼,共同進步。

參考資料

[1]

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

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

推薦閱讀

1個月,200+人,一起讀了4周源碼
我歷時3年才寫了10余篇源碼文章,但收獲了100w+閱讀

老姚淺談:怎么學JavaScript?

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

aacbcea36749e00447e5a51007bcc265.gif

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

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

99c451672624f46aacf7a0247525fbf8.png

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

今日話題

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

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

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

相關文章

什么事接口

假設你設計一個和人交流的程序。 先建立一個接口 interface 人 //定義接口&#xff0c;它代表一個人&#xff0c; {void Hello(); }//接口虛函數&#xff0c;用來跟這個人說話 但不同的人有不用的交流方式&#xff0c;具體方式用類來實現&#xff0c;比如。 class 美國人&#…

6個高效辦公的Excel小技巧,學會讓你高效辦公

很多人在做Excel表格的時候&#xff0c;會出現下面這種情況&#xff1a;好不容易把內容都輸入好了&#xff0c;才發現文字或是數字的排列組合需要重新調整&#xff0c;這個時候頭就大了&#xff0c;到底是要一個個復制黏貼&#xff0c;還是要刪除后再添加&#xff1f;不管哪種方…

unity 完美像素_像素完美

unity 完美像素從Kidpix到設計系統 (From Kidpix to design systems) Did you ever create stamps in KidPix? Kidpix is bitmap drawing software that’s been around since the nineties, and I remember many happy — more like maddening — hours creating tiny pixela…

整整4個月了,盡全力組織了源碼共讀活動~

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

kvm 學習(二)

Linux下 如何通過命令行使用現有的鏡像創建、啟動kvm虛擬機 這里假定已經創建好了相應的鏡像&#xff1a; eg&#xff1a;我這里制作的鏡像名稱為zu1-centos7.img # lszu1-centos7.img 1、拷貝這個鏡像到某一個目錄 cp zu1-centos7.img /data2/ 2、編寫鏡像的配置文件&#x…

字節內部前端開發手冊(完整版)開放下載!

備戰2022&#xff0c;準備好了嗎&#xff1f;據字節HR部門發布的最新信息&#xff0c;2019年以來字節連續3年擴招&#xff0c;而即將到來的2022年春招前端崗位數不低于3000&#xff0c;雖連年擴招&#xff0c;但是報錄比卻從2019年的3%下降到今年的1%。BAT等一線大廠同樣有類似…

EBS中Java并發程序筆記(1)

在Oracle EBS中的Java并發程序&#xff08;Java Concurrent Program&#xff09;是系統功能中的一個亮點&#xff0c;它的出現使得用戶可以在ERP系統中運行自己定義的Java程序。本文為學習筆記&#xff0c;所以不會介紹太多背景知識。 使用Java并發程序的好處&#xff1a; 當遇…

figma設計_5位來自雜亂無章的設計師的Figma技巧

figma設計When starting a design project, a fast pace and multiple design iterations can easily lead to a cluttered mess. Taking the time in the beginning to build good organizational habits will save you time later. You’ll thank your past self when you do…

hello,你知道獲取元素有哪幾種方式嗎?

收下我的小心心&#xff01;&#xff08;害羞臉&#xff09; 根據id屬性的值獲取元素&#xff0c;返回來的是一個元素對象 document.getElementById("id屬性的值") 根據標簽名獲取元素&#xff0c;返回來的是一個偽數組&#xff0c;里面保存了多個的DOM對象 documen…

設計和實現一個 Chrome 插件提升登錄效率

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信ruochuan12 進群參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。已進行4個月了&#xff0c;很多小伙伴表示收獲頗豐。前言在我們的工作過程中&#xff0c;每當…

[待總結]redmine

先列出來&#xff0c;有空再總結轉載于:https://www.cnblogs.com/gracexiao/archive/2011/11/18/2253834.html

qq空間網頁設計_網頁設計中的負空間

qq空間網頁設計重點 (Top highlight)Because screens are limited, web design is also limited. It can be said that in the small box of the screen, each pixel is a piece of real estate.由于屏幕有限&#xff0c;因此網頁設計也受到限制。 可以說&#xff0c;在屏幕的小…

前端組件化-抽象公共組件類

優化上次的組件化小demo 上次的組件化demo只是為了簡單的實現前端組件化的思想&#xff0c;這次我們稍微優化一下抽離公共類 下面代碼 html <div id"wrapper"></div> 復制代碼js /* DOM字符串轉DOM節點 */ const createStringToDom str > {const ele…

時隔一年半,我,一個卑微的前端菜雞,又來寫面經了

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信ruochuan12 進群參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。已進行4個月了&#xff0c;很多小伙伴表示收獲頗豐。作者&#xff1a;刮涂層_贏大獎原文地址…

javascript模版引擎-tmpl的bug修復與性能優化

http://www.planeart.cn/?p1594 http://ejohn.org/blog/javascript-micro-templating http://bbs.phpchina.com/thread-224712-1-1.html [ Noevil: 下面直接貼出改進好的MicroTemp&#xff0c;但是還是建議看一下原文&#xff0c;里面有詳細的改進細節&#xff0c;和改進前后的…

2019.5.8_此書真乃寶書也_從定位參數到僅限關鍵字參數

《摘自流暢的Python》 此書真乃寶書也,雖說還是有點兒沒懂 從定位參數到僅限關鍵字參數 Python最好的特性之一是提供了極為靈活的參數處理機制&#xff0c;而且Python3進一步提供了僅限關鍵字參數(keyword-only argument)。與之密切相關的是&#xff0c;調用函數時使用*和**“展…

用戶體驗與可用性測試_可用性作為用戶體驗的原則

用戶體驗與可用性測試Every UX Designer has his views and best practices. We all have a guide book created through time and experience. I want to share mine with you.每個UX設計器都有他的觀點和最佳實踐。 我們都有一本通過時間和經驗編寫的指南。 我想和你分享我的…

Jenkins插件之Deploy

deploy插件&#xff1a; Deploy Plugindeploy插件支持將War/Jar部署到遠程的應用服務器上&#xff0c;例如Tomcat,JBoss,Glassfish。正在尋找或開發.NET web 應用的自動發布插件。如何回滾或重新部署先前的build&#xff1a;0&#xff09; 需要被deploy的job的結果要存檔&#…

受美國法律保護美國妞_為什么美國法律有效地要求所有軟件設計都要響應

受美國法律保護美國妞Smashing Magazine defines “responsive design” as an approach where design responds to the user’s behavior and environment based on screen size, platform, and orientation. In responsive design, a breakpoint is the “point” at which a…

源碼群友問:你這么多項目是怎么進行技術選型的?

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信ruochuan12 進群參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。已進行4個月了&#xff0c;很多小伙伴表示收獲頗豐。源碼群有群友提問我是怎么找到那么多npm…