vue中electron框架自定義外部配置文件的配置與讀取辦法
簡(jiǎn)介
在vue2.6版本后,會(huì)生成vue.config.js文件,本文章主要講解如何在vue中,如何生成electron的外部配置文件,與如何讀取外部配置文件。
一、配置與生成config.json文件
首先,要在項(xiàng)目下新建一個(gè)config.json文件,然后再config文件中,寫(xiě)入一些信息。

然后在vue.config.js中寫(xiě)入配置,通知electron在打包時(shí),不要將指定文件打包進(jìn)app.asar中。
pluginOptions: {
electronBuilder: {
builderOptions: {
// build配置在此處
// options placed here will be merged with default configuration and passed to electron-builder
appId: "com.emr.app",
extraResources: [
{ "from": "./config.json", "to": "../" }
],
"mac": { "icon": "./public/favicon.icns" },
"win": { "icon": "./public/favicon.ico" } // 配置打包后,在win下的應(yīng)用圖標(biāo)。ico圖片至少要是256*256尺寸的,尺寸太小,會(huì)打包失敗。
}
},
},
這里附上我的vue.config.js文件的配置,方便大家理解
const webpack = require('webpack')
module.exports = {
lintOnSave: false,
publicPath: "./",
// PC端適配代碼
// css: {
// loaderOptions: {
// css: {},
// postcss: {
// plugins: [
// require("postcss-px2rem")({
// remUnit: 192, // 以1920屏幕為標(biāo)準(zhǔn)來(lái)縮放網(wǎng)頁(yè)
// propList: ['*', '!border', '!font-size'], // border屬性不進(jìn)行適配
// })
// ]
// }
// }
// },
chainWebpack: config => {
config.plugin('provide').use(webpack.ProvidePlugin, [{
$: 'jquery',
jquery: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}])
},
configureWebpack: {
resolve: {
alias: {}
}
},
pluginOptions: {
electronBuilder: {
builderOptions: {
// build配置在此處
// options placed here will be merged with default configuration and passed to electron-builder
appId: "com.emr.app",
extraResources: [
{ "from": "./config.json", "to": "../" },
{ "from": "./MatchDownloader.exe", "to": "../" },
{ "from": "./download.bat", "to": "../" },
],
"mac": { "icon": "./public/favicon.icns" },
"win": { "icon": "./public/favicon.ico" }
}
},
},
// 代理
/* devServer: {
port: 8080,
// host: 'localhost',
https: false, // https:{type:Boolean}
open: true, // 配置自動(dòng)啟動(dòng)瀏覽器
disableHostCheck: true,
"proxy": {
"/*": {
"target": "http://xxx",
"changeOrigin": true
}
}
}, */
}然后,在執(zhí)行npm run electron:build命令后,就可以在打包后的文件里看到config.json文件被獨(dú)立出來(lái)了。

