點擊頁面元素,這個Vite插件竟然幫我打開了Vue組件文件!超級好用!

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

前言

這兩天肝了個Vite插件,本文主要跟大家分享一下它的功能和實現思路.如果你覺得它對你有幫助,請給一個star支持作者 💗.

介紹

vite-plugin-vue-inspector的功能是點擊頁面元素,自動打開本地IDE并跳轉到對應的Vue組件.類似于Vue DevToolsOpen component in editor功能。(若川批注:關于原理可以看我寫過的文章:據說 99% 的人不知道 vue-devtools 還能直接打開對應組件文件?本文原理揭秘)

29afeed3e991a9d018ea4794988d70e0.png

用法

vite-plugin-vue-inspector支持Vue2 & Vue3,并且只需要進行簡單的配置就可以使用.

Vue2

//?vite.config.tsimport?{?defineConfig?}?from?"vite"
import?{?createVuePlugin?}?from?"vite-plugin-vue2"
import?Inspector?from?"vite-plugin-vue-inspector"export?default?defineConfig({plugins:?[createVuePlugin(),Inspector({vue:?2,}),],
})

Vue3

//?vite.config.tsimport?{?defineConfig?}?from?"vite"
import?Vue?from?"@vitejs/plugin-vue"
import?Inspector?from?"vite-plugin-vue-inspector"export?default?defineConfig({plugins:?[Vue(),?Inspector()],
})

IDE也要進行配置,這里就不啰嗦了, 👉 傳送門.

實現思路

看到這里,如果你覺得這個插件索然無味的話先別跑,插件沒意思,看看怎么寫插件還是有點意思的嘛 ! 接下來跟大家介紹一下這個插件的實現思路.

我們先來分析一下實現這個功能我們需要有哪些元素 :

  • Open IDE: 打開編輯器功能.

  • Web層: 提供該功能所需的頁面元素及交互功能.

  • Server層: 用戶交互時傳遞數據到Server層,由Server層調用Open IDE功能.

  • DOM=>Vue SFC映射關系: 告訴OPen IDE打開哪個文件并定位到對應的行列.

明確我們需要什么元素,我們就可以進一步來梳理它的實現方式,直接曬圖:

4a9907aaedf8b53b9f12e14cff4d4fab.png
vite-plugin-step.drawio (2).png

實現細節

接下來,我們來看具體的實現細節.在這之前,我們先簡單看下我們需要用到的幾個Vite插件API:

function?VitePluginInspector():?Plugin?{return?{name:?"vite-plugin-vue-inspector",//?應用順序enforce:?"pre",//?應用模式?(只在開發模式應用)apply:?"serve",//?含義:?轉換鉤子,接收每個傳入請求模塊的內容和文件路徑//?應用:?在這個鉤子對SFC模版進行解析并注入自定義屬性transform(code,?id)?{},//?含義:?配置開發服務器鉤子,可以添加自定義中間件//?應用:?在這個鉤子實現Open?Editor調用服務configureServer(server)?{},//?含義:?轉換index.html的專用鉤子,接收當前HTML字符串和轉換上下文//?應用:?在這個鉤子注入交互功能transformIndexHtml(html)?{},}
}

解析SFC模版 & 注入自定義屬性

這部分的實現主要分為兩步:

  • SFC Template => AST

    • 獲取元素所在組件的行和列的編號

    • 獲取自定義屬性插入的位置

  • 注入自定義屬性

    • file (SFC路徑,用于跳轉到指定文件)

    • line (元素所在行編號,用于跳轉到指定行)

    • column (元素所在列編號,用于跳轉到指定列)

    • title (SFC名稱,用于展示)

//?vite.config.tsfunction?VitePluginInspector():?Plugin?{return?{name:?"vite-plugin-vue-inspector",transform(code,?id)?{const?{?filename,?query?}?=?parseVueRequest(id)//?只處理SFC文件if?(filename.endsWith(".vue")?&&?query.type?!==?"style")?return?compileSFCTemplate(code,?filename)return?code},}
}
//?compiler.tsimport?path?from?"path"
import?MagicString?from?"magic-string"
import?{?parse,?transform?}?from?"@vue/compiler-dom"const?EXCLUDE_TAG?=?["template",?"script",?"style"]export?async?function?compileSFCTemplate(code:?string,id:?string,
)?{//?MagicString是一個非常好用的字符串操作庫,也如它的名字一樣,非常的神奇?!//?有了它,我們可以直接操作字符串,避免操作AST,換來更好的性能.?Vue3的實現也大量的用到了它.const?s?=?new?MagicString(code)//?SFC?=>?ASTconst?ast?=?parse(code,?{?comments:?true?})const?result?=?await?new?Promise((resolve)?=>?{transform(ast,?{//?ast?node節點訪問器nodeTransforms:?[(node)?=>?{if?(node.type?===?1)?{//?只解析html標簽?if?(node.tagType?===?0?&&?!EXCLUDE_TAG.includes(node.tag))?{const?{?base?}?=?path.parse(id)//?獲取到相關信息,并進行自定義屬性注入!node.loc.source.includes("data-v-inspecotr-file")&&?s.prependLeft(node.loc.start.offset?+?node.tag.length?+?1,`?data-v-inspecotr-file="${id}"?data-v-inspecotr-line=${node.loc.start.line}?data-v-inspecotr-column=${node.loc.start.column}?data-v-inspecotr-title="${base}"`,)}}},],})resolve(s.toString())})return?result
}

