专业的手机网站建设公司,网站建设表格的属性,做抖音seo用哪些软件,wordpress引导页死循环1. 前言大家好#xff0c;我是若川。最近组织了源码共读活动#xff0c;感兴趣的可以加我微信 ruochuan12 参与#xff0c;每周大家一起学习200行左右的源码#xff0c;共同进步。已进行四个月了#xff0c;很多小伙伴表示收获颇丰。想学源码#xff0c;极力推荐之前我写… 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强制在项目上使用特定的包管理器UsageAdd a preinstall script to your projects package.json.If you want to force yarn[13], add:{scripts: {preinstall: npx only-allow yarn}
}同理可得强制使用 npm、pnpm也是类似设置。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。调试截图最终调试完会在终端报错提示使用 pnpm install。如下图所示终端报错截图更多调试细节可以看我的这篇文章新手向前端程序员必学基本技能——调试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 dont 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 dont 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 x64use strictmodule.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我在阿里招前端该怎么帮你可进面试群················· 若川简介 ·················你好我是若川毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》10余篇在知乎、掘金收获超百万阅读。从2014年起每年都会写一篇年度总结已经写了7篇点击查看年度总结。同时最近组织了源码共读活动帮助1000前端人学会看源码。公众号愿景帮助5年内前端人走向前列。识别上方二维码加我微信、拉你进源码共读群今日话题略。分享、收藏、点赞、在看我的文章就是对我最大的支持~