uniapp package desktop application exe

uniapp has functions such as packaging apps, and the recently taken over project has also implemented uniapp packaging desktop application exe

Article Directory

1. Plug-in Electron

A brief introduction to Electron:

Electron is a cross-platform desktop application built using JavaScript, HTML, and CSS. It is based on Node.js and Chromium and is used by the Atom editor and many other applications.

Electron is compatible with Mac, Windows and Linux , and can build applications for three platforms.

2. Use steps

1. Install the electron plugin globally

The code is as follows (example):

npm install electron -g // 安装electron(主程序)
npm install electron-packager -g // 安装electron-packager(打包用)

Two problems arise:

  • Question 1: Solve the problem that npm download is too slow
安装淘宝的cnpm:
#在任意目录执行都可以
--global意思为安装到全局
npm install --global cnpm

If you don’t want to install cnpm and want to use Taobao’s server to download packages
npm install jquery --registry=https://registry.npm.taobao.org

But adding parameters manually every time is very troublesome, so we can add this option to the configuration file In:
npm config set registry https://registry.npm.taobao.org

  • Question 2: The following error occurs when installing electron:

connect ETIMEDOUT 20.205.243.166:443

Solution:

ping GitHub.com

If you can ping through, continue the following operations

更改electron安装源。
npm config set ELECTRON_MIRROR https://npmmirror.com/mirrors/electron/

Successful installation

2. Modify manifest.json

The code is as follows (example):

h5 configuration

The basic path of operation is changed to : ./  Otherwise, a white screen will appear when it is packaged, and it cannot be read, because the default loading address of the packaged h5 is /static/

去掉启用https协议Otherwise, the network will fail to load, and removing https will not affect the https protocol on the backend of your request.

The diagram is as follows:

3. H5 packaging

4. Create new package.json and main.js under the H5 folder generated after packaging

The code example is as follows:

  • package.json
{  "name"    : "exam考试系统",  "version" : "0.1.0",  "main"    : "main.js"}

If an error is reported:
error couldn't find a package.json file in

Solution:

This error message means that the packagejson file cannot be found in the current directory. When using npm to install dependent packages, you need to execute the command in the project root directory to ensure that the current directory
There is package.json file. If not, you can  generate a new package.ison file by executing the npm init command.

Execute  the npm init command to generate a new package.ison file as follows:

完整代码:
{
"name": "你的名字(注意不能是中文不能大写)",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"win": {
"icon": "icon.ico"(注意,此处为打包exe文件后生成桌面应用的图标,注意将图标位置放置正确,可直接放在生成的H5中)
}
}
  • New main.js

Points to note :

1. Mainly index.html and icon icon placement (in the example, index.html is in the root directory)

2. Solve the problem that the overall style of clicking the window to maximize is too large (the default is to open the full screen, and the project needs to open the application without full screen, and this problem will occur if you directly set the width and height)

Listen to the will-resize event

The BrowserWindow in Electron will trigger an event before each resizing will-resize, we just need to intercept this event and manually set the window size to the desired size.

//解决点击窗口最大化样式整体过大问题
const WIDTH = 1860
const HEIGHT = 900
const aspectRatio = WIDTH / HEIGHT // 窗口宽高比

win = new BrowserWindow({
// fullscreen: true,
// width: 800,
// height: 600,
width: WIDTH,
height: HEIGHT,
// frame: false, // 无边框窗口
webPreferences: {
nodeIntegration: true, // 使渲染进程拥有node环境

}

})


win.once('ready-to-show', () => {
// 限制窗口最小尺寸(int整形), 无边框模式下,不考虑标题栏高度
win.setMinimumSize(WIDTH / 2, HEIGHT / 2)
win.show()
})

// 控制等比缩放
win.on('will-resize', resizeWindow)

function resizeWindow(event, newBounds) {
const wins = event.sender
event.preventDefault() // 拦截,使窗口先不变
const currentSize = wins.getSize()
const widthChanged = currentSize[0] !== newBounds.width // 判断是宽变了还是高变了,两者都变优先按宽适配
// ! 虽然搞不懂为何有1px偏差,但是可以解决问题(Windows 10)
if (widthChanged) {
wins.setContentSize(newBounds.width - 1, parseInt(newBounds.width / aspectRatio + 0.5) - 1)
} else {
wins.setContentSize(parseInt(aspectRatio * newBounds.height + 0.5) - 1, newBounds.height - 1)
}
}

3.win.webContents.openDevTools() Open the debug box -------- ( shift + ctrl + i shortcut key )

4.Menu.setApplicationMenu(null) close the top navigation menu bar

