编译后的Vue的配置文件

273 阅读2分钟

开发环境

Vue3 + Vite

需求

我司有个项目,要求前端同时适配Nginx服务器和electron桌面端。可是vue打包后已经无法修改参数。

第一阶段

这个阶段是想着能否利用electron拦截功能,做出和Nginx反向代理相同的功能,于是经过和ChatGPT的友好交流,就有了利用electron session的拦截功能的代码:

//main.js
const { app, BrowserWindow, session } = require('electron')
const path = require('path')
const url = require('url')

const auth_path = "/auth/api";
const data_path = "/api/v1";
const ws_path = "/websocket";
const proxy_map = {
    "/api/v1": "http://xxxx:xxxx", //主接口,
    "/auth/api": "http://xxxx:xxxxx", // 认证接口
    "/websocket": "http://xxxx:xxxxx", // websocket接口
};

const createWindow = () => {
    // 创建浏览窗口
    const mainWindow = new BrowserWindow({
        width: 1400,
        height: 800,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js')
        },
        icon: path.join(__dirname, './assert/favicon.ico'),
        
    })
    mainWindow.loadFile(path.join(__dirname, './dist/index.html'))
    mainWindow.maximize()
    // 打开开发工具
    // mainWindow.webContents.openDevTools();
}

app.whenReady().then(() => {
    createWindow()
    session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
        const parsedUrl = url.parse(details.url)
        if (parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') {
            callback({});
            return
        }

        let auth_pos = details.url.indexOf(auth_path)
        if (auth_pos >= 0) {
            let real_path = details.url.substring(auth_pos);
            callback({ redirectURL: proxy_map[auth_path] + real_path });
            return;
        }
        let data_pos = details.url.indexOf(data_path)
        if (data_pos >= 0) {
            let real_path = details.url.substring(data_pos);
            callback({ redirectURL: proxy_map[data_path] + real_path });
            return;
        }
        let ws_pos = details.url.indexOf(ws_path)
        if (ws_pos >= 0) {
            let real_path = details.url.substring(ws_pos);
            callback({ redirectURL: proxy_map[ws_path] + real_path });
            return;
        }
        
        callback({});
    });
})

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
})

这段代码就是拦截非HTTP的请求。因为安装Nginx的代理写法,Electron会认为是文件请求。拦截下的请求安装map转向真正的http请求。

结果

就是成功了一半。这样搞能成功拦截http请求,但是无法重定向websocket。还是那个GPT,他说像websocket这种长链接一般是无法重定向的,比较好的办法是建立一个websocket服务器进行转发,我觉得太麻烦就放弃了。

第二阶段

于是转向了针对vue的配置文件的操作。

1 直接引入

事实上,直接引入JSON

import Settings from "../../public/settings.json";

是可以实现的,而且也能正确识别。可是打包的时候,Vite会直接把JSON文件内容值当成一个变量打包,打包后无论如何改变配置文件都无法改变dist包内的变量值。

2 axios 引入

这个方案主要需要考虑axios是异步操作,只有等结果到达之后才能初始化vue。

//main.js
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import router from './router';
import axios from "axios";

axios.get("/settings.json").then((data)=>{
    let settings = data.data;
    const app = createApp(App)
    app.config.globalProperties.settings = settings;
    app.provide("settings", settings);
    app.use(createPinia())
    app.use(router)
    app.mount('#app');
}).catch((error)=>{
    console.log(error)
});

在这里,提供了两种使用setting的方式: globalProperties 和 provide ,个人比较建议使用 provide 方式。

setting 参数使用

//app_settings.js
class AppSettings {
    constructor() {
        //...
    }
    set_settings(settings) {
        //...
    }
}
const app_settings = new AppSettings();
export default app_settings;

个人比较建议参数统一在某个类中进行管理和使用。

<script setup>
//App.vue
import {ref, nextTick, provide, inject} from "vue";
import app_settings from "./app_settings";

const settings = inject("settings");
app_settings.set_settings(settings);
</script>

然后在App.vue中重新设置参数。

现在,你就可以在别的各个组件中引入app_settings ,然后愉快的使用可配置参数拉!enjoy!!!!