Electron开发一个小应用
保命声明:笔者在校属于中水平学生,代码能力有限,若行文中有错漏之处欢迎大家指出。
项目地址:https://gitee.com/qsbye/electron-app
Electron
作为一个跨平台的桌面应用开发框架,Electron 的迷人之处在于,它是建立在 Chromium 和 Node.js 之上的 —— 二位分工明确,一个负责界面,一个负责背后的逻辑. Electron 能开发跨平台的桌面应用.
安装Electron Fidder集成开发环境
[https://www.electronjs.org/zh/docs/latest/]
[https://www.electronjs.org/fiddle#downloads]
获取数据
获取天气数据
[https://blog.csdn.net/weixin_36018773/article/details/114052637]
[https://www.cnblogs.com/bianchengxia/p/9234037.html]
[https://blog.csdn.net/weixin_42339078/article/details/100150188]
[http://www.tianqihoubao.com/weather/top/guangzhou.html]
[https://www.cnblogs.com/ngz311616/p/9525045.html]
因为使用天气API有限制,所以直接从百度网页获取,例如百度搜索“天气”就会自动根据ip地址给出所在城市的天气预报,获取天气信息几乎是没有限制。
百度天气
[https://weathernew.pae.baidu.com/weathernew/pc?query=广东广州天气&srcid=4982]
选择器路径:
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_shishi > div.op_weather4_twoicon_shishi_info
实时温度
<!--数值-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_shishi > div.op_weather4_twoicon_shishi_info > span.op_weather4_twoicon_shishi_title
<!--单位-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_shishi > div.op_weather4_twoicon_shishi_info > span.op_weather4_twoicon_shishi_data > i.op_weather4_twoicon_shishi_sup
当日温度范围
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > p.op_weather4_twoicon_temp
风向、风速
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > p.op_weather4_twoicon_wind
空气质量
<!--数值-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_realtime_quality_wrap > span > span:nth-child(1)
<!--等级-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_realtime_quality_wrap > span > span.op_weather4_twoicon_aqi_text_today
天气
<!--实时天气-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_shishi > div.op_weather4_twoicon_shishi_info > span.op_weather4_twoicon_shishi_data > i.op_weather4_twoicon_shishi_sub
<!--当日天气-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > p.op_weather4_twoicon_weath
当日公历、农历
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > p.op_weather4_twoicon_date
使用墨迹天气
npm install request --save // http请求库
npm install cheerio --save // 分析html工具
npm install express --save // nodejs web框架
脚本:
const request = require("request")
const cheerio = require("cheerio")
const weatherURL = 'https://tianqi.moji.com/weather/china/Guangdong/guangzhou'
// 获取墨迹天气提示信息
function getWeatherTips(url) {
return new Promise((resolve,reject)=>{
request(weatherURL,(error,res,body)=>{
if (!error) {
let html = res.body || "";
let $ =cheerio.load(html)
let temp = $('.wea_weather em').text().trim()+'℃'
let desc = $('.wea_weather b').text().trim()
let water = $('.wea_about span').text().trim()
let win = $('.wea_about em').text().trim()
let tips = $('.wea_tips em').text().trim()
let words=`今日${city}天气\n${desc}\n温度:${temp}\n湿度:${water}\n风力:${win}\n${tips}`
resolve(words)
} else {
reject(error)
}
})
})
}
获取网速
[https://segmentfault.com/a/1190000040771061?sort=newest]
一言
这里不用API方式,而是用网页获取方式
网址[https://hitokoto.cn]
<!--文本-->
#hitokoto_text
<!--出处-->
#hitokoto_author
毒鸡汤
#text
每日一图
[https://zhuanlan.zhihu.com/p/136867451]
[https://wallhaven.cc/help/api]
<div style="background-image: url(http://tool.liumingye.cn/bingimg/img.php);"></div>
<img src="http://tool.liumingye.cn/bingimg/img.php" />
http://tool.liumingye.cn/bingimg/img.php
生成网页截图
[http://wenku.kuryun.com/docs/phantomjs/screencapture.html]
npm install --global phantomjs #无头浏览器
npm install --global pageres-cli
开始
[https://www.electronjs.org/zh/docs/latest/tutorial/tutorial-first-app]
初始化npm项目
mkdir my-electron-app && cd my-electron-app
npm init
初始化后会生成package.json,存储项目配置
程序的入口点为main.js
在 package.json 中指定的脚本文件 main 是所有 Electron 应用的入口点。 这个文件控制 主程序 (main process),它运行>在 Node.js 环境里,负责控制您应用的生命周期、显示原生界面、执行特殊操作并管理渲染器进程 (renderer processes)
打包后的应用本身会包含 Electron 的二进制文件,但是开发环境需要安装electron
npm install electron --save-dev
安装需要喝一杯奶茶的时间(本土化一点,歪果仁喝一杯咖啡的时间😏)
npm换源:[https://www.cnblogs.com/wyq1995/p/13651904.html]
第一种:npm config set registry http://registry.npm.taobao.org/
第二种:安装cnpm,npm install -g cnpm --registry=https://registry.npm.taobao.org
然后以后都是用cnpm安装插件,cnpm install xxx
第三种:使用nrm
1.下载nrm:npm install -g nrm
2.列出可以选择的源:nrm ls
3.选择想要使用的源:nrm use taobao
4.查看当前npm使用的源:npm config get registry
5.后续的想安装什么插件直接使用npm install xxx就行了
然后会有node_modules文件夹存放可执行文件和package-lock.json存储依赖需求.
Electron 遵循 JavaScript 传统约定,以帕斯卡命名法 (PascalCase) 命名可实例化的类 (如 BrowserWindow, Tray 和 Notification),以驼峰命名法 (camelCase) 命名不可实例化的函数、变量等 (如 app, ipcRenderer, webContents) 。
Electron 的很多核心模组是 Node.js 事件触发器,遵守 Node.js 的异步事件驱动架构。 app 模块就是其中一个。
您应用中的每个页面都在一个单独的进程中运行,我们称这些进程为 渲染器 (renderer) 。 渲染器也能访问前端开发常会用到的 API 和工具,例如用于打包并压缩代码的 webpack,还有用于构建用户界面的 React 。
报错处理
- 引入外部文件,报错
Refused to load the image 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1971525978,455276806&fm=26&gp=0.jpg?rd=_1664896428274' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
解决方案
[https://www.cnblogs.com/xkxf/p/15553510.html]
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://ss0.bdstatic.com https://www.baidu.com; script-src 'self'; style-src 'self' 'unsafe-inline';img-src 'self' https://ss0.bdstatic.com https://www.baidu.com";>
[https://www.jianshu.com/p/74ea9f0860d2]
原因就是有一个CSP安全限制,我们需要允许从https://ss0.bdstatic.com https://www.baidu.com网址加载。
效果:
www.baidu.com/search/error.html:1 GET https://www.baidu.com/search/error.html net::ERR_TIMED_OUT
可以访问设置的网址,但是百度的图片没有这么容易访问😭
另外找了一张图片:https://mirrors.tuna.tsinghua.edu.cn/static/img/logo-small@2x.png?rd=_
注意在图片后添加 rd=_" +new Date().getTime(),否则浏览器会缓存当前图片就不去加载了,影响到测速
- '\$ '符号报错,网页引用jQuery在Electron运行出现"\$ is not defined"
[https://www.cnblogs.com/junchu25/p/11593604.html]
引用jQuery1.8.2版本
<script src="./jquery-1.8.2.min.js"></script>
代码
点击查看代码
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://ss0.bdstatic.com https://www.baidu.com https://music.163.com https://widget.heweather.net; script-src 'self'; style-src 'self' 'unsafe-inline';img-src 'self' https://ss0.bdstatic.com https://www.baidu.com https://mirrors.tuna.tsinghua.edu.cn http://www.qsbye.cn http://tool.liumingye.cn https://www.bing.com https://cn.bing.com;";>
<link href="./styles.css" rel="stylesheet">
<title>桌面信息屏</title>
</head>
<body class="glass">
<h1>桌面信息屏</h1>
<!--网速显示-->
<div class="signal"></div>
<!--结束网速显示-->
<!--开始天气显示-->
<h4 id="tianqi"></h4>
</br>
<h4 id="fengli"></h4>
<!-- 天气 -->
<div class="weather card">
<p>今日天气:晴</p>
<div id="he-plugin-simple" style="display: contents;"></div>
<script>
WIDGET = {
CONFIG: {
"modules": "12034",
"background": 5,
"tmpColor": "888",
"tmpSize": 14,
"cityColor": "888",
"citySize": 14,
"aqiSize": 14,
"weatherIconSize": 24,
"alertIconSize": 18,
"padding": "10px 10px 10px 10px",
"shadow": "1",
"language": "auto",
"borderRadius": 5,
"fixed": "false",
"vertical": "middle",
"horizontal": "left",
"key": "a922adf8928b4ac1ae7a31ae7375e191"
}
}
</script>
<script src="https://widget.heweather.net/simple/static/js/he-simple-common.js?v=1.1"></script>
</div>
<!-- 天气 end -->
<!--结束天气显示-->
<!--每日一图卡片-->
<div class="card" src="http://www.qsbye.cn/more/bing_daily_img.php">
<p>天天天晴😊</p>
<img src="http://www.qsbye.cn/more/bing_daily_img.php" width="200" height="100" style="border-radius: 10px;"/>
</div>
<div class="card">
<img src="http://tool.liumingye.cn/bingimg/img.php" width="200" height="100" style="border-radius: 10px;" />
<img id="signal_ico" src="./bq1.png" width="26" height="18" title="强"><h5 id="speed"></h5>
</div>
<!--结束每日一图-->
<!--网易云音乐-->
<div class="music card"><iframe src="https://music.163.com/outchain/player?type=2&id=864711417&auto=1&height=66" width="330" height="86" frameborder="no" marginwidth="0" marginheight="0"></iframe></div>
<!--结束网易云音乐-->
<!-- You can also require other files to run in this process -->
<script src="./jquery-1.8.2.min.js"></script>
<script src="./renderer.js"></script>
</body>
</html>
styles.css
/* styles.css */
p{
font-family: Arial, Helvetica, sans-serif;
}
body{
background-image:url(bg3.jpg);
background-color: skyblue;
background-size: cover;
background-attachment:fixed;
width: 800px;
height: 600px;
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
}
/*毛玻璃效果*/
.glass{
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
}
/*卡片效果*/
.card {
width: 400px;
height: auto;
padding: 2rem;
border-radius: 1rem;
background: rgba(255, 255, 255, .7);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
margin: 5rem;
}
.card-title {
margin-top: 0;
margin-bottom: .5rem;
font-size: 1.2rem;
}
p, a {
font-size: 1rem;
}
a {
color: #4d4ae8;
text-decoration: none;
}
.glass h1{
color:aliceblue;
font-family: Arial, Helvetica, sans-serif;
}
/* Add styles here to customize the appearance of your app */
其他文件保持默认即可.
测试页面
#注意命令是node不是npm😂
node main.js
或者
npm start
打包为可执行文件
npm install electron-packager -g
electron-packager . HelloWorld --win --out ./HelloWorldApp --arch=x64 --electron-version=19.0.6 --icon=./icon.icns --app-version=0.0.1 --overwrite --ignore=node_modules
# --platform=win32可用于指定平台
#会下载需要的依赖:
#注意electron-version需要和package.json中的匹配才能开始打包,不然报错read ETIMEDOUT.
Downloading electron-v19.0.6-darwin-x64.zip: [============================================================] 100% ETA: 0.0 seconds
Packaging app for platform darwin x64 using electron v19.0.6
效果
内心os: