談Vite在Electron環境下吃花卷拉饅頭的現象


緣起

在Electron的渲染進程中(也就是頁面代碼中),

我們常常使用process.env來攜帶一些環境變量,

比如HTTP服務地址的基質,本地靜態資源的路徑等

這樣做主要有兩個目的

一個是方便開發者寫多個配置環境變量的文件,區分生產環境、測試環境和開發環境

另一個是主進程和渲染進程共享一套環境變量,全局任何一個地方都隨取隨用,非常方便

正因為如此,一般的編譯工具都不會動用戶的process對象

但Vite不一樣,Vite的作者認為Vite只是給Web(運行在瀏覽器中的)產品提供服務的,

所以編譯時把用戶的process對象吃掉沒關系,甚至可以拉一個完全不一樣的東西給開發者都沒影響

因為Web前端開發者用不到這個對象

哎,尤雨溪完全忽略了Electron開發者的感受

現象

 用Vite創建一個Vue3項目,在入口文件中輸出這兩個對象

console.log(process)
console.log(process.env)

然后用Vite編譯,Electron打包編譯的文件,安裝並啟動Electron,打開調試器,

process對象的輸出如下(注意process下env屬性是正常的):

process.env對象的輸出如下:

為什么會出現這種現象呢?我們打開Vite編譯后的文件,找到目標位置,發現代碼被轉化成了這個樣子:

  console.log(process);
  console.log({NODE_ENV: "production"});

process還是老樣子,但process.env被直接轉成了一個對象字面量  

原理

想來Vite這么做可能的原因是:

在process.env下加屬性是Node.js開發者最常用的區分生產環境和開發環境的方案了

但瀏覽器環境下根本就沒有process對象,那怎么辦呢?

就直接粗暴的改寫了開發者的代碼吧

把process.env轉碼成了{NODE_ENV: "production"}

於是,就是現在我們看到的結果

 翻翻Vite的代碼,確實找到了如下邏輯(這是最新的代碼,以前我看到的跟這還不一樣):

      createReplacePlugin(
        (id) =>
          !/\?vue&type=template/.test(id) &&
          // also exclude css and static assets for performance
          !isCSSRequest(id) &&
          !resolver.isAssetRequest(id),
        {
          ...defaultDefines,
          ...userDefineReplacements,
          ...userEnvReplacements,
          ...builtInEnvReplacements,
          'import.meta.env.': `({}).`,
          'import.meta.env': JSON.stringify({
            ...userClientEnv,
            ...builtInClientEnv
          }),
          'process.env.NODE_ENV': JSON.stringify(resolvedMode),
          'process.env.': `({}).`,
          'process.env': JSON.stringify({ NODE_ENV: resolvedMode }),
          'import.meta.hot': `false`
        },
        !!sourcemap
      ),

就是這段代碼轉寫了我們業務代碼中的process.env

元凶找到,就有相應的解決方案了

方案

最老的版本的Vite,只能這樣做才可以

eval(['process',"env"].join('.'))

當前版本的Vite,這樣寫也可以的:

process["env"]

官方推薦使用的方式

import.meta.env

但我不推薦這樣用,這種寫法拿到的env對象的內容和實際的內容是有出入的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM