最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

教你如何開發(fā)Vite3插件構(gòu)建Electron開發(fā)環(huán)境

 更新時(shí)間:2022年11月11日 08:24:38   作者:liulun  
這篇文章主要介紹了如何開發(fā)Vite3插件構(gòu)建Electron開發(fā)環(huán)境,文中給大家提到了如何讓 Vite 加載 Electron 的內(nèi)置模塊和 Node.js 的內(nèi)置模塊,需要的朋友可以參考下

開發(fā)新版本 Vue 項(xiàng)目推薦你使用 Vite 腳手架構(gòu)建開發(fā)環(huán)境,然而 Vite 腳手架更傾向于構(gòu)建純 Web 頁面,而不是桌面應(yīng)用,因此開發(fā)者要做很多額外的配置和開發(fā)工作才能把 Electron 引入到 Vue 項(xiàng)目中,這也是很多開發(fā)者都基于開源工具來構(gòu)建 Electron+Vue 的開發(fā)環(huán)境的原因。

但這樣做有兩個(gè)問題:第一個(gè)是這些開源工具封裝了很多技術(shù)細(xì)節(jié),導(dǎo)致開發(fā)者想要修改某項(xiàng)配置非常不方便;另一個(gè)是這些開源工具的實(shí)現(xiàn)方式我認(rèn)為也并不是很好。

所以,我還是建議你盡量 自己寫代碼構(gòu)建 Electron+Vue 的開發(fā)環(huán)境 ,這樣可以讓自己更從容地控制整個(gè)項(xiàng)目。

具體應(yīng)該怎么做呢?接下來我將帶你按如下幾個(gè)步驟構(gòu)建一個(gè) Vite+Electron 的開發(fā)環(huán)境:

創(chuàng)建項(xiàng)目

首先通過命令行創(chuàng)建一個(gè) Vue 項(xiàng)目:

npm create vite@latest electron-jue-jin -- --template vue-ts

接著安裝 Electron 開發(fā)依賴:

npm install electron -D

安裝完成后,你的項(xiàng)目根目錄下的 package.json 文件應(yīng)該與下面大體類似:

{
  "name": "electron-jue-jin",
  "private": true,
  "version": "0.0.1",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview"
  },
  "dependencies": {},
  "devDependencies": {
    "vue": "^3.2.37",
    "@vitejs/plugin-vue": "^3.0.0",
    "electron": "^19.0.8",
    "typescript": "^4.6.4",
    "vite": "^3.0.0",
    "vue-tsc": "^0.38.4"
  }
}

注意:這里我們 把 vue 從 dependencies 配置節(jié)移至了 devDependencies 配置節(jié)。這是因?yàn)樵?Vite 編譯項(xiàng)目的時(shí)候,Vue 庫會(huì)被編譯到輸出目錄下,輸出目錄下的內(nèi)容是完整的,沒必要把 Vue 標(biāo)記為生產(chǎn)依賴;而且在我們將來制作安裝包的時(shí)候,還要用到這個(gè) package.json 文件,它的生產(chǎn)依賴?yán)锊粦?yīng)該有沒用的東西,所以我們?cè)谶@里做了一些調(diào)整。

到這里,我們就創(chuàng)建了一個(gè)基本的 Vue+TypeScript 的項(xiàng)目,接下來我們就為這個(gè)項(xiàng)目引入 Electron 模塊。

創(chuàng)建主進(jìn)程代碼

創(chuàng)建好項(xiàng)目之后,我們創(chuàng)建主進(jìn)程的入口程序:src\main\mainEntry.ts。

這個(gè)入口程序的代碼很簡(jiǎn)單,如下所示:

//src\main\mainEntry.ts
import { app, BrowserWindow } from "electron";

let mainWindow: BrowserWindow;

app.whenReady().then(() => {
  mainWindow = new BrowserWindow({});
  mainWindow.loadURL(process.argv[2]);
});

在這段代碼里,我們?cè)?app ready 之后創(chuàng)建了一個(gè)簡(jiǎn)單的 BrowserWindow 對(duì)象。app 是 Electron 的全局對(duì)象,用于控制整個(gè)應(yīng)用程序的生命周期。在 Electron 初始化完成后,app 對(duì)象的 ready 事件被觸發(fā),這里我們使用 app.whenReady() 這個(gè) Promise 方法來等待 ready 事件的發(fā)生。

mainWindow 被設(shè)置成一個(gè)全局變量,這樣可以避免主窗口被 JavaScript 的垃圾回收器回收掉。另外,窗口的所有配置都使用了默認(rèn)的配置。

這個(gè)窗口加載了一個(gè) Url 路徑,這個(gè)路徑是以命令行參數(shù)的方式傳遞給應(yīng)用程序的,而且是命令行的第三個(gè)參數(shù)。

app 和 BrowserWindow 都是 Electron 的內(nèi)置模塊,這些內(nèi)置模塊是通過 ES Module 的形式導(dǎo)入進(jìn)來的,我們知道 Electron 的內(nèi)置模塊都是通過 CJS Module 的形式導(dǎo)出的,這里之所以可以用 ES Module 導(dǎo)入,是因?yàn)槲覀兘酉聛碜龅闹鬟M(jìn)程編譯工作幫我們完成了相關(guān)的轉(zhuǎn)化工作。

開發(fā)環(huán)境 Vite 插件

主進(jìn)程的代碼寫好之后,只有編譯過之后才能被 Electron 加載,我們是 通過 Vite 插件的形式來完成這個(gè)編譯工作和加載工作 的,如下代碼所示:

//plugins\devPlugin.ts
import { ViteDevServer } from "vite";
export let devPlugin = () => {
  return {
    name: "dev-plugin",
    configureServer(server: ViteDevServer) {
      require("esbuild").buildSync({
        entryPoints: ["./src/main/mainEntry.ts"],
        bundle: true,
        platform: "node",
        outfile: "./dist/mainEntry.js",
        external: ["electron"],
      });
      server.httpServer.once("listening", () => {
        let { spawn } = require("child_process");
        let addressInfo = server.httpServer.address();
        let httpAddress = `http://${addressInfo.address}:${addressInfo.port}`;
        let electronProcess = spawn(require("electron").toString(), ["./dist/mainEntry.js", httpAddress], {
          cwd: process.cwd(),
          stdio: "inherit",
        });
        electronProcess.on("close", () => {
          server.close();
          process.exit();
        });
      });
    },
  };
};

這是一個(gè)簡(jiǎn)單的 Vite 插件,在這個(gè)插件中我們注冊(cè)了一個(gè)名為 configureServer 的鉤子,當(dāng) Vite 為我們啟動(dòng) Http 服務(wù)的時(shí)候,configureServer鉤子會(huì)被執(zhí)行。

這個(gè)鉤子的輸入?yún)?shù)為一個(gè)類型為 ViteDevServer 的對(duì)象 server,這個(gè)對(duì)象持有一個(gè) http.Server 類型的屬性 httpServer,這個(gè)屬性就代表著我們調(diào)試 Vue 頁面的 http 服務(wù),一般情況下地址為:http://127.0.0.1:5173/

我們可以 通過監(jiān)聽 server.httpServerlistening 事件來判斷 httpServer 是否已經(jīng)成功啟動(dòng),如果已經(jīng)成功啟動(dòng)了,那么就啟動(dòng) Electron 應(yīng)用,并給它傳遞兩個(gè)命令行參數(shù),第一個(gè)參數(shù)是主進(jìn)程代碼編譯后的文件路徑,第二個(gè)參數(shù)是 Vue 頁面的 http 地址,這里就是 http://127.0.0.1:5173/

為什么這里傳遞了兩個(gè)命令行參數(shù),而主進(jìn)程的代碼接收第三個(gè)參數(shù)(process.argv[2])當(dāng)做 http 頁面的地址呢?因?yàn)?默認(rèn)情況下 electron.exe 的文件路徑將作為第一個(gè)參數(shù)。也就是我們通過 require("electron") 獲得的字符串。

這個(gè)路徑一般是:node_modules\electron\dist\electron.exe,如果這個(gè)路徑下沒有對(duì)應(yīng)的文件,說明你的 Electron 模塊沒有安裝好。

我們是 通過 Node.js child_process 模塊的 spawn 方法啟動(dòng) electron 子進(jìn)程的,除了兩個(gè)命令行參數(shù)外,還傳遞了一個(gè)配置對(duì)象。

這個(gè)對(duì)象的 cwd 屬性用于設(shè)置當(dāng)前的工作目錄,process.cwd() 返回的值就是當(dāng)前項(xiàng)目的根目錄。stdio 用于設(shè)置 electron 進(jìn)程的控制臺(tái)輸出,這里設(shè)置 inherit 可以讓 electron 子進(jìn)程的控制臺(tái)輸出數(shù)據(jù)同步到主進(jìn)程的控制臺(tái)。這樣我們?cè)谥鬟M(jìn)程中 console.log 的內(nèi)容就可以在 VSCode 的控制臺(tái)上看到了。

