vite
和Electron
。
- Vite是一种新型前端构建工具,能够显著提升前端开发体验。由尤大推出,其发动态表示“再也回不去webpack了...”
- Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入Chromium和Node.js到二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验。
- 因此,若要使用
vite
和electron
,还需要自己来配置。
一. 创建一个vite项目
1.安装vite
yarn create vite
2.创建项目
yarn create vite electron-vue --template vue
3.进入并运行项目
cd electron
yarn install
yarn dev
二.配置Electron
1.官方文档
在Electron官网的快速入门文档中,有官方给出的利用html、javascript、css来创建一个electron应用的案例,vite+electron的方案也借鉴其中。
2.安装
首先安装electron至vite应用。
yarn add --dev electron
如果安装不上,可能会是网络问题,使用手机wifi连接然后进行安装。如果还是不行更换淘宝源。
3.配置文件
1)在vite.config.js文件里
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
base: process.env.ELECTRON == "true" ? "./" : "./",
plugins: [vue()],
css: {
preprocessorOptions: {
less: {
math: "always", // 括号内才使用数学计算
globalVars: {
// 全局变量
// mainColor: "red",
},
},
},
},
});
2)electron主进程文件夹
在项目根目录下创建一个electron文件夹,并在下面创建一个mian.js和preload.js文件
mian.js
// electron/mian.js
const { app, BrowserWindow } = require("electron");
const path = require("path");
const isDev = process.env.IS_DEV == "true" ? true : false;
function createWindow() {
//创建浏览器窗口。
const mainWindow = new BrowserWindow({
width: 480,
height: 800,
webPreferences: {
contextIsolation: false,
nodeIntegration: true,
webSecurity: false,
preload: path.join(__dirname, "preload.js"),
},
});
// 加载 index.html
mainWindow.loadURL(
isDev
? "http://localhost:5173"
: `file://${path.join(__dirname, "../dist/index.html")}`
);
// 是否打开开发工具
if (isDev) {
mainWindow.webContents.openDevTools();
}
}
// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
createWindow();
app.on("activate", function () {
// 通常在 macOS 上,当点击 dock 中的应用程序图标时,如果没有其他
// 打开的窗口,那么程序会重新创建一个窗口。
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
// 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 因此,通常对程序和它们在
// 任务栏上的图标来说,应当保持活跃状态,直到用户使用 Cmd + Q 退出。
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
3)preload.js
preload是electron提供 的一个中间层功能,electron在构造嵌入html窗口的过程中可在preload.js中写一些代码得到node.js提供的fs对象
// electron/preload.js
// 所有Node.js API都可以在预加载过程中使用。
// 它拥有与Chrome扩展一样的沙盒。
window.ipcRenderer = require("electron").ipcRenderer;
window.shell = require("electron").shell;
window.addEventListener("DOMContentLoaded", () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector);
if (element) element.innerText = text;
};
for (const dependency of ["chrome", "node", "electron"]) {
replaceText(`${dependency}-version`, process.versions[dependency]);
}
});
4)在package.json对象中添加下列属性
"build": {
"appId": "com.my-website.my-app",
"productName": "MyApp",
"copyright": "Copyright © 2019 ${author}",
"mac": {
"category": "public.app-category.utilities"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true
},
"files": [
"dist/**/*",
"electron/**/*"
],
"directories": {
"buildResources": "assets",
"output": "dist_electron"
}
}
修改 package.json 的 scripts 属性
"scripts": {
"dev": "vite --host",
"build": "vite build",
"serve": "vite preview",
"electron": "wait-on tcp:5173 && cross-env IS_DEV=true electron .",
"electron:dev": "concurrently -k \"cross-env BROWSER=none npm run dev\" \"npm run electron\"",
"electron:build.win": "npm run build && electron-builder --win --dir",
"electron:build.linux": "npm run build && electron-builder --linux appImage",
"electron:build.test": "npm run build && electron-builder --dir",
"electron:build.exe": "npm run build && electron-builder --win"
},
修改 package.json 的顶部属性,最重要的是要添加 main 指明入口
{
"name": "vite-electron",
"author": "github@lathesky",
"version": "0.0.0",
"main": "electron/electron.js",
}
到此,vue+vite+electron打包流程完毕。接下来是实现使用electron完成操控本机电脑文件夹。
三.访问本机盘符并进行操作
1.了解如何操控
涉及到的读文件的方法就是使用node.js提借的fs类库,但是他默认读取的文件都是在磁盘某个路径,比如传的参数 是d:\xxx文件这样的,主进程可以读取electron文件夹下面的文件,vue是读不到electron文件夹下面的文件,所以用主进程读文件再把结果发到vue页面上。
1.2 什么是主进程
主进程 就是electron容器,这样理解就行了,不用深研究,涉及一个对象ipcmain
要操作本机文件就得使用node.js,要使用node.js的一些方法就必须得在mian.js创建窗口时开启node API。在webpreferences里面
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 480,
height: 800,
webPreferences: {
contextIsolation: false,//是否开启隔离上下文
nodeIntegration: true,//渲染进程使用node api
webSecurity: false,
preload: path.join(__dirname, "preload.js"),
},
});
// and load the index.html of the app.
// win.loadFile("index.html");
mainWindow.loadURL(
isDev
? "http://localhost:5173"
: `file://${path.join(__dirname, "../dist/index.html")}`
);
// Open the DevTools.
if (isDev) {
mainWindow.webContents.openDevTools();
}
}
webpreferences里面的这四项都加上,由于nodeIntegration这项非常关键,preload这个选项就是配置preload.js文件在哪个地方,我的项目 preload.js文件和main.js在同级目录,所以截图当中写法就行。其中path是引入的node.js的path变量
const path = require("path")
2.主进程通信相关
在electron文件夹中的main.js最上方从electron引入ipcMain主进程对象
const { app, BrowserWindow, ipcMain } = require("electron");
在electron文件下mian.js文件末尾添加监听代码,注意是独立的方法块,不包含在任何代码块中, 是一个单独的javascript代码。
ipcMain.handle("getDirectoryContent", (event, directoryPath) => {
return new Promise((resolve, reject) => {
fs.readdir(directoryPath, (err, filesList) => {
if (err) {
reject(err);
return;
}
resolve(filesList);
});
});
});
再添加一个读取文件的方法electron文件夹中的main.js当中引入node.js的fs类。
const fs = require("fs");
2.1 preLoad.js代码
window.ipcRenderer = require('electron').ipcRenderer;
只写这一行就够了,目前就是从electron里面得到ipcRender对象,这样这个对象已要赋值给html window对象的一个自定义属性_ipcRenderer了,如果不赋值给window,使用import引入的话,会找不到这个方法。
2.2 在Vue页面进行使用
<script>
import { ref } from "vue";
export default {
setup() {
const items = ref([]);
const fs = require("fs");
let directoryPath = "/Users/xxx/Desktop/xxxx"; // 替换为实际的目录路径
async function getCatalogue(path) {
try {
const filesList = await window.ipcRenderer.invoke(
"getDirectoryContent",
path
);
//此时filesList即是访问指定路径的文件夹数据
//利用循环使用fs的statSync方法 区分访问的文件夹目录里面 那些是文件夹和文件
const itemsList = await Promise.all(
filesList.map(async (file) => {
const filePath = `${path}/${file}`;
const state = fs.statSync(filePath);
return {
name: file,
isDirectory: state.isFile(),
};
})
);
items.value = itemsList;
} catch (err) {
console.error(err);
}
return Promise.resolve();
}
getCatalogue(directoryPath);
return {
items,
};
},
};
</script>
这样 就完成了访问本机电脑文件的流程。如果要操作文件夹,同样是使用node里面的API进行操作