开发依赖
Node.js 版本 16.13.1
官网地址:https://nodejs.org/zh-cn/
Electron 版本 16.0.4
Semantic UI
官网地址:Semantic UI
Bootstrap UI
Ace.js
官网地址:https://ace.c9.io/
目录结构
built:
src:
arduino:放置与blockly相关代码
assets:放置img、css等一些静态资源
core:核心代码,所有的逻辑功能实现
pluglns:插件
views:放置html文件、目前有启动页和主页
app.js:在html中调用的js文件
main.js:electron需要的主文件
target.js:配置文件、放置一些配置信息
package.json:定义需要的各种模块
uncompressed.js:没有编译的逻辑代码,这个主要负责将我们编写的代码实现在 home.html引用,后面新增的js文件就不再html中引用,而是在uncompressed.js添加间 接引用,之所以这个文件名称为uncompressed,是因为当我们发布后要压缩代码,所 以叫未编译
我们进入src下,执行如下命令,我使用的cnpm,执行完了就多了一个 node_modules文件夹
cnpm install
其中package.json代码如下:里面定义了需要用到的各种模块以及版本
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "main.js",
"build": {
"appId": "com.me.app",
"mac": {
"icon": "../build/logo.icns",
"target": [
"dmg"
]
},
"win": {
"icon": "../build/logo.ico",
"target": [
"zip"
]
},
"directories": {
"output": "../dist"
},
"asar": true,
"extraResources": [
{
"from": "../../cli/linux/arduino",
"to": "../arduino"
}
]
},
"dependencies": {
"jquery": "^3.6.0",
"serialport": "^9.2.8"
},
"devDependencies": {
"electron": "^16.0.4",
"electron-builder": "^22.14.5",
"electron-rebuild": "^3.2.3",
"google-closure-compiler": "20180402.0.0",
"google-closure-library": "20190301.0.0"
},
"scripts": {
"start": "electron .",
"build-win": "sudo electron-builder --win",
"build-mac": "sudo electron-builder --mac",
"build-linux": "sudo electron-builder --linux",
"build-linux-arm": "sudo electron-builder --linux --arm64"
}
}
main.js 代码如下,这个electron的主进程
const electron = require('electron');
const {ipcMain} = require("electron");
const App = electron.app;
const Dialog = electron.dialog;
const BrowserWindow = electron.BrowserWindow;
const path = require('path');
const url = require('url');
const SerialPort = require('serialport');
const os = require('os');
const fs = require("fs");
const process = require('process');
const isMac = os.type() === 'Darwin';
const isLinux = os.type() === 'Linux';
const isWin = os.type() === 'Windows_NT';
electron.Menu.setApplicationMenu(null);
function Lzm() {
// 主窗口
this.home = null;
// 启动窗口
this.start = null;
// 串口
this.serialPort = null;
}
/**
* 创建主窗口
*/
Lzm.prototype.createMainWindow = function(callback) {
// 创建主窗口
this.home = new BrowserWindow({
title: 'AudDemo',
width: 1200,
height: 720,
minWidth: 800,
minHeight: 600,
backgroundColor: '#FFF',
plugins: true,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
contextIsolation: false,
},
show: false,
});
// 绑定Html
this.home.loadURL(url.format({
pathname: path.join(__dirname, 'views/home.html'),
protocol: 'file:',
slashes: true
})).then();
// 首次启动
this.home.once('ready-to-show', () => {
callback();
this.home.show();
});
// 关闭时
this.home.on('close', (e) => {
this.home.webContents.send("close-app");
e.preventDefault();
});
// 关闭后
this.home.on('closed', () => {
this.home = null;
});
// 调试工具
// this.home.webContents.openDevTools();
};
/**
* 创建启动界面
*/
Lzm.prototype.createStartWindow = function() {
//获取屏幕像素计算窗口大小
const size = electron.screen.getPrimaryDisplay().workAreaSize;
let width = parseInt((Math.min(size.height, size.width) / 2).toString());
let height = parseInt((width * 0.75).toString());
//创建启动界面
this.start = new BrowserWindow({
width: width,
height: height,
minWidth: width,
minHeight: height,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
contextIsolation: false,
},
transparent: true,
frame: false,
show: false
});
//加载启动页面
this.start.loadURL(url.format({
protocol: 'file:',
pathname: path.join(__dirname, 'views/start.html'),
})).then();
//启动一次
this.start.once('ready-to-show', () => {
this.start.show();
});
};
/**
* 绑定
*/
Lzm.prototype.bind = function() {
// 主进程于渲染进程间通信
};
/**
* 应用准备完成
*/
App.on('ready', function() {
const lzm = new Lzm();
// 创建启动页
lzm.createStartWindow();
// 绑定监听
lzm.bind();
});
/**
* 退出
*/
App.on('window-all-closed', function() {
App.quit();
});
app.js 我们暂时不需要编写代码
在views/start.html 代码如下,这个主要是用来显示启动界面,我们可以做一些与处理的操作,当然现在我们不需要,只是一个演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="../plugins/bootstrap/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../plugins/semantic/semantic.min.css">
<link rel="stylesheet" href="../assets/css/style.css">
<script>window.$ = window.jQuery = require('jquery');</script>
</head>
<style>
.start-page {
width: 100%;
height: 100%;
background-image: linear-gradient(#063737, #063737, #0c7272);
padding: 0;
}
.name {
text-align: center;
position: absolute;
padding-top: 4rem;
top: 25%;
width: 100%;
height: 50%;
font-size: 4rem;
font-weight: bold;
color: #8dbaba;
}
</style>
<body ondragstart="return false">
<div class="start-page">
<div class="name">Dome</div>
</div>
</body>
<script>
const {ipcRenderer} = require("electron");
ipcRenderer.send("load-config", 0);
// 代码授权使用
// const hour = 48 - Math.ceil((new Date().getTime() - 1639926972171) / 1000 / 60 / 60);
// setTimeout(() => {
// ipcRenderer.send("load-config", hour < 0);
// }, 500);
</script>
</html>
页面大概是这样子
uncompressed.js代码如下,主要实现间接调用其他js,就不反复在home.html中添加引用
/**
* 动态加载
* @type {
{css: dynamicLoading.css, js: dynamicLoading.js}}
*/
const dynamicLoading = {
css: function(path) {
if (!path || path.length === 0) {
throw new Error('argument "path" is required !');
}
const head = document.getElementsByTagName('head')[0];
const link = document.createElement('link');
link.href = path;
link.rel = 'stylesheet';
link.type = 'text/css';
head.appendChild(link);
},
js: function(path) {
if (!path || path.length === 0) {
throw new Error('argument "path" is required !');
}
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = path;
script.type = 'text/javascript';
head.appendChild(script);
}
};
/**
* 需要加载的js文件,无需写后缀 例如 jsFiles = ["test"]
* @type {string[]}
*/
const jsFiles = [];
//动态加载 JS 文件
for (let i = 0, file; (file = jsFiles[i]); i++) {
dynamicLoading.js("../" + file + '.js');
}
在views/home.html 代码如下,这个用于主窗口内容显示的文件,其中插件也是在此引用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="../plugins/bootstrap/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../plugins/semantic/semantic.min.css">
<link rel="stylesheet" href="../assets/css/style.css">
<script>window.$ = window.jQuery = require('jquery');</script>
<script type="text/javascript" src="../plugins/semantic/semantic.min.js"></script>
<script type="text/javascript" src="../plugins/ace/ace.js"></script>
<script type="text/javascript" src="../plugins/ace/ext-language_tools.js"></script>
</head>
<body ondragstart="return false"></body>
<script type="text/javascript" src="../uncompressed.js"></script>
</html>
这样我们的环境就搭建好了,执行下面命令可以运行electron
cd src
electron .
如果不出意外的话,就会看到以下界面,首先是现实启动界面,然后跳转到主界面,因为我什么都没写,所以是一个空白界面
到这里我们已经完成了项目的准备工作,剩下就是编写逻辑。