The complete main.js code is as follows:

const {
app,
BrowserWindow,
ipcMain
} = require('electron')
const fs = require('fs')
const electron = require('electron')
const path = require('path')
const url = require('url')

// ipcMain.on('asynchronous-message', function(event, arg) {
//    // arg是从渲染进程返回来的数据
//   console.log(arg,1);

//   // 这里是传给渲染进程的数据C:/Users/Administrator/Desktop/test.txt
//   fs.readFile(path.join(__dirname,"./test.txt"),"utf8",(err,data)=>{
//    if(err){
// event.sender.send('asynchronous-reply', "读取失败");
// }else{
// event.sender.send('asynchronous-reply', data);
// }

//   })
// });

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
const Menu = electron.Menu

function createWindow() {
// Create the browser window.
// Menu.setApplicationMenu(null)

//解决点击窗口最大化样式整体过大问题
const WIDTH = 1860
const HEIGHT = 900
const aspectRatio = WIDTH / HEIGHT // 窗口宽高比


win = new BrowserWindow({
// fullscreen: true,(设置默认打开满屏)
// width: 800,
// height: 600,
width: WIDTH,
height: HEIGHT,
// frame: false, // 无边框窗口
webPreferences: {
nodeIntegration: true, // 使渲染进程拥有node环境

},
icon: path.join(__dirname, 'icon.ico') // 设置ico

})


win.once('ready-to-show', () => {
// 限制窗口最小尺寸(int整形), 无边框模式下,不考虑标题栏高度
win.setMinimumSize(WIDTH / 2, HEIGHT / 2)
win.show()
})

// 控制等比缩放
win.on('will-resize', resizeWindow)

function resizeWindow(event, newBounds) {
const wins = event.sender
event.preventDefault() // 拦截,使窗口先不变
const currentSize = wins.getSize()
const widthChanged = currentSize[0] !== newBounds.width // 判断是宽变了还是高变了,两者都变优先按宽适配
// ! 虽然搞不懂为何有1px偏差,但是可以解决问题(Windows 10)
if (widthChanged) {
wins.setContentSize(newBounds.width - 1, parseInt(newBounds.width / aspectRatio + 0.5) - 1)
} else {
wins.setContentSize(parseInt(aspectRatio * newBounds.height + 0.5) - 1, newBounds.height - 1)
}
}

// and load the index.html of the app.
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
//cpu


// Open the DevTools.
// win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null
})

// ipcMain.on('asynchronous-message', function(event, arg) {
//    // arg是从渲染进程返回来的数据
//   console.log(arg,2);

//   // 这里是传给渲染进程的数据C:/Users/Administrator/Desktop/test.txt
//   fs.readFile(path.join(__dirname,"./test.txt"),"utf8",(err,data)=>{
//    if(err){
// event.sender.send('asynchronous-reply', "读取失败");
// }else{
// event.sender.send('asynchronous-reply', data);
// }

//   })
// });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})

app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.



Note: There is a problem when solving the window style too large problem

Clicking on the right slide will result in the following error :

Error
A JavaScript error occurred in the main process
Uncaught Exception:
TypeError: Cannot read properties of undefined (reading 'getSize')
at BrowserWindow.resizeWindow
(E:\desktop\shb-win32-x64\resources\app.asar\main.js:71:28)
at BrowserWindow.emit(node:events:513:28)

At present, this problem has not been resolved, please give me your advice

5. Final packaging

1.electron-packager . 可执行文件的文件名 --win --out 打包成的文件夹名 --arch=x64位还是32位 --electron-version版本号(不是你的h5版本号,是electron版本号) --overwrite --ignore=node_modules
例如:electron-packager . myAPP --win --out appDist --arch=x64 --electron-version 23.1.0 --overwrite --ignore=node_modules

If the packaging speed is slow first, you can use the mirror packaging method

2.electron-packager . appName --platform=win32 --electron-version=10.0.0 --arch=x64 --download.mirrorOptions.mirror=https://npm.taobao.org/mirrors/electron/ --asar --app-version=0.0.0 --build-version=0.0.0 --out=outName --overwrite --no-package-manager --ignore="(.git)" --icon=logo.ico

Run the command to package, and then there will be an App-win32-x64 folder in the project. This file is the packaged desktop application. There is an App.exe file in the folder. App.exe is the startup file of this project


Summarize

The above is what I want to talk about today. This article only briefly introduces the uniapp packaged desktop application exe , and electron provides a large number of functions and methods that allow us to process data quickly and conveniently. For details, please refer to the official website of electron .

Guess you like

Origin blog.csdn.net/z_2183441353/article/details/132624030