每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!
1. 前言
大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信 ruochuan12 參與,已進行三個月了,大家一起交流學習,共同進步。
想學源碼,極力推薦之前我寫的《學習源碼整體架構系列》 包含jQuery、underscore、lodash、vuex、sentry、axios、redux、koa、vue-devtools、vuex4、koa-compose、vue-next-release、vue-this、create-vue、玩具vite等10余篇源碼文章。
本文倉庫 open-analysis,求個star^_^[1]
最近組織了源碼共讀活動,大家一起學習源碼。于是搜尋各種值得我們學習,且代碼行數不多的源碼。
我們經常遇到類似場景:每次啟動項目的服務,電腦竟然乖乖的幫我打開了瀏覽器。當然你也可能沒有碰到過,但可能有這樣的需求。而源碼300行左右,核心源碼不到100行。跟我們工作息息相關,非常值得我們學習。
之前寫過據說 99% 的人不知道 vue-devtools 還能直接打開對應組件文件?本文原理揭秘,也是跟本文類似原理。
閱讀本文,你將學到:
1.?電腦竟然乖乖的幫我打開了瀏覽器原理和源碼實現 2.?學會使用?Node.js?強大的?child_process?模塊 3.?學會調試學習源碼 4.?等等2. 使用
2.1 在 webpack 中使用
devServer.open[2]
告訴 dev-server[3] 在服務器啟動后打開瀏覽器。將其設置為 true 以打開您的默認瀏覽器。
webpack.config.js
module.exports?=?{//...devServer:?{open:?true,}, };Usage via the CLI:
npx?webpack?serve?--openTo disable:
npx?webpack?serve?--no-open現在大多數都不是直接用 webpack 配置了。而是使用腳手架。那么接著來看我們熟悉的腳手架中,打開瀏覽器的功能是怎么使用的。
2.2 在 vue-cli 使用
npx?@vue/cli?create?vue3-project #?我的?open-analysis?項目中?vue3-project?文件夾 #?npm?i?-g?yarn #?yarn?serve?不會自動打開瀏覽器 yarn?serve #?--open?參數后會自動打開瀏覽器 yarn?serve?--open2.3 在 create-react-app 使用
npx?create-react-app?react-project #?我的?open-analysis?項目中?react-project?文件夾 #?npm?i?-g?yarn #?默認自動打開了瀏覽器 yarn?start為此我截了圖終端我用的是 window terminal,推薦我之前的文章:使用 ohmyzsh 打造 windows、ubuntu、mac 系統高效終端命令行工具,用過都說好。
webpack、vue-cli和create-react-app,它們三者都有個特點就是不約而同的使用了open[4]。
引用 open 分別的代碼位置是:
webpack-dev-server[5]
vue-cli[6]
create-react-app[7]
接著我們來學習open原理和源碼。
3. 原理
在 npm 之王 @sindresorhus[8] 的 open README文檔[9]中,英文描述中寫了為什么使用它的幾條原因。
為什么推薦使用 open
積極維護。 支持應用參數。 更安全,因為它使用?spawn?而不是?exec。 修復了大多數 node-open 的問題。 包括適用于 Linux 的最新 xdg-open 腳本。 支持 Windows 應用程序的 WSL 路徑。一句話概括open原理則是:針對不同的系統,使用Node.js的子進程 child_process 模塊的spawn方法,調用系統的命令打開瀏覽器。
對應的系統命令簡單形式則是:
#?mac open?https://lxchuan12.gitee.io #?win start?https://lxchuan12.gitee.io #?linux xdg-open?https://lxchuan12.gitee.iowindows start 文檔[10]
open包描述信息:open[11]
在這里可以看到有哪些 npm 包依賴了 open[12]
我們熟悉的很多 npm 包都依賴了open。這里列舉幾個。
webpack-dev-server[13]
react-dev-utils[14]
@vue/cli-shared-utils[15]
patch-package[16]
lighthouse[17]
release-it[18]
4. 閱讀源碼前的準備工作
#?推薦克隆我的項目,保證與文章同步,同時測試文件齊全 git?clone?https://github.com/lxchuan12/open-analysis.git #?npm?i?-g?yarn cd?open?&&?yarn#?或者克隆官方項目 git?clone?https://github.com/sindresorhus/open.git #?npm?i?-g?yarn cd?open?&&?yarn4.1 寫個例子,便于調試源碼
由于測試用例相對較為復雜,我們自己動手寫個簡單的例子,便于我們自己調試。
根據 README,我們在 open-analysis 文件夾下新建一個文件夾 examples ,里面存放一個 index.js。文件內容如下:
//?open-analysis/examples/index.js (async?()?=>?{const?open?=?require('../open/index.js');await?open('https://lxchuan12.gitee.io'); })();在 await open('https://lxchuan12.gitee.io'); 打上斷點。在終端命令行中執行
node?examples/index.js會自動喚起調試模式。如果不支持先閱讀這個官方文檔配置:Node.js debugging in VS Code[19],如果還是不行,可以升級到最新版VSCode試試。
跟著調試我們可以進入 open 函數。
調試VSCode 調試 Node.js 說明4.2 open 打開函數
//?open/index.js const?open?=?(target,?options)?=>?{if?(typeof?target?!==?'string')?{throw?new?TypeError('Expected?a?`target`');}return?baseOpen({...options,target}); };跟著斷點,我們來看最終調用的 baseOpen。這個函數比較長,重點可以猜到是:const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);這句,我們可以打上斷點調試。
4.3 baseOpen 基礎打開函數
//?open/index.js const?childProcess?=?require('child_process'); const?localXdgOpenPath?=?path.join(__dirname,?'xdg-open');const?{platform,?arch}?=?process; //?調試時我們可以自行調整修改平臺,便于調試各個平臺異同,比如?mac、win、linux //?const?{arch}?=?process; //?mac //?const?platform?=?'darwin'; //?win //?const?platform?=?'win32'; //?const?platform?=?'其他';const?baseOpen?=?async?options?=>?{options?=?{wait:?false,background:?false,newInstance:?false,allowNonzeroExitCode:?false,...options};//?省略部分代碼//?命令let?command;//?命令行參數const?cliArguments?=?[];//?子進程選項const?childProcessOptions?=?{};if?(platform?===?'darwin')?{command?=?'open';//?省略?mac?部分代碼}?else?if?(platform?===?'win32'?||?(isWsl?&&?!isDocker()))?{//?省略?window?或者?window?子系統代碼const?encodedArguments?=?['Start'];}?else?{const?useSystemXdgOpen?=?process.versions.electron?||platform?===?'android'?||?isBundled?||?!exeLocalXdgOpen;command?=?useSystemXdgOpen???'xdg-open'?:?localXdgOpenPath;//?省略?linux?代碼}//?省略部分代碼const?subprocess?=?childProcess.spawn(command,?cliArguments,?childProcessOptions);//?省略部分代碼subprocess.unref();return?subprocess; }由此我們可以看出:
一句話概括open原理則是:針對不同的系統,使用Node.js的子進程 child_process 模塊的spawn方法,調用系統的命令打開瀏覽器。
對應的系統命令簡單形式則是:
#?mac open?https://lxchuan12.gitee.io #?win start?https://lxchuan12.gitee.io #?linux xdg-open?https://lxchuan12.gitee.io5. 總結
一句話概括open原理則是:針對不同的系統,使用Node.js的子進程 child_process 模塊的spawn方法,調用系統的命令打開瀏覽器。
本文從日常常見的場景每次啟動服務就能自動打開瀏覽器出發,先講述了日常在webpack、vue-cli、create-react-app如何使用該功能,最后從源碼層面解讀了open[20]的原理和源碼實現。工作常用的知識能做到知其然,知其所以然,就比很多人厲害了。
因為文章不宜過長,所以未全面展開講述源碼中所有細節。非常建議讀者朋友按照文中方法使用VSCode調試 open 源碼。學會調試源碼后,源碼并沒有想象中的那么難。
最后可以持續關注我@若川。歡迎加我微信 ruochuan12 交流,參與 源碼共讀 活動,大家一起學習源碼,共同進步。
參考資料
[1]
本文倉庫 open-analysis,求個star^_^: https://github.com/lxchuan12/open-analysis.git
[2]更多參考資料可以點擊閱讀原文查看
最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進群。
推薦閱讀
1個月,200+人,一起讀了4周源碼
我歷時3年才寫了10余篇源碼文章,但收獲了100w+閱讀
老姚淺談:怎么學JavaScript?
我在阿里招前端,該怎么幫你(可進面試群)
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》10余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助1000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
識別上方二維碼加我微信、拉你進源碼共讀群
今日話題
略。歡迎分享、收藏、點贊、在看我的公眾號文章~
總結
以上是生活随笔為你收集整理的每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(3052):vue+eleme
- 下一篇: 前端学习(2956):项目中组件的本地注