Vite引入虛擬文件的實現

背景

在新項目升級vue3以後,自然而然的就把vue-cli&webpack更換成瞭vite,不得不說vite真的很香,不僅編譯速度剛剛的,而且在vue3的新功能上也有更好的支持.

不過在開發過程中也遇到瞭一些問題

在看到vite-plugin-pages插件之後,突然看到這樣的寫法:

import routes from "virtual:generated-pages";

其實在使用很多vite插件的時候,發現在引用中存在這樣的用法:

import xxx from "virtual:xxx";

那麼這個virtual:xxx怎麼之前沒有見過,這明顯不是一個npm上面的包,那會是什麼?

引入虛擬文件

在看瞭vite的文檔之後才明白,原來這是一個引入虛擬文件功能,他可以生成一個虛擬的文件讓你來引入.

在vite文檔的插件API中引入一個虛擬文件處說到這個功能,章節裡面有寫到支持引入你一個虛擬文件,也就是這個文件並不存在,而是通過代碼臨時生成的.

而這個生成是通過vite的插件來完成,也就是說在nodejs環境中來生成對應的虛擬文件

vite-plugin-pages就是通過這個功能實現的,他首先在編譯時遍歷對應的頁面目錄,根據目錄結構和文件名的命名規則來動態生成對應的路由表,這樣就很好的完成瞭本地目錄結構到動態路由之間的良好交互.

其實在nuxt中也有動態路由的功能,不過他可沒有虛擬引入,在項目啟動前來動態修改webpack配置,使用definePlugin來將路由表傳遞給前端代碼的.

通過引入虛擬文件的功能,我們就避免瞭需要通過傳遞修改常量的方式,將對應的數據傳遞給前端代碼.

而除瞭傳遞常量,虛擬引入可以做的更多,要知道他可是引入的是一個虛擬js文件,這表示我們也可以動態的生成函數以及代碼邏輯在其中.

例子

舉個例子,比如可以在生成的代碼中自動導入需要的文件,然後返回一個函數,通過這個函數來使用之前導入的文件,這樣我們就不需要在實際使用的導入這些文件瞭,通過返回虛擬文件中導出的函數我們就可以直接使用這些本來要導入的文件.

import a from 'a-module'
import b from 'b-module'
...
import z from 'z-module'

const modules = {a,b,...,z}

export default useModule(name){
    return modules[name]
}

之前使用 👇

import a from 'a-module'
import b from 'b-module'
...
import z from 'z-module

a()
b()
c()

現在使用 👇

import useModule from 'virtual:xxx'

const a = useModule('a')
const b = useModule('b')
const c = useModule('c')

當然這隻是一個簡單的例子,你可以更多的發揮自己的想象力還是先更多的功能

文檔

我們來回到文檔來看看具體功能是如何實現的呢?

文檔中給出的例子如下:

export default function myPlugin() {
  const virtualFileId = '@my-virtual-file'  

  return {
    name: 'my-plugin', // 必須的,將會在 warning 和 error 中顯示
    resolveId(id) {
      if (id === virtualFileId) {
        return virtualFileId
      }
    },
    load(id) {
      if (id === virtualFileId) {
        return `export const msg = "from virtual file"`
      }
    }
  }
}

可以看出其中主要又三個關鍵點:

  • virtualFileId : 需要引入的虛擬文件名
  • resolveId(id): 判斷是否是需要解析的虛擬文件名
  • load(id): 返回對應的虛擬引入文件的代碼字符串

可以看出返回的代碼是以字符串的方式返回的,我們可以通過模板拼接或模板轉譯的方式來方便我們構建需要返回的代碼字符串.

Typescript支持

不過需要註意的是虛擬文件引入返回的是js代碼而不是ts代碼,而且代碼是動態生成的這也說明在使用過程中我們會遇到在TS中沒有類型支持的情況

那麼如果你的代碼結構是確定的可以提前生成對應的d.ts定義文件.然後通過 在tsconfig中配置compilerOptions.types加載對應的定義文件即可,如果代碼結構是動態的,那麼就需要動態生成對應的d.ts文件寫入到項目中來實現.

declare module 'virtual:xxx' {
...
}

總結

可以看出引入虛擬文件是一個很實用的功能,它不僅可以讓前端代碼可以與編譯環境進行交互,而且可以動態的生成代碼來實現一些以前不是那麼方便實現的功能,而開發起來具體實現也很簡單,你準備在你的插件中使用瞭麼?

到此這篇關於Vite引入虛擬文件的實現的文章就介紹到這瞭,更多相關Vite引入虛擬文件內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: