Vue團隊核心成員開發的39行小工具 install-pkg 安裝包,值得一學!

1. 前言

大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。

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

源碼共讀活動 每周一期,已進行到16期。Vue團隊核心成員 Anthony Fu 開發的 install-pkg[2] 小工具,主文件源碼僅39行,非常值得我們學習。

閱讀本文,你將學到:

1.?如何學習調試源碼
2.?如何開發構建一個?ts?的?npm?包
3.?如何配置?github?action
4.?配置屬于自己的?eslint?預設、提升版本號等
5.?學會使用?execa?執行命令
6.?等等

2. install-pkg 是什么

Install package programmatically. Detect package managers automatically (npm, yarn and pnpm).

以編程方式安裝包。自動檢測包管理器(npmyarnpnpm)。

npm?i?@antfu/install-pkg
import?{?installPackage?}?from?'@antfu/install-pkg'
await?installPackage('vite',?{?silent:?true?})

我們看看npmjs.com @antfu/install-pkg[3] 有哪些包依賴的這個包。

我們可以發現目前只有以下這兩個項目使用了。

unplugin-icons[4]@chenyueban/lint[5]

我們克隆項目來看源碼。

3 克隆項目

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

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

{"name":?"@antfu/install-pkg","version":?"0.1.0","scripts":?{"start":?"esno?src/index.ts"},
}

關于調試可以看我的這篇文章:新手向:前端程序員必學基本技能——調試JS代碼,這里就不再贅述了。

我們可以得知入口文件是 src/index.ts

src文件夾下有三個文件

src
-?detect.ts
-?index.ts
-?install

接著我們看這些文件源碼。

4. 源碼

4.1 index.js

導出所有

//?src/install.ts
export?*?from?'./detect'
export?*?from?'./install'

我們來看 install.ts 文件,installPackage 方法。

4.2 installPackage 安裝包

//?src/install.ts
import?execa?from?'execa'
import?{?detectPackageManager?}?from?'.'export?interface?InstallPackageOptions?{cwd?:?stringdev?:?booleansilent?:?booleanpackageManager?:?stringpreferOffline?:?booleanadditionalArgs?:?string[]
}export?async?function?installPackage(names:?string?|?string[],?options:?InstallPackageOptions?=?{})?{const?agent?=?options.packageManager?||?await?detectPackageManager(options.cwd)?||?'npm'if?(!Array.isArray(names))names?=?[names]const?args?=?options.additionalArgs?||?[]if?(options.preferOffline)args.unshift('--prefer-offline')return?execa(agent,[agent?===?'yarn'??'add':?'install',options.dev???'-D'?:?'',...args,...names,].filter(Boolean),{stdio:?options.silent???'ignore'?:?'inherit',cwd:?options.cwd,},)
}

支持安裝多個,也支持指定包管理器,支持額外的參數。

其中 github execa[6] 是執行腳本

Process execution for humans

也就是說:最終執行類似以下的腳本。

pnpm?install?-D?--prefer-offine?release-it?react?antd

我們接著來看 detect.ts文件 探測包管理器 detectPackageManager 函數如何實現的。

4.3 detectPackageManager 探測包管理器

根據當前目錄鎖文件,探測包管理器。

//?src/detect.ts
import?path?from?'path'
import?findUp?from?'find-up'export?type?PackageManager?=?'pnpm'?|?'yarn'?|?'npm'const?LOCKS:?Record<string,?PackageManager>?=?{'pnpm-lock.yaml':?'pnpm','yarn.lock':?'yarn','package-lock.json':?'npm',
}export?async?function?detectPackageManager(cwd?=?process.cwd())?{const?result?=?await?findUp(Object.keys(LOCKS),?{?cwd?})const?agent?=?(result???LOCKS[path.basename(result)]?:?null)return?agent
}

其中 find-up[7] 查找路徑。

