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.mzph.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余篇源码文章。这篇文章在知乎被尤雨溪…

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余篇源码文章。源码共读活动很多都是读…

印刷报价系统源码_皇家印刷术-设计系统案例研究

印刷报价系统源码重点 (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…

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;我和我…

全新的 Vue3 状态管理工具:Pinia

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。Vue3 发布已经有一段时间…

都快 2022 年了,这些 Github 使用技巧你都会了吗?

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。最近经常有小伙伴问我如…

Repeater\DataList\GridView实现分页,数据编辑与删除

一、实现效果 1、GridView 2、DataList 3、Repeater 二、代码 1、可以去Csdn资源下载&#xff0c;包含了Norwind中文示例数据库噢&#xff01;&#xff08;放心下&#xff0c;不要资源分&#xff09; 下载地址&#xff1a;数据控件示例源码Norwind中文数据库 2、我的开发环境&a…

网站快速成型_我的老板对快速成型有什么期望?

网站快速成型Some of the top excuses I have gotten from clients when inviting them into a prototyping session are: “I am not a designer!” “I can’t draw!” “I have no creative background!”在邀请客户参加原型制作会议时&#xff0c;我从客户那里得到的一些主…

EXT.NET复杂布局(四)——系统首页设计(上)

很久没有发帖了&#xff0c;很是惭愧&#xff0c;因此给各位使用EXT.NET的朋友献上一份礼物。 本篇主要讲述页面设计与效果&#xff0c;下篇将讲述编码并提供源码下载。 系统首页设计往往是个难点&#xff0c;因为往往要考虑以下因素&#xff1a; 重要通知系统功能菜单快捷操作…

figma设计_在Figma中使用隔片移交设计

figma设计I was quite surprised by how much the design community resonated with the concept of spacers since I published my 自从我发表论文以来&#xff0c;设计界对间隔件的概念产生了多少共鸣&#xff0c;我感到非常惊讶。 last story. It encouraged me to think m…

axios源码中的10多个工具函数,值得一学~

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。本文来自读者Ethan01投稿…

寄充气娃娃怎么寄_我如何在5小时内寄出新设计作品集

寄充气娃娃怎么寄Over the Easter break, I challenged myself to set aside an evening rethinking the structure, content and design of my portfolio in Notion with a focus on its 在复活节假期&#xff0c;我挑战自己&#xff0c;把一个晚上放在一边&#xff0c;重新思…

最全 JavaScript Array 方法 详解

大家好&#xff0c;我是若川。最近组织了源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。我们在日常开发中&#…

管理沟通中移情的应用_移情在设计中的重要性

管理沟通中移情的应用One of the most important aspects of any great design is the empathetic understanding of and connection to the user. If a design is ‘selfish’, as in when a product designed with the designer in mind and not the user, it will ultimatel…