至此,就完成了第一步,配置與生成config.json這個(gè)外部配置文件了。
二、讀取外部配置文件 ---- config.json
至此,我們已經(jīng)有了config.json這個(gè)外部配置文件,要讀取這個(gè)文件的配置信息,就要用到electron的remote模塊,這個(gè)模塊不同electron版本的獲取方式不同,這個(gè)用了是electron13.0.0的獲取方法。
首先,要在electorn的入口文件(我項(xiàng)目里的是background.js)里,做一些配置,讓html頁(yè)面能訪問(wèn)node里面的fs模塊,方便調(diào)用fs來(lái)讀取文件。
// main.js
'use strict'
// Modules to control application life and create native browser window
// const { app, BrowserWindow } = require('electron')
import moment from "moment"
import { app, protocol, BrowserWindow, globalShortcut } from 'electron'
import { createProtocol, installVueDevtools } from 'vue-cli-plugin-electron-builder/lib'
// 設(shè)置運(yùn)行內(nèi)存350MB
process.env.NODE_OPTIONS = '--no-warnings --max-old-space-size=350'
// app.commandLine.appendSwitch('disable-site-isolation-trials'); // //這行一定是要加的,要不然無(wú)法使用iframe.contentDocument方法
const { ipcMain, Menu, MenuItem, shell } = require('electron')
const path = require('path')
const fs = require('fs')
const exePath = path.dirname(app.getPath('exe'))
const localFileUrlList = { // 要生成的文件的本地文件路勁
'app.asar': {
win: '\\resources\\app.asar',
mac: '/resources/app.asar'
},
'update.asar': {
win: '\\resources\\update.asar',
mac: '/resources/update.asar'
},
'download.bat': {
win: '\\download.bat',
mac: '/download.bat'
}
}
// console.log("exePath", exePath)
const menuContextTemplate = [
{ label: '復(fù)制', role: 'copy' }, // 使用了role,click事件不起作用
{ label: '粘貼', role: 'paste' }
]
const menuBuilder = Menu.buildFromTemplate(menuContextTemplate)
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{
scheme: 'app',
privileges: {
secure: true,
standard: true
}
}])
function showGoBackMenu (mainWindow) {
const template = [{
label: '返回',
submenu: [{
label: '返回上一頁(yè)',
click: () => { mainWindow.webContents.goBack() }
}]
},
{
label: '刷新', // 重新加載代碼
accelerator: 'CmdOrCtrl+R',
click: function (item, focusedWindow) {
if (focusedWindow) {
focusedWindow.reload()
}
}
}
]
// 構(gòu)建菜單模版
const m = Menu.buildFromTemplate(template)
// 設(shè)置菜單模版
Menu.setApplicationMenu(m)
}
function deleteOldLogFiles() {
let rententionPeriodInMs = 7 * 24 * 60 * 60 * 1000
let now = new Date().getTime()
// 時(shí)間閾值,創(chuàng)建時(shí)間早于此閾值,則刪除對(duì)應(yīng)文件
let thresholdTime = now - rententionPeriodInMs
let LogsFolderPath = path.join(exePath, "logs")
console.log("LogsFolderPath", LogsFolderPath)
let files = fs.readdirSync(LogsFolderPath)
files.forEach(file => {
let filePath = path.join(LogsFolderPath, file)
let fileStat = fs.statSync(filePath) // 返回文件的文件信息
let createTimeOfFile = fileStat.ctimeMs // 獲取文件的創(chuàng)建時(shí)間
if (createTimeOfFile < thresholdTime) {
fs.unlinkSync(filePath)
}
})
}
const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
title: '',
webPreferences: {
// preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true, // 允許html頁(yè)面上的javascipt代碼訪問(wèn)nodejs 環(huán)境api代碼的能力
enableRemoteModule: true, // 是否允許使用remote
contextIsolation: false,
// 加載本地圖片
webSecurity: false, // 允許跨域
webviewTag: true // 允許webview
},
icon: path.join(__static, './favicon.ico'),
show: false,
autoHideMenuBar: true, // 隱藏頂部工具欄,生產(chǎn)環(huán)境時(shí)設(shè)置為true
frame: false // 無(wú)邊框
})
let timeStr = moment(new Date()).format("YYYY-MM-DD HH:mm:ss")
let dateStr = moment(new Date()).format("YYYY-MM-DD")
let LogsFolderPath = path.join(exePath, "logs")
let logFilePath = path.join(LogsFolderPath, `log-${dateStr}.log`)
// 如果文件夾不存在,則新建
if (!fs.existsSync(LogsFolderPath)) {
fs.mkdirSync(LogsFolderPath)
}
// 刪除7天前的日志文件,節(jié)約硬盤(pán)空間
deleteOldLogFiles()
// 監(jiān)聽(tīng)控制臺(tái)錯(cuò)誤輸出的事件
mainWindow.webContents.on('console-message', (event, level, message, line, sourceId) => {
if (level === 3) { // 3 代表錯(cuò)誤級(jí)別
const logMessage = `[${timeStr}] ${message}\n`;
fs.appendFileSync(logFilePath, logMessage);
console.error(logMessage);
}
});
// 生產(chǎn)環(huán)境下隱藏此函數(shù)
// showGoBackMenu(mainWindow)
globalShortcut.register('CommandOrControl+Shift+i', function () {
mainWindow.webContents.openDevTools()
})
mainWindow.maximize()
mainWindow.show()
createProtocol('app')
mainWindow.loadURL('http://localhost:8080') // 跑本地開(kāi)啟這行,打包的時(shí)候注掉這行
// mainWindow.loadURL(`app://./index.html`); //打包的時(shí)候開(kāi)啟這行,跑本地注掉這行
// 1. 窗口 最小化
ipcMain.on('window-min', function () { // 收到渲染進(jìn)程的窗口最小化操作的通知,并調(diào)用窗口最小化函數(shù),執(zhí)行該操作
mainWindow.minimize()
})
// 2. 窗口 最大化、恢復(fù)
ipcMain.on('window-max', function () {
if (mainWindow.isMaximized()) { // 為true表示窗口已最大化
mainWindow.restore() // 將窗口恢復(fù)為之前的狀態(tài).
} else {
mainWindow.maximize()
}
})
// 3. 關(guān)閉窗口
ipcMain.on('window-close', function () {
mainWindow.close()
})
// 刷新窗口
ipcMain.on('window-reload', function () { // 收到渲染進(jìn)程的窗口最小化操作的通知,并調(diào)用窗口最小化函數(shù),執(zhí)行該操作
mainWindow.reload()
})
ipcMain.on('show-context-menu', function () {
menuBuilder.popup({
window: BrowserWindow.getFocusedWindow()
})
})
ipcMain.on('print-view', function () {
const win = new BrowserWindow({ width: 800, height: 600 })
// 打開(kāi)新窗口 BrosweWindow 初始化
win.loadURL('http://www.baidu.com')
win.webContents.printToPDF({ pageSize: 'A4', printBackground: true }, (error, data) => {
console.log('---------------------------------:', data)
if (error) throw error
debugger
fs.writeFile('print.pdf', data, (error) => {
if (error) throw error
console.log('Write PDF successfully.')
})
})
})
// json: { downloadUrl: "", targetPath: "C:\\...", fileName: "config.json" }
ipcMain.on('system-update', function (event, { json, asar }) {
console.log('system-update', asar)
const request = require('request')
const req = request({ method: 'GET', uri: json.downloadUrl })
const out = fs.createWriteStream(json.targetPath)
req.pipe(out)
req.on('end', function () {
const batPath = getFilePath('download.bat')
// console.log("batPath", batPath)
const fileData = `MatchDownloader.exe /opt url ${asar.downloadUrl} process Match-EMR.exe src ~/resources/update.asar dest ~/resources/app.asar`
fs.writeFileSync(batPath, fileData)
shell.openPath(batPath) // 打開(kāi)bat文件
app.quit() // 關(guān)閉應(yīng)用
})
})
}
app.whenReady().then(async () => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// 除了 macOS 外,當(dāng)所有窗口都被關(guān)閉的時(shí)候退出程序。 There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
function getFilePath (localFileName) {
console.log('localFileName', localFileName)
if (getSystem() === 1) {
return exePath + localFileUrlList[localFileName].mac
} else {
return exePath + localFileUrlList[localFileName].win
}
}
function getSystem () {
// 這是mac系統(tǒng)
if (process.platform == 'darwin') {
return 1
}
// 這是windows系統(tǒng)
if (process.platform == 'win32') {
return 2
}
// 這是linux系統(tǒng)
if (process.platform == 'linux') {
return 3
}
}關(guān)鍵配置就在102行附近,createWindow函數(shù)的new BrowserWindow里,nodeIntegration: true和enableRemoteModule: true。這2個(gè)配置,一個(gè)是允許頁(yè)面支持node環(huán)境及其api調(diào)用。一個(gè)允許頁(yè)面使用remote對(duì)象。
其次,新建一個(gè)getBaseUrl.js文件
const path = window.require && window.require("path");
const fs = window.require && window.require("fs");
const electron = window.require && window.require('electron')
export function getSystem() {
//這是mac系統(tǒng)
if (process.platform == "darwin") {
return 1;
}
//這是windows系統(tǒng)
if (process.platform == "win32") {
return 2;
}
//這是linux系統(tǒng)
if (process.platform == "linux") {
return 3;
}
}
/**
*
* @returns 獲取安裝路徑
*/
export function getExePath() {
// return path.dirname("C:");
return path.dirname(electron.remote.app.getPath("exe"));
}
/**
*
* @returns 獲取配置文件路徑
*/
export function getConfigPath() {
if (getSystem() === 1) {
return getExePath() + "/config.json";
} else {
return getExePath() + "\\config.json";
}
}
/**
* 讀取配置文件
*/
export function readConfig() {
return new Promise((res, rej) => {
console.log("fs", fs)
fs.readFile(getConfigPath(), "utf-8", (err, data) => {
let config = ""
if (data) {
//有值
config = JSON.parse(data)
}
res(config)
})
})
}這個(gè)文件的readConfig函數(shù),就是獲取config文件的函數(shù)。所以外部只要調(diào)用這個(gè)readConfig函數(shù),就可以獲取外部配置文件的信息了(你可以在main.js里調(diào)用,就是在項(xiàng)目加載時(shí),就讀取config.json這個(gè)配置文件)。
例如:
import { readConfig } from '@/utils/getBaseUrl.js'
// let applicationType = 'website' // 如果最后打包的是網(wǎng)站,就打開(kāi)這個(gè)
let applicationType = "exe" // 如果最后打包的是exe應(yīng)用,就打開(kāi)這個(gè)
if (applicationType === 'exe') {
(async function () {
const res = await readConfig()
axios.defaults.baseURL = res.baseUrl
Vue.prototype.$baseURL = res.baseUrl
window.$config = res
})()
}
// 因?yàn)槲以瓉?lái)的項(xiàng)目是可以打包成網(wǎng)站與桌面應(yīng)用,但是在網(wǎng)頁(yè)版中,window.require('electron')返回的是undefined,所以這里才會(huì)用applicationType來(lái)區(qū)分,如果打包后的是exe應(yīng)用時(shí),才去讀取安裝目錄下的config.json文件
最后
這篇文章就講這個(gè)外部配置文件的生成與獲取,如果大家有興趣的話,會(huì)找個(gè)時(shí)間分享一下,electron的桌面的版本更新下載的功能,就像其他桌面應(yīng)用一樣,點(diǎn)擊更新按鈕,自動(dòng)下載與更新應(yīng)用的功能。
附上我當(dāng)前項(xiàng)目的vue與electron版本
"vue": "^2.6.11", "electron": "^13.0.0", "electron-packager": "^15.4.0",
附:Electron 實(shí)現(xiàn)打包后動(dòng)態(tài)配置應(yīng)用參數(shù)
實(shí)現(xiàn)一款交互屏桌面應(yīng)用軟件,類似醫(yī)院那張種給用戶操作辦理業(yè)務(wù)的應(yīng)用程序。應(yīng)用程序需要多點(diǎn)放置,根據(jù)放置地點(diǎn)的不同給應(yīng)用做配置
- 開(kāi)發(fā)框架:electron-vue
- vue版本:v2.6.14
- electron版本:v17.2.0
- node版本:v16.13.0
實(shí)現(xiàn)
在架構(gòu)的根目錄下創(chuàng)建一個(gè)config.conf文件,作為動(dòng)態(tài)配置的入口。文件內(nèi)容就是正常的JSON個(gè)是就可以。例如:
{
"STADIUM_ID":"112"
}在主進(jìn)程中,定義讀取配置文件的程序:
import { app } from 'electron'
const path = require("path");
const fs = require("fs");
export function getExePath() {
return path.dirname(app.getPath("exe"));
}
export function getConfigPath() {
return getExePath() + "\\config.conf";
}
export function readConfig(callback) {
fs.readFile(getConfigPath(),"utf-8",(err,data) => {
if(data) {
const config = JSON.parse(data);
callback(config)
}else {
callback({STADIUM_ID:102})
}
})
}在ipc中設(shè)置handle事件,作為被調(diào)用的入口:
ipcMain.handle("get-params", (event, args) => {
readConfig(res => {
BrowserWindow.fromWebContents(event.sender).webContents.send(
"get-params-reply",
res
);
});
});在渲染進(jìn)程中,觸發(fā)并使用參數(shù):
ipcRenderer.invoke('get-params')
ipcRenderer.once('get-params-reply',(event,args) => {
this.getStadiumDetail(args.STADIUM_ID);
})到此這篇關(guān)于vue中electron框架自定義外部配置文件的配置與讀取辦法的文章就介紹到這了,更多相關(guān)electron自定義外部配置文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue配置electron使用electron-builder進(jìn)行打包的操作方法
- vue3使用Electron打包成exe的方法與打包報(bào)錯(cuò)解決
- 使用electron打包Vue前端項(xiàng)目的詳細(xì)流程
- 如何使用electron將vue項(xiàng)目打包成.exe文件(保姆級(jí)教程)
- electron+vue?實(shí)現(xiàn)靜默打印功能
- electron-vue中報(bào)錯(cuò)Cannot?use?import?statement?outside?a?module的解決方案(親測(cè)有效!)
- Electron+Vue實(shí)現(xiàn)截屏功能的兩種方式
相關(guān)文章
Vue+Express實(shí)現(xiàn)登錄狀態(tài)權(quán)限驗(yàn)證的示例代碼
這篇文章主要介紹了Vue+Express實(shí)現(xiàn)登錄狀態(tài)權(quán)限驗(yàn)證的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05
vue Tooltip提示動(dòng)態(tài)換行問(wèn)題
這篇文章主要介紹了vue Tooltip提示動(dòng)態(tài)換行問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
一文詳解vue-router中的導(dǎo)航守衛(wèi)
vue-router提供的導(dǎo)航守衛(wèi)主要用來(lái)通過(guò)跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航,在 vue-router 中,導(dǎo)航守衛(wèi)是一種非常重要的功能,所以本文將詳細(xì)講解一下vue-router中的導(dǎo)航守衛(wèi),感興趣的同學(xué)跟著小編一起來(lái)看看吧2023-07-07
vue 地區(qū)選擇器v-distpicker的常用功能
這篇文章主要介紹了vue 地區(qū)選擇器v-distpicker的常用功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07
vue.js的狀態(tài)管理vuex中store的使用詳解
今天小編就為大家分享一篇vue.js的狀態(tài)管理vuex中store的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
vue3-pinia-ts項(xiàng)目中的使用示例詳解
這篇文章主要介紹了vue3-pinia-ts項(xiàng)目中的使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08