當(dāng) electron 子進(jìn)程退出的時(shí)候,我們要關(guān)閉 Vite 的 http 服務(wù),并且控制父進(jìn)程退出,準(zhǔn)備下一次啟動(dòng)。

http 服務(wù)啟動(dòng)之前,我們 使用 esbuild 模塊完成了主進(jìn)程 TypeScript 代碼的編譯工作 ,這個(gè)模塊是 Vite 自帶的,所以我們不需要額外安裝,可以直接使用。

主進(jìn)程的入口文件是通過 entryPoints 配置屬性設(shè)置的,編譯完成后的輸出文件時(shí)通過 outfile 屬性配置的。

編譯平臺(tái) platform 設(shè)置為 node,排除的模塊 external 設(shè)置為 electron, 正是這兩個(gè)設(shè)置使我們可以在主進(jìn)程代碼中可以通過 import 的方式導(dǎo)入 electron 內(nèi)置的模塊 。非但如此,Node 的內(nèi)置模塊也可以通過 import 的方式引入。

這個(gè) Vite 插件的代碼編寫好后,在 vite.config.ts 文件中引入一下就可以使用了,如下代碼所示:

// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { devPlugin } from "./plugins/devPlugin";
import optimizer from "vite-plugin-optimizer";

export default defineConfig({
  plugins: [devPlugin(), vue()],
});

現(xiàn)在執(zhí)行命令 npm run dev,你會(huì)看到 Electron 應(yīng)用加載了 Vue 的首頁,如下圖所示:

關(guān)閉窗口,主進(jìn)程和子進(jìn)程也會(huì)跟著退出。修改一下 Vue 組件里的內(nèi)容,窗口內(nèi)顯示的內(nèi)容也會(huì)跟著變化,說明熱更新機(jī)制在起作用。

渲染進(jìn)程集成內(nèi)置模塊

現(xiàn)在主進(jìn)程內(nèi)可以自由的使用 Electron 和 Node.js 的內(nèi)置模塊了,但渲染進(jìn)程還不行,接下去我們就為渲染進(jìn)程集成這些內(nèi)置模塊。

首先我們修改一下主進(jìn)程的代碼,打開渲染進(jìn)程的一些開關(guān),允許渲染進(jìn)程使用 Node.js 的內(nèi)置模塊,如下代碼所示:

// src\main\mainEntry.ts
import { app, BrowserWindow } from "electron";
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = "true";
let mainWindow: BrowserWindow;

app.whenReady().then(() => {
  let config = {
    webPreferences: {
      nodeIntegration: true,
      webSecurity: false,
      allowRunningInsecureContent: true,
      contextIsolation: false,
      webviewTag: true,
      spellcheck: false,
      disableHtmlFullscreenWindowResize: true,
    },
  };
  mainWindow = new BrowserWindow(config);
  mainWindow.webContents.openDevTools({ mode: "undocked" });
  mainWindow.loadURL(process.argv[2]);
});

在這段代碼中,有以下幾點(diǎn)需要注意:

1:ELECTRON_DISABLE_SECURITY_WARNINGS 用于設(shè)置渲染進(jìn)程開發(fā)者調(diào)試工具的警告,這里設(shè)置為 true 就不會(huì)再顯示任何警告了。

如果渲染進(jìn)程的代碼可以訪問 Node.js 的內(nèi)置模塊,而且渲染進(jìn)程加載的頁面(或腳本)是第三方開發(fā)的,那么惡意第三方就有可能使用 Node.js 的內(nèi)置模塊傷害最終用戶 。這就是為什么這里要有這些警告的原因。如果你的應(yīng)用不會(huì)加載任何第三方的頁面或腳本。那么就不用擔(dān)心這些安全問題啦。

2:nodeIntegration配置項(xiàng)的作用是把 Node.js 環(huán)境集成到渲染進(jìn)程中,contextIsolation配置項(xiàng)的作用是在同一個(gè) JavaScript 上下文中使用 Electron API。其他配置項(xiàng)與本文主旨無關(guān),大家感興趣的話可以自己翻閱官方文檔。

3: webContentsopenDevTools方法用于打開開發(fā)者調(diào)試工具。

完成這些工作后我們就可以在開發(fā)者調(diào)試工具中訪問 Node.js 和 Electron 的內(nèi)置模塊了。

設(shè)置 Vite 模塊別名與模塊解析鉤子

雖然我們可以在開發(fā)者調(diào)試工具中使用 Node.js 和 Electron 的內(nèi)置模塊,但現(xiàn)在還不能在 Vue 的頁面內(nèi)使用這些模塊。