/
└──?Users└──?install-pkg├──?pnpm-lock.yaml
import?{findUp}?from?'find-up';console.log(await?findUp('pnpm-lock.yaml'));
//=>?'/Users/install-pkg/pnpm-lock.yaml'

path.basename('/Users/install-pkg/pnpm-lock.yaml') 則是 pnpm-lock.yaml

所以在有pnpm-lock.yaml文件的項目中,detectPackageManager 函數最終返回的是 pnpm

至此我們可以用一句話總結原理就是:通過鎖文件自動檢測使用何種包管理器(npm、yarn、pnpm),最終用 execa[8] 執行類似如下的命令。

pnpm?install?-D?--prefer-offine?release-it?react?antd

看完源碼,我們接著來解釋下 package.json 中的 scripts 命令。

5. package.json script 命令解析

{"name":?"@antfu/install-pkg","version":?"0.1.0","scripts":?{"prepublishOnly":?"nr?build","dev":?"nr?build?--watch","start":?"esno?src/index.ts","build":?"tsup?src/index.ts?--format?cjs,esm?--dts?--no-splitting","release":?"bumpp?--commit?--push?--tag?&&?pnpm?publish","lint":?"eslint?\"{src,test}/**/*.ts\"","lint:fix":?"nr?lint?--?--fix"},
}

5.1 ni 神器

github ni[9]

我之前寫過源碼文章。

尤雨溪推薦神器 ni ,能替代 npm/yarn/pnpm ?簡單好用!源碼揭秘![10]

自動根據鎖文件 yarn.lock / pnpm-lock.yaml / package-lock.json 檢測使用 yarn / pnpm / npm 的包管理器。

nr?dev?--port=3000#?npm?run?dev?--?--port=3000
#?yarn?run?dev?--port=3000
#?pnpm?run?dev?--?--port=3000
nr
#?交互式選擇腳本
#?interactively?select?the?script?to?run
#?supports?https://www.npmjs.com/package/npm-scripts-info?convention

nci - clean install

nci
#?npm?ci
#?簡單說就是不更新鎖文件
#?yarn?install?--frozen-lockfile
#?pnpm?install?--frozen-lockfile

pnpm install --frozen-lockfile[11]

5.2 esno 運行 ts

esno[12]

TypeScript / ESNext node runtime powered by esbuild

源碼也不是很多。

#!/usr/bin/env?nodeconst?spawn?=?require('cross-spawn')
const?spawnSync?=?spawn.syncconst?register?=?require.resolve('esbuild-register')const?argv?=?process.argv.slice(2)process.exit(spawnSync('node',?['-r',?register,?...argv],?{?stdio:?'inherit'?}).status)

esbuild-register[13]簡單說:使用 esbuild 即時傳輸 JSX、TypeScript 和 esnext 功能

5.3 tsup 打包 ts

打包 TypeScript 庫的最簡單、最快的方法。

tsup[14]

5.4 bumpp 交互式提升版本號

bumpp[15]

version-bump-prompt[16]

交互式 CLI 可增加您的版本號等

5.5 eslint 預設

eslint 預設[17]

pnpm?add?-D?eslint?@antfu/eslint-config

添加 .eslintrc 文件

//?.eslintrc
{"extends":?["@antfu"],"rules":?{}
}

之前看其他源碼發現的也很好用的 eslint 工具 xo

xo[18]

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

看完 scripts 命令解析,我們來看看 github action 配置。

6. github action workflows

對于github action 不熟悉的讀者,可以看阮一峰老師 GitHub Actions 入門教程[19]

配置文件workflows/release[20]

構建歷史github action workflow[21]

name:?Releaseon:push:tags:-?'v*'jobs:release:runs-on:?ubuntu-lateststeps:-?uses:?actions/checkout@v2with:fetch-depth:?0-?uses:?actions/setup-node@v2with:node-version:?'14'registry-url:?https://registry.npmjs.org/-?run:?npm?i?-g?pnpm?@antfu/ni-?run:?nci-?run:?nr?test?--if-present-?run:?npx?conventional-github-releaser?-p?angularenv:CONVENTIONAL_GITHUB_RELEASER_TOKEN:?${{secrets.GITHUB_TOKEN}}

根據每次 tags 推送,執行。

#?全局安裝?pnpm?和?ni
npm?i?-g?pnpm?@antfu/ni
#?如何存在?test?命令則執行
nr?test?--if-present

nci - clean install

nci
#?npm?ci
#?簡單說就是不更新鎖文件
#?yarn?install?--frozen-lockfile
#?pnpm?install?--frozen-lockfile

最后 npx conventional-github-releaser -p angularconventional-github-releaser[22]

生成 changelog

至此我們就學習完了 install-pkg[23] 包。

7. 總結

整體代碼比較簡單。原理就是通過鎖文件自動檢測使用何種包管理器(npm、yarn、pnpm),最終用 execa[24] 執行類似如下的命令。

pnpm?install?-D?--prefer-offine?release-it?react?antd

我們學到了:

1.?如何學習調試源碼
2.?如何開發構建一個?ts?的?npm?包
3.?如何配置?github?action
4.?配置屬于自己的?eslint?預設、提升版本號等
5.?學會使用?execa?執行命令
6.?等等

還有各種依賴工具。

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

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

參考資料

[1]

本文倉庫 https://github.com/lxchuan12/install-pkg-analysis.git,求個star^_^: https://github.com/lxchuan12/install-pkg-analysis.git
更多資料點擊閱讀原文查看

208ae9c58817eed53856c7888ce15771.gif

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

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

6bfc7c64144aaf513a230a2762ce36be.png

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

今日話題

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

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

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

相關文章

人臉識別及對比_沒有“色彩對比可及性的神話”

人臉識別及對比重點 (Top highlight)When you need to work on interfaces, color contrast is a real thing you have to take into account to make it accessible. You have the right to be afraid of losing part of the aesthetics of your beautifully well-designed in…

Entity Framework4.0 (一)概述(EF4 的Database First方法)

