需求背景
甲方要求需要将交付项目打包成.exe文件,这里选用electron来实现该需求(也可以使用nw.js )。
实现方案
方案一:
将自己的 vue 项目进行相关配置后进行打包,放到官方的提供的 demo 文件中,改变打包路径之后再打包成.exe文件。
方案二:
在自己Vue项目中引入插件再进行打包。
我最终选择方案一来实现该需求,因为比较简单快捷,但是打包过程中也遇到了很多问题。
实现步骤
第一步:登录你的GitHub账号(我当时未登录账号,克隆好几次都失败了),然后通过如下命令将官方demo克隆到本地,然后安装依赖包:
git clone https://github.com/electron/electron-quick-start
npm i // 安装依赖包
在安装依赖包的时候,我遇到了node版本过低的问题,我当时node版本是14.16.0,但是终端提醒的版本必须大于14.17.5 ,我推荐大家使用16+版本
CANNOT RUN WITH NODE 14.16.0
Electron Packager requires Node >= 14.17.5.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
至于怎么去动态切换node版本,这里推荐大家使用NVM,node版本控制工具,详细安装教程可以参考这篇文章。nvm安装和使用保姆级教程(详细)一、 nvm是什么 : nvm全英文也叫node.js version management,是一个nodejs的版本管理工具。nvm和npm都是node.js版本管理工具,为了解决node.js各种版本存在不兼容现象可以通过它可以安装和切换不同版本的node.js。 二、卸载之前安装的node: …http://www.xbhp.cn/news/64284.html
注意:一定要将node的npm安装镜像源设置成淘宝镜像,否则会遇到npm下载不成功的问题。
第二步:当你安装依赖包成功之后,我们对打包项目进行配置。
首先修改vue.config.js文件,
module.exports = {
publicPath: './', // vue-cli3项目如果有该项配置,则将值修改为‘./’, 没有则添加
assetsPublicPath: './', // vue-cli2项目使用该配置项
}
然后npm run build进行打包,将打包完成后的dist包直接拖入electron-quick-start 项目根目录下,如图
第三步:对electron-quick-start 进行相关操作
首先删除该项目下的index.html文件,并且对main.js内容进行修改:
# main.js
mainWindow.loadFile('index.html') // 原文件
mainWindow.loadFile('./dist/index.html') // 替换原文件
然后,安装打包.exe所需要的依赖electron-packager、electron,执行如下命令,
npm i electron-packager --save-dev 或 npm i electron-packager -D
npm i electron --save-dev 或 npm i electron -D
注意:很多人在安装依赖包的时候会遇到安装不成功的问题,这是由于镜像源问题,如果你也遇到了请先运行如下命令:
// 如果本地全局的镜像源已经是淘宝镜像,只需执行第二条命令
npm config set registry https://registry.npm.taobao.org/
npm config set ELECTRON_MIRROR http://npm.taobao.org/mirrors/electron/
成功之后,再对项目package.json进行相应修改:
"scripts": {
"start": "electron .",
"packager": "electron-packager ./ Vite App --platform=win32 --arch=x64 --icon=./dist/favicon.ico --overwrite"
},
// 如果不需要自动匹配dist文件夹下的应用图标使用该内容
"electron-packager ./ Vite App --platform=win32 --arch=x64 --overwrite"
Vite App // 这个位置是设置打包后的.exe文件名,可以自定义进行替换
最后,执行npm run packager命令就可以完成打包了,执行完之后就可以在如图目录下找到.exe文件了!
问题来了
打包问题是解决了,但是打包之后的.exe文件,打开之后无法发送网络请求,并且请求是以file:///api/login开头的,但是本地代理服务一切正常。
原因:
是由于对electron-quick-start项目的main.js(入口文件)中设置了win.loadFile访问了本地index.html文件导致。
function createWindow () {
// Create the browser window.
Menu.setApplicationMenu(null) // 去掉默认菜单列表
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
webSecurity: false, // 允许跨域
}
})
// Load a remote URL
mainWindow.loadURL('http://192.168.0.241:9999')
// and load the index.html of the app.
mainWindow.loadFile('./dist/index.html')
// Open the DevTools.
mainWindow.webContents.openDevTools() // 打开调试工具
}
看了electron官网,也试了很多网上的很多方法,最终亲测了两种方法:
方法一:
在项目打包之前直接将axios实例中的baseUrl写成需要的服务域名,如下:
const service = axios.create({
baseURL: 'https://xxx.xxx.net' + apiBaseUrl,
timeout: 15000 // 请求超时时间
})
方法二:
将服务器地址直接注入到vue原型上,如下:
# 这样写也是为了避免影响本地服务代理
Vue.prototype.$api = process.env.NODE_ENV === 'development' ? "/api" : "http://xxx.xxx.net/api";
# 然后修改axios实例
const service = axios.create({
baseURL: this.$api,
timeout: 15000 // 请求超时时间
})
其实上面两种方法如出一辙,只是第二种方法考虑的场景比较全,更加灵活一些。
再次发现问题
经过上面的操作后,再次打包,服务问题是解决了,但是新的问题又来了。在打开.exe文件后,项目路由无法跳转。
经调研,在electron打包后的文件中是不支持history路由模式的,只支持hash路由模式。
所以,修改项目路由模式,如下:
const router = new Router({
mode: 'hash', // history || hash
})
到这里,才算真正完成了vue项目打包成.exe所有流程。
总结
首先,感谢小伙伴能够阅读到这里,如果文章中发现有异议的地方及时评论,我及时修正,希望能够帮助到遇到同样问题的小伙伴,点个赞呗