日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

点击页面元素,这个Vite插件竟然帮我打开了Vue组件文件!超级好用!

發布時間:2023/12/9 vue 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 点击页面元素,这个Vite插件竟然帮我打开了Vue组件文件!超级好用! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

前言

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

介紹

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

用法

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打開哪個文件并定位到對應的行列.

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

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等源碼排查解決.這里給想看源碼的童鞋一個建議,從實踐和帶著問題的角度出發,也許會有更好的效果和更深刻的印象 (教訓) :)

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

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

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

今日話題

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

總結

以上是生活随笔為你收集整理的点击页面元素,这个Vite插件竟然帮我打开了Vue组件文件!超级好用!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。