Entity Framework4.0(以后簡稱&#xff1a;EF4)&#xff0c;是Microsoft的一款ORM&#xff08;Object-Relation-Mapping&#xff09;框架。同其它ORM&#xff08;如&#xff0c;NHibernate,Hibernate&#xff09;一樣&#xff0c;一是為了使開發人員以操作對象的方式去操作關系…

mysql 相關子查詢使用【主表得數據需要擴展(統計數據依賴與其他表,但是與主表有關聯)】...

2019獨角獸企業重金招聘Python工程師標準>>> SELECT t.building,t.unit,t.room,t.ashcan ,(SELECT COUNT(a.resident_id) from t_address_book a where a.village_id t.village_id AND a.building t.building and a.room t.unit and a.house t.room and…

竟然被尤雨溪點贊了:我給Vue生態貢獻代碼的這一年

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。這篇文章在知乎被尤雨溪…

java版電子商務spring cloud分布式微服務b2b2c社交電商(四)SpringBoot 整合JPA

b2b2c電子商務社交平臺源碼請加企鵝求求&#xff1a;一零三八七七四六二六。JPA全稱Java Persistence API.JPA通過JDK 5.0注解或XML描述對象&#xff0d;關系表的映射關系&#xff0c;并將運行期的實體對象持久化到數據庫中。JPA 的目標之一是制定一個可以由很多供應商實現的AP…

60款很酷的 jQuery 幻燈片演示和下載

jQuery 是一個非常優秀的 JavaScript 框架&#xff0c;使用簡單靈活&#xff0c;同時還有許多成熟的插件可供選擇&#xff0c;它可以幫助你在項目中加入漂亮的效果&#xff0c;其中之一就是幻燈片&#xff0c;一種在有限的網頁空間內展示系列項目時非常好的方法。今天這篇文章要…

流體式布局與響應式布局_將固定像素設計轉換為流體比例布局

流體式布局與響應式布局Responsive web design has been a prime necessity for every enterprise ever since Google announced that responsive, mobile-friendly websites will see a hike in their search engine rank in 2015.自Google宣布響應式&#xff0c;移動友好型網…

怎樣開發一個 Node.js 命令行工具包

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。源碼共讀活動很多都是讀…

redis完全攻略

安裝篇 聲明&#xff1a;以下環境均是在ubuntu下進行 wget http://redis.googlecode.com/files/redis-2.4.4.tar.gztar zxf redis-2.4.4.tar.gz 然后進入目錄后直接make就可以了、如果邇的系統是32位的那么執行 make 32bit 安裝完成后、執行一下make test看是否正常、如果出現“…

印刷報價系統源碼_皇家印刷術-設計系統案例研究

印刷報價系統源碼重點 (Top highlight)Typography. It’s complicated. With Product Design, it’s on every screen. Decisions for a type scale affect literally every aspect of a product. When you’re working with an existing product, defining typography can fee…

Python簡單試題3

1&#xff0c;水仙花數 水仙花數是指一個 3 位數&#xff0c;它的每個位上的數字的 3次冪之和等于它本身 &#xff08;例如&#xff1a;1^3 5^3 3^3 153&#xff09; 代碼如下&#xff1a; 方法一&#xff1a; for i in range(100,1000): # 進行for循環num ia num % 10 # …

React Hooks 完全使用指南

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。React HooksHook 是什么…

重新設計Videoland的登錄頁面— UX案例研究

In late October of 2019 me and our CRO lead Lucas, set up a project at Videoland to redesign our main landing page for prospect customers (if they already have a subscription, they will go to the actual streaming product).在2019年10月下旬&#xff0c;我和我…

【常見Web應用安全問題】---5、File Inclusion

Web應用程序的安全性問題依其存在的形勢劃分&#xff0c;種類繁多&#xff0c;這里不準備介紹所有的&#xff0c;只介紹常見的一些。 常見Web應用安全問題安全性問題的列表&#xff1a;   &#xff11;、跨站腳本攻擊(CSS or XSS, Cross Site Scripting)   &#xff12;、S…

全新的 Vue3 狀態管理工具:Pinia

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。Vue3 發布已經有一段時間…

JS中變量和函數的使用

一、變量的介紹 1、啥是變量&#xff1f; 變量的本質是一塊有名字的內存空間。變量由變量名和變量值構成。變量名指的是內存空間的別名&#xff0c;一般位于賦值運算符的左邊&#xff1b;而變量值指的是內存空間中的數據&#xff0c;一般位于賦值運算符的右邊。例如:var balanc…

Win32 API消息函數:GetMessagePos

Win32 API消息函數:GetMessagePos 函數功能&#xff1a;該函數返回表示屏幕坐標下光標位置的長整數值。此位置表示當上一消息由GetMessage取得時鼠標占用的點。 函數原型&#xff1a;DWORD GetMessagePos&#xff08;VOID&#xff09; 參數&#xff1a;無。 返回值&…

都快 2022 年了,這些 Github 使用技巧你都會了嗎?

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。最近經常有小伙伴問我如…

單線程+異步協程

一 . 線程池和進程池 可以適當的使用,在大量的IO情況下有更好的方法 import time from multiprocessing.dummy import Pool def request(url):print(正在下載->,url)time.sleep(2)print(下載完畢->,url) start time.time() urls [www.baidu.com,www.taobao.com,www.sou…

Repeater\DataList\GridView實現分頁,數據編輯與刪除

一、實現效果 1、GridView 2、DataList 3、Repeater 二、代碼 1、可以去Csdn資源下載&#xff0c;包含了Norwind中文示例數據庫噢&#xff01;&#xff08;放心下&#xff0c;不要資源分&#xff09; 下載地址&#xff1a;數據控件示例源碼Norwind中文數據庫 2、我的開發環境&a…