這是因?yàn)?Vite 主動(dòng)屏蔽了這些內(nèi)置的模塊,如果開發(fā)者強(qiáng)行引入它們,那么大概率會(huì)得到如下報(bào)錯(cuò):

Module "xxxx" has been externalized for browser compatibility and cannot be accessed in client code.

接下去我們就介紹如何讓 Vite 加載 Electron 的內(nèi)置模塊和 Node.js 的內(nèi)置模塊。

首先我們?yōu)楣こ贪惭b一個(gè) Vite 組件:vite-plugin-optimizer

npm i vite-plugin-optimizer -D

然后修改 vite.config.ts 的代碼,讓 Vite 加載這個(gè)插件,如下代碼所示:

// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { devPlugin, getReplacer } from "./plugins/devPlugin";
import optimizer from "vite-plugin-optimizer";

export default defineConfig({
  plugins: [optimizer(getReplacer()), devPlugin(), vue()],
});

vite-plugin-optimizer 插件會(huì)為你創(chuàng)建一個(gè)臨時(shí)目錄:node_modules.vite-plugin-optimizer

然后把類似 const fs = require('fs'); export { fs as default } 這樣的代碼寫入這個(gè)目錄下的 fs.js 文件中。

渲染進(jìn)程執(zhí)行到:import fs from "fs" 時(shí),就會(huì)請(qǐng)求這個(gè)目錄下的 fs.js 文件,這樣就達(dá)到了在渲染進(jìn)程中引入 Node 內(nèi)置模塊的目的。

getReplacer 方法是我們?yōu)?vite-plugin-optimizer 插件提供的內(nèi)置模塊列表。代碼如下所示:

// plugins\devPlugin.ts
export let getReplacer = () => {
  let externalModels = ["os", "fs", "path", "events", "child_process", "crypto", "http", "buffer", "url", "better-sqlite3", "knex"];
  let result = {};
  for (let item of externalModels) {
    result[item] = () => ({
      find: new RegExp(`^${item}$`),
      code: `const ${item} = require('${item}');export { ${item} as default }`,
    });
  }
  result["electron"] = () => {
    let electronModules = ["clipboard", "ipcRenderer", "nativeImage", "shell", "webFrame"].join(",");
    return {
      find: new RegExp(`^electron$`),
      code: `const {${electronModules}} = require('electron');export {${electronModules}}`,
    };
  };
  return result;
};

我們?cè)谶@個(gè)方法中把一些常用的 Node 模塊和 electron 的內(nèi)置模塊提供給了 vite-plugin-optimizer 插件,以后想要增加新的內(nèi)置模塊只要修改這個(gè)方法即可。而且 vite-plugin-optimizer 插件不僅用于開發(fā)環(huán)境,編譯 Vue 項(xiàng)目時(shí),它也會(huì)參與工作 。

再次運(yùn)行你的應(yīng)用,看看現(xiàn)在渲染進(jìn)程是否可以正確加載內(nèi)置模塊了呢?你可以通過如下代碼在 Vue 組件中做這項(xiàng)測(cè)試:

//src\App.vue
import fs from "fs";
import { ipcRenderer } from "electron";
import { onMounted } from "vue";
onMounted(() => {
  console.log(fs.writeFileSync);
  console.log(ipcRenderer);
});

不出意外的話,開發(fā)者調(diào)試工具將會(huì)輸出如下內(nèi)容:

總結(jié)

現(xiàn)在我們邁出了萬里長(zhǎng)征的第一步,構(gòu)建好了 Vue3+Vite3+Electron 的開發(fā)環(huán)境 ,而且完成這項(xiàng)工作并不依賴于市面上任何一個(gè)現(xiàn)成的構(gòu)建工具,這個(gè)開發(fā)環(huán)境是我們自己動(dòng)手一點(diǎn)一點(diǎn)搭起來的,以后我們想增加或者修改一項(xiàng)功能,都可以很從容地自己動(dòng)手處理。

非但如此,我們還通過本講內(nèi)容向你介紹了 Vite 插件的開發(fā)技巧和如何創(chuàng)建一個(gè)簡(jiǎn)單的 Electron 應(yīng)用等知識(shí)。下一講我們將在本節(jié)課的基礎(chǔ)上,進(jìn)一步介紹如何使用 Vite 插件制作 Electron 應(yīng)用的安裝包。