注入后的DOM元素長這樣 :

<h3?data-v-inspector-file="/xxx/src/Hi.vue"???data-v-inspector-line="3"?data-v-inspector-column="5"?data-v-inspector-title="Hi.vue">
</h3>

Open Editor Server服務

前面我們提到了創建Server服務的思路是在vite的configureServer的鉤子函數注入中間件:

//?vite.config.tsfunction?VitePluginInspector():?Plugin?{return?{name:?"vite-plugin-vue-inspector",configureServer(server)?{//?注冊中間件//?請求Query參數解析中間件?server.middlewares.use(queryParserMiddleware)//?Open?Edito服務中間件server.middlewares.use(launchEditorMiddleware)},}
}
//?middleware.ts//?請求Query參數解析中間件?
export?const?queryParserMiddleware:?Connect.NextHandleFunction?=?(req:?RequestMessage?&?{query?:?object},_,next,
)?=>?{if?(!req.query?&&?req.url?.startsWith(SERVER_URL))?{const?url?=?new?URL(req.url,?"http://domain.inspector")req.query?=?Object.fromEntries(url.searchParams.entries())}next()
}//?Open?Editor服務中間件
export?const?launchEditorMiddleware:?Connect.NextHandleFunction?=?(req:?RequestMessage?&?{query?:?{?line:?number;?column:?number;?file:?string?}},res,next,
)?=>?{//?只處理Open?Editor接口if?(req.url.startsWith(SERVER_URL))?{//?解析SFC路徑,行號,列號const?{?file,?line,?column?}?=?req.queryif?(!file)?{res.statusCode?=?500res.end("launch-editor-middleware:?required?query?param?\"file\"?is?missing.")}const?lineNumber?=?+line?||?1const?columnNumber?=?+column?||?1//?見下方鏈接launchEditor(file,?lineNumber,?columnNumber)res.end()}else?{next()}
}

關于launchEditor的具體邏輯我直接fork了react-dev-utils的實現,它支持很多IDE (vscode,atom,webstorm...),它的大致原理就是通過維護一些進程映射表和環境變量,然后通過調用Node.js的子進程喚醒IDE:

child_process.spawn(editor,?args,?{?stdio:?'inherit'?});

交互功能注入

這個功能的實現原理其實就在transformIndexHtml注入功能所需要的html,scripts,styles.

//?vite.config.tsfunction?VitePluginInspector():?Plugin?{return?{transformIndexHtml(html)?{return?{html,tags:?[{tag:?"script",children:?...,injectTo:?"body",},?{tag:?"script",attrs:?{type:?"module",},children:?scripts,injectTo:?"body",},?{tag:?"style",children:?styles,injectTo:?"head",}],}}}
}

關于交互的頁面實現有很多種,最簡單的無非就是編寫原生js,這樣我們無需任何編譯就可以直接注入到html中,但是用原生js來寫頁面真的是慢又不好維護,于是我選擇了Vue進行開發,使用Vue就意味著要進行編譯才能在瀏覽器中跑起來.為了這個所謂的研發體驗,又折騰了一波,大概過程就是通過compile-sfc等包編譯出render函數,樣式代碼等,為了兼容Vue2,我又引入了祖傳的vue-template-compiler...噼里啪啦噼里啪啦..感興趣的童鞋可以點傳送門詳看. (u1s1,還是有點意思的!!) 當然了,這部分的編譯都是在插件打包時完成的,用戶在使用插件的時候并不會有這部分的運行時開銷.

致謝

這個項目的靈感來自于react-dev-inspector,使用React的童鞋可以看看.

結語

在做這個插件的時候也踩了一些坑,通過查看vue,vite等源碼排查解決.這里給想看源碼的童鞋一個建議,從實踐和帶著問題的角度出發,也許會有更好的效果和更深刻的印象 (教訓) :)

858d2be00aa7548a2abc0bf9ca8b7697.gif

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

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

f43695f7f26369d36a6f9db8b2d4940a.png

掃碼加我微信 ruochuan02、拉你進源碼共讀

今日話題

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

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

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

相關文章

shields 徽標_符號,標志,文字標記:徽標類型的綜合指南

shields 徽標Designers and non-designers alike struggle with common terminology when talking about brand marks, often using different terms interchangeably. When it comes to clarifying definitions, sometimes even the most seasoned professionals get confused…

【原創】SVM小結

理論基礎&#xff1a; 機器學習有三類基本的問題&#xff0c;即模式識別、函數逼近和概率密度估計&#xff0e; SVM有著嚴格的理論基礎&#xff0c;建立了一套較好的有限訓練樣本下機器學習的理論框架和通用方法。他與機器學習是密切相關的&#xff0c;很多理論甚至解決了機器學…

React 18 帶給我們的驚喜

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

建模心法(2)——邁出建模第一步

原文地址&#xff1a;http://www.cnblogs.com/1-2-3/archive/2008/08/04/model-method-part1.html 原文作者&#xff1a;景春雷 一錯再錯的這故事才精彩 ——樸樹 《我愛你再見》摘要 即使讀了再多的書、跟過再多的項目&#xff0c;…

Web:你知道我這十幾年是怎么過來的嗎?!

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

設計師更高效_如何丟掉我的工作使我成為一名更好的設計師

設計師更高效I lost my job a few times early on in my design career. In the process of getting back up after a job loss, it has made me a better designer not only in terms of hard skills but the soft skills required to be more resilient and empathetic, whic…

【ASP.NET】登陸成功后如何跳轉到上一個頁面

當用戶瀏覽網頁的時候會在某個地方需要用戶登陸才能繼續瀏覽&#xff0c;用戶登陸之后會自動跳轉到剛剛瀏覽的頁面。這個步驟是怎么實現的呢&#xff1f;net小伙在查閱相關資料實踐之后終于明白了&#xff0c;其實很簡單&#xff0c;先分享給大家吧。 當用戶在瀏覽一個頁面的時…

4月,誠邀你參加源碼共讀,學會看源碼,打開新世界!開闊視野

大家好&#xff0c;我是若川。很多關注我的新朋友可能不知道我組織了源碼共讀活動~也有很多人不知道我是誰。有人以為我是80后。有人以為我是全職自媒體等等。若川的 2021 年度總結&#xff0c;彈指之間 這篇文章寫了我是16年畢業的&#xff0c;或許有些啟發。源碼共讀按照從易…

bt709和srgb_選擇用于多用途視頻編輯和色彩校正的顯示器— sRGB,DCI-P3,REC 709

bt709和srgb**Note from the author: if you enjoy this article, please follow me or this publication for more video production and marketing related content.****作者注&#xff1a;如果您喜歡本文&#xff0c;請關注我或此出版物以獲取更多與視頻制作和營銷相關的內容…

超4000人參加源碼共讀,喊你來一起學習成長~打開新世界

大家好&#xff0c;我是若川。很多關注我的新朋友可能不知道我組織了源碼共讀活動~也有很多人不知道我是誰。有人以為我是80后。有人以為我是全職自媒體等等。若川的 2021 年度總結&#xff0c;彈指之間 這篇文章寫了我是16年畢業的&#xff0c;或許有些啟發。源碼共讀按照從易…

figma設計_如何在Figma中構建設計入門套件(第二部分)

figma設計Figma教程 (Figma Tutorial) With this short, but informative Tutorial Series I aim to show you how to build the solid foundations of a powerful, and versatile Design Starter Kit, enabling you to start your next project in Figma faster than ever bef…

Hibernate 簡介(百度)

Hibernate是一個開放源代碼的對象關系映射框架&#xff0c;它對JDBC進行了非常輕量級的對象封裝&#xff0c;使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合&#xff0c;既可以在Java的客戶端程序使用&#xff0c;也可以在…

GitHub 最受歡迎的Top 20 JavaScript 項目

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

java反編譯,eclipse支持插件

http://java.decompiler.free.fr/?qjdeclipse 按照說明 在eclipse更新插件就可以。 這樣 在一些 閉源的jar文件&#xff0c;你也可以看到 大致的源碼。&#xff08;公司 知道如何 加密混淆 java代碼或class文件&#xff0c;居然無法使用jd-gui瀏覽源碼&#xff09; 而&#xf…

unity vr 交互_基于手動的VR / MR交互,用于刪除實體

unity vr 交互Deleting an entity or closing an application is one of the most ubiquitous operations performed in any application. It is necessary for the organization of the data. On the computer, there are multiple ways to delete a file like cmd delete, d…

手把手帶你走進Babel的編譯世界

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

iPhone/Mac Objective-C內存管理教程和原理剖析(二)口訣與范式轉

版權聲明 此文版權歸作者Vince Yuan (vince.yuan#gmail.com)所有。歡迎非營利性轉載&#xff0c;轉載時必須包含原始鏈接http://vinceyuan.cnblogs.com&#xff0c;且必須包含此版權聲明的完整內容。 版本 1.1 發表于2010-03-08 二 口訣與范式 1 口訣。 1.1 …

同態加密應用_重新設計具有同態性的銀行應用

同態加密應用Catering user preference is undoubtedly a never-ending task. End of the day, it takes all sorts to make a world. For that reason, it is deemed important to design with the accent of communicating core business value, and resolving user needs wi…

(字節/華為/美團)前端面經記錄冷冷清清的金三銀四

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

PHP連接PGSQL

function conn($hostName,$Login,$Password,$dbName,$Port) //建立目標數據庫連接 {$conn &ADONewConnection(postgres8);$conn->debug false; //true時adodb將在頁面顯示debug信息$conn->LogSQL(false); //true時adodb將建立adodb_sqllog表記錄每次sql操作$conn-&…