到此這篇關(guān)于如何開發(fā)Vite3插件構(gòu)建Electron開發(fā)環(huán)境的文章就介紹到這了,更多相關(guān)Vite3插件構(gòu)建Electron開發(fā)環(huán)境內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • element-ui之解決select無法回顯的問題

    element-ui之解決select無法回顯的問題

    這篇文章主要介紹了element-ui之解決select無法回顯的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Vue處理循環(huán)數(shù)據(jù)流程示例精講

    Vue處理循環(huán)數(shù)據(jù)流程示例精講

    這篇文章主要介紹了Vue處理循環(huán)數(shù)據(jù)流程,這個(gè)又是一個(gè)編程語言,?模版語法里面必不可少的一個(gè),?也是使用業(yè)務(wù)場(chǎng)景使用最多的一個(gè)環(huán)節(jié)。所以學(xué)會(huì)使用循環(huán)也是重中之重了
    2023-04-04
  • vue3?Error:Unknown?variable?dynamic?import:?../views/的解決方案

    vue3?Error:Unknown?variable?dynamic?import:?../views/的解

    這篇文章主要給大家介紹了關(guān)于vue3?Error:Unknown?variable?dynamic?import:?../views/的解決方案,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • vue實(shí)現(xiàn)同一個(gè)頁面可以有多個(gè)router-view的方法

    vue實(shí)現(xiàn)同一個(gè)頁面可以有多個(gè)router-view的方法

    今天小編就為大家分享一篇vue實(shí)現(xiàn)同一個(gè)頁面可以有多個(gè)router-view的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • v-if 導(dǎo)致 elementui 表單校驗(yàn)失效問題解決方案

    v-if 導(dǎo)致 elementui 表單校驗(yàn)失效問題解決方案

    在使用 elementui 表單的過程中,某些表單項(xiàng)需要通過 v-if 來判斷是否展示,但是這些表單項(xiàng)出現(xiàn)了檢驗(yàn)失效的問題,今天小編給大家介紹v-if 導(dǎo)致 elementui 表單校驗(yàn)失效問題解決方案,感興趣的朋友一起看看吧
    2024-01-01
  • Vue中傳遞自定義參數(shù)到后端、后端獲取數(shù)據(jù)并使用Map接收參數(shù)

    Vue中傳遞自定義參數(shù)到后端、后端獲取數(shù)據(jù)并使用Map接收參數(shù)

    有些傳遞的參數(shù)是直接拼接到URL地址欄中的、但是為了統(tǒng)一管理、不能將傳遞的參數(shù)直接拼接到地址欄中,接下來通過本文給大家介紹Vue中傳遞自定義參數(shù)到后端、后端獲取數(shù)據(jù)并使用Map接收參數(shù),感興趣的朋友一起看看吧
    2022-10-10
  • 使用vue-cli創(chuàng)建項(xiàng)目的圖文教程(新手入門篇)

    使用vue-cli創(chuàng)建項(xiàng)目的圖文教程(新手入門篇)

    這篇文章主要介紹了新手入門vue 使用vue-cli創(chuàng)建項(xiàng)目的圖文教程,本文是針對(duì)完全不了解過vue和npm的小白而寫的,需要的朋友可以參考下
    2018-05-05
  • Vue全家桶入門基礎(chǔ)教程

    Vue全家桶入門基礎(chǔ)教程

    Vue 是一套用于構(gòu)建用戶界面的漸進(jìn)式框架,和React,都自稱自己只關(guān)注視圖層,全家桶對(duì)于開發(fā)一個(gè)完整的中大型單頁面應(yīng)用項(xiàng)目所必須的所必須的插件和框架,本文給大家分享Vue全家桶入門基礎(chǔ)教程,感興趣的朋友一起看看吧
    2021-05-05
  • 一個(gè)手寫的vue放大鏡效果

    一個(gè)手寫的vue放大鏡效果

    這篇文章主要介紹了一個(gè)手寫的vue放大鏡,組件使用less,文中給出了示例代碼,需要的朋友可以參考下
    2019-08-08
  • 在Vue.js中加載字體的正確方法

    在Vue.js中加載字體的正確方法

    這篇文章主要介紹了在Vue.js中加載字體的正確方法,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04

最新評(píng)論

赤峰市| 三明市| 南江县| 万荣县| 连江县| 兖州市| 竹溪县| 商城县| 德格县| 灵山县| 揭东县| 溆浦县| 鹤岗市| 湖州市| 黄山市| 新建县| 绥棱县| 东城区| 雅江县| 宁陵县| 法库县| 若羌县| 利川市| 奉贤区| 新竹县| 陆良县| 安溪县| 海兴县| 洪雅县| 城市| 涪陵区| 泰州市| 台湾省| 常宁市| 平山县| 宁津县| 永平县| 辽宁省| 永宁县| 临猗县| 平度市|