blog's Introduction
blog's People
blog's Issues
前端黑科技
js控制伪元素样式 原文链接
<!DOCTYPE html>
<title>CSS</title>
<style>
body {
font: 200%/1.45 charter;
}
ref::before {
content: '\00A7';
letter-spacing: .1em;
}
</style>
<article>The seller can, under Business Law <ref>1782</ref>, offer a full refund to buyers. </article>
<script>
function ruleSelector(selector) {
function uni(selector) {
return selector.replace(/::/g, ':')
}
return Array.prototype.filter.call(Array.prototype.concat.apply([], Array.prototype.map.call(document.styleSheets, function(x) {
return Array.prototype.slice.call(x.cssRules);
})), function(x) {
return uni(x.selectorText) === uni(selector);
});
}
var toggle = false,
pseudo = ruleSelector("ref::before").slice(-1);
document.querySelector("article").onclick = function() {
pseudo.forEach(function(rule) {
if (toggle = !toggle)
rule.style.color = "red";
else
rule.style.color = "black";
});
}
</script>
vuex在js中触发命名空间下的模块
原理是通过触发全局 action
,来触发模块中的action
,然后使数据发生变化.上代码
module模块
// src/store/module/data.js
export default {
namespaced: true,
state: {
data: 0
},
mutations: {
setData (state, data) {
state.data = data
}
},
actions: {
setData: {
root: true,
handler ({commit}, data) {
commit('setData', data)
}
}
}
}
引入模块
// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import demo from './module/data'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
setDemoData({dispatch}, data) {
dispatch('setData', data)
}
},
modules: {
demo
}
})
使用
// xx.js
import store form '@/store'
store.dispatch('setDemoData', 2)
tsconfig-json总结
{
"compilerOptions": {
/* 基本选项 */
"target": "es5", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
"module": "commonjs", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
"lib": [], // 指定要包含在编译中的库文件
"allowJs": true, // 允许编译 javascript 文件
"checkJs": true, // 报告 javascript 文件中的错误
"jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
"declaration": true, // 生成相应的 '.d.ts' 文件
"sourceMap": true, // 生成相应的 '.map' 文件
"outFile": "./", // 将输出文件合并为一个文件
"outDir": "./", // 指定输出目录
"rootDir": "./", // 用来控制输出目录结构 --outDir.
"removeComments": true, // 删除编译后的所有的注释
"noEmit": true, // 不生成输出文件
"importHelpers": true, // 从 tslib 导入辅助工具函数
"isolatedModules": true, // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似).
/* 严格的类型检查选项 */
"strict": true, // 启用所有严格类型检查选项
"noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错
"strictNullChecks": true, // 启用严格的 null 检查
"noImplicitThis": true, // 当 this 表达式值为 any 类型的时候,生成一个错误
"alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict'
/* 额外的检查 */
"noUnusedLocals": true, // 有未使用的变量时,抛出错误
"noUnusedParameters": true, // 有未使用的参数时,抛出错误
"noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误
"noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿)
/* 模块解析选项 */
"moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
"baseUrl": "./", // 用于解析非相对模块名称的基目录
"paths": {}, // 模块名到基于 baseUrl 的路径映射的列表
"rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容
"typeRoots": [], // 包含类型声明的文件列表
"types": [], // 需要包含的类型声明文件名列表
"allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。
/* Source Map Options */
"sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
"mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置
"inlineSourceMap": true, // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
"inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性
/* 其他选项 */
"experimentalDecorators": true, // 启用装饰器
"emitDecoratorMetadata": true // 为装饰器提供元数据的支持
},
"files": { // 那些文件需要被编译
},
"include": { // 需要包含的文件
},
"exclude": { // 排除的文件
},
}
electron-builder打包build配置
市面上对于electron-builder打包的介绍文章很多,这里不做过多介绍,如果需要可以看苏南大叔的博客,这里只是针对打包配置进行一个总结。
为了不浪费大家时间,如果你有以下问题,可以试着看我的文档:
- 打包后发现文件访问不了,在开发环境下是好的
- 打包的时候,怎么设置不让安装在c盘
- 将文件移动到根目录
配置文件如下
package.json
{
"name": "demo",
"version": "0.0.2",
"author": "四月 <[email protected]>",
"build": { // electron-builder配置
"productName":"xxxx",//项目名 这也是生成的exe文件的前缀名
"appId": "xxxxx",//包名
"copyright":"xxxx",//版权 信息
"compression": "store", // "store" | "normal"| "maximum" 打包压缩情况(store 相对较快),store 39749kb, maximum 39186kb
"directories": {
"output": "build" // 输出文件夹
},
"asar": false, // asar打包
"extraResources": { // 拷贝dll等静态文件到指定位置
"from": "./app-update.yml",
"to": "./b.txt"
},
"win": {
"icon": "xxx/icon.ico"//图标路径,
"extraResources": { // 拷贝dll等静态文件到指定位置(用于某个系统配置)
"from": "./app-update.yml",
"to": "./b.txt"
}
},
"nsis": {
"oneClick": false, // 一键安装
"guid": "xxxx", //注册表名字,不推荐修改
"perMachine": true, // 是否开启安装时权限限制(此电脑或当前用户)
"allowElevation": true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
"allowToChangeInstallationDirectory": true, // 允许修改安装目录
"installerIcon": "./build/icons/aaa.ico", // 安装图标
"uninstallerIcon": "./build/icons/bbb.ico", //卸载图标
"installerHeaderIcon": "./build/icons/aaa.ico", // 安装时头部图标
"createDesktopShortcut": true, // 创建桌面图标
"createStartMenuShortcut": true, // 创建开始菜单图标
"shortcutName": "xxxx" // 图标名称
}
}
}
问题及解决方案
-
问: 打包后发现文件访问不了,在开发环境下是好的,有些喜欢研究的发现是asar的问题
答: 对的,打包为
asar
文件后内部是只读的,所以当你需要操作的时候,肯定不能操作呀,解决方案很多种- 可以使用userData存放
- 可以设置
asar
为false
,详细配置参照上面写的配置文件 - 看官方文档有一种
asar
可以直接将文件放置在app.asar
外的写法,目前还在研究,可行,等试验成功在更新
-
问: 打包的时候,怎么设置不让安装在c盘
-
问: dll文件打包后怎么移动到根目录
答:
extraResources
用来将依赖的文件放的指定位置,'./'指向app同级目录 -
有什么问题欢迎留言告知
树莓派/linux命令整理
查找软件位置
which [fileName]
查找安装包
dpkg-query -W [fileName]
打开文件夹
dde-file-manager [path]
查看权限
ls -al [path]
设置权限
sudo chmod 777 [filePath]
内存相关
ulimit
格式化磁盘
mkfs -t ext4 [diskPath]
查看路径所在磁盘
df -h [filePath]
挂载磁盘
mount [diskPath] [dirPath]
取消挂载磁盘
umount [diskPath]
查找进程
pidof xxx
ps aux | grep -i xxx
pgrep firefox
重启
sudo reboot
关机
sudo poweroff
查看文件所在路径
which xxx
修改环境变量
sudo nano /etc/profile
添加 export PATH="$PATH: path"
source /etc/profile
打开配置
sudo raspi-config
拍照
参考地址:
https://blog.csdn.net/fhqlongteng/article/details/80433633
raspistill -o -t 3000 1.jpg
-v:调试信息查看
-w:图像宽度
-h:图像高度
-q: 图片质量(0-100)
-br: 图片亮度(0-100)
-sa: 图片饱和度(-100-100)
-ev: 曝光补偿(-10 - 10)
–ex: 曝光模式
auto – 使用自动曝光模式
night – 夜间拍摄模式
nightpreview -夜间预览拍摄模式(暂且这么称呼)
backlight – 逆光拍摄模式
spotlight – 聚光灯拍摄模式
sports – 运动拍摄模式(高速快门等)
snow – 雪景优化拍摄模式
beach – 海滩优化拍摄模式
verylong – 长时间曝光拍摄模式
fixedfps – 帧约束拍摄模式
antishake – 防抖模式
fireworks – 烟火优化拍摄模式
-awb 自动白平衡
off – 关闭白平衡测算
auto – 自动模式(默认)
sun – 日光模式
cloud – 多云模式
shade – 阴影模式
tungsten – 钨灯模式
fluorescent – 荧光灯模式
incandescent – 白炽灯模式
flash – 闪光模式
horizon – 地平线模式
-rot:图像旋转角度,支持 0、90、180、270 度
-o:图像输出地址,例如1.jpg,如果文件名为“-”,将输出发送至标准输出设备
-t:获取图像前等待时间,默认为5000,即5秒
-tl:多久执行一次图像抓取
淘宝源总结
electron
原地址: https://atom.io/download/electron
淘宝地址: https://npm.taobao.org/mirrors/atom-shell
vue cypress包: set CYPRESS_INSTALL_BINARY=https://npm.taobao.org/mirrors/cypress/3.4.1/win32-x64/cypress.zip
工具总结
生活小计
2020-3-21 微信多开
今天开机后,无意多点了几次微信,打开了两个微信登录框。然后下意识想到,微信更新允许多开了?!随后测试发现,仅允许打开一个微信登录框。然后突发奇想:
让子弹拐弯是有原理的。就是射手在子弹出膛的那一刹那,手腕急速的抖动,给了子弹一个水平的加速度,从而形成一个弧线,这就是枪斗术。
枪斗术是不可能学会的,这辈子都不可能学会的,但是我可以用bat多开呀!说干就干,代码如下:
:: openWechat.bat
set wechat=D:\tool\Tencent\WeChat\WeChat.exe
start %wechat%
start %wechat%
就先开两个压压惊吧!
nice!果然和我想的一样,虽然我们没有枪斗术的手速,但是我们有dos
的强大帮助。
日常经验+1!
最后在来一版优化后的代码
:: openWechat.bat
@echo off
:: wechat为微信路径,注意替换
set wechat=D:\tool\Tencent\WeChat\WeChat.exe
echo hi!我需要先找到并杀死当前所有的微信,否则多开无效。
taskkill /f /im WeChat.exe
echo 微信进程清理完成,准备打开微信!
set /p count=请输入需要打开的微信个数:
for /L %%i in (1, 1, %count%) do start %wechat%
exit
ubuntu server 链接蓝牙
获取蓝牙设备
sudo hcitool scan
获取蓝牙通道
sdptool records [Mac] | grep Channel
连接蓝牙
sudo rfcomm connect /dev/rfcomm0 [Mac] [Channel]
打开/关闭蓝牙
sudo hciconfig hci0 up
sudo hciconfig hci0 down
部署阿里云(从实操到放弃)
在公司部署了N+1套node项目之后,终于耐不住寂寞租了阿里云的服务器,准备从零开始部署一套项目,下面将记录我每天的采坑之旅。
第一天:docker环境搭建、mysql数据持久化、node安装
不出所料不负众望,终于还是踩了一堆坑来到了这里
docker环境搭建
mysql数据持久化
获取mysql镜像
docker 安装成功后, 通过
docket pull mysql:5.7.28
将mysql 5.7.28
下载完毕。通过docker images
查看mysql是否下载成功
创建配置文件
首先创建存放配置文件的文件夹
mkdir -p /mysql/config /mysql/data
然后生成并编辑配置文件
vi /mysql/config/my.conf // 生成文件
配置文件内容:
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
启动容器
docker run -d -p 3306:3306 --restart always --privileged=true --name Mysql -e MYSQL_ROOT_PASSWORD=xxxxx -v /mysql/config/my.conf:/etc/my.cof -v=/mysql/data:/var/lib/mysql mysql:5.7.28
参数说明如下:
-d 后台运行容器
-p 3306:3306 指定端口映射(主机(宿主)端口:容器端口)
--restart=always 开机启动
--privileged=true 提升容器内权限
--name 为容器指定一个名称
-e 设置环境变量
MYSQL_ROOT_PASSWORD=xxxx 初始密码
-v /mysql/config/my.conf:/etc/my.cof 映射配置文件
-v=/mysql/data:/var/lib/mysql 映射数据目录
mysql:5.7.28 镜像名称
登录mysql并设置远程连接
登录mysql
docker exec -it Mysql bash
mysql -u root -p
设置远程连接
ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxxxxx!';
然后去阿里云配置安全组规则(都放在明面上的东西,一眼就看到了不做过多陈述),因为并没有碰到防火墙打开,所以也没法陈述。。。
node安装
electron设置 Chrome 实验功能
electron简介
Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库。 Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用来实现这一目的。
electron Chrome命令行中文网文档
先上electron中文网关于Chrome 命令行开关
方法的介绍。戳我
然后我们还可以看都支持哪些命令行。戳我
起因
今天在使用audio
的自动播放的时候发现了,当我调用audio.play()
会报错
DOMException: play() failed because the user didn't interact with the document first
因为之前一直使用的electron2.0.4,Chromium版本较低,所以并不知道有这个问题。
思路
通过错误给的提示去https://goo.gl/xX8pDD查看解决方案。看到了可以通过chrome://flags/#autoplay-policy中调整autoplay-policy的选项来使用自动播放,随想到官网的关于Chrome命令行的介绍,查了下也的确可行。
上代码
import { app } from 'electron';
app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required');
// 需要注意官网对这个方法进行了阐述: 您可以在app 模块的ready事件生效之前。所以需要在ready生效之前运行
重置虚拟机网络导致ubuntu没有网关问题修改
设置网关,ip
首先利用ll /etc/netwo*
查看当前的网络配置文件夹
# ll /etc/netwo*
-rw-r--r-- 1 root root 91 4月 9 2018 /etc/networks
/etc/network:
总用量 40
drwxr-xr-x 7 root root 4096 11月 9 17:30 ./
drwxr-xr-x 126 root root 12288 11月 9 02:34 ../
drwxr-xr-x 2 root root 4096 11月 2 23:42 if-down.d/
drwxr-xr-x 2 root root 4096 11月 2 23:42 if-post-down.d/
drwxr-xr-x 2 root root 4096 11月 2 23:42 if-pre-up.d/
drwxr-xr-x 2 root root 4096 11月 2 23:42 if-up.d/
-rw-r--r-- 1 root root 183 11月 9 17:30 interfaces
drwxr-xr-x 2 root root 4096 4月 27 2018 interfaces.d/
然后修改上方查出的文件夹/etc/network/interfaces
(有些人的文件夹叫networking
,新手上手linux
不是很懂)
修改配置文件
# sudo vim /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
# auto lo
# iface lo inet loopback
# 网络名称
auto intervm
iface intervm inet dhcp
# 设置ip地址
address 192.168.159.129
# 设置子网掩码
netmask 255.255.255.0
# 设置网关
gateway 192.168.92.0
electron-vue开发环境内存泄漏问题汇总
package.json
"dependencies": {
"vue": "^2.5.16"
},
"devDependencies": {
"ajv": "^6.5.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-0": "^6.24.1",
"babel-register": "^6.26.0",
"babili-webpack-plugin": "^0.1.2",
"cfonts": "^2.1.2",
"chalk": "^2.4.1",
"copy-webpack-plugin": "^4.5.1",
"cross-env": "^5.1.6",
"css-loader": "^0.28.11",
"del": "^3.0.0",
"devtron": "^1.4.0",
"electron": "3.0.0",
"electron-builder": "^20.19.2",
"electron-debug": "^1.5.0",
"electron-devtools-installer": "^2.2.4",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "0.4.0",
"multispinner": "^0.2.1",
"node-loader": "^0.6.0",
"style-loader": "^0.21.0",
"url-loader": "^1.0.1",
"vue-html-loader": "^1.2.4",
"vue-loader": "^15.2.4",
"vue-style-loader": "^4.1.0",
"vue-template-compiler": "^2.5.16",
"webpack": "^4.15.1",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4",
"webpack-hot-middleware": "^2.22.2",
"webpack-merge": "^4.1.3"
}
electron测试版本3.0.0, 4.0.0, 4.2.6
问题描述
在开发环境中,修改主进程保存后,每次保存会多出一到两个electron进程,根据群友反馈2.0.8也是存在这个问题的,只是出现的频率较低
排查过程以及解决思路
1、 首先先看了webpack.main.config.js
,然而并没有发现有什么异样的地方,配置了只启动一个应用程序,每次退出前也使用app.exit()
强制退出,然而并没有任何好转,遂新建一个项目,用来测试
2、 在创建完毕后(electron v4.0.0),发现每次保存并不是都会出现一个新的进程,经过多次测试后,发现问题出在保存完后,主进程未生成成功,然后再次保存,于是进程创建了多次,但是只杀死了最开始的进程,造成内存泄漏。
3、 在dev-runner.js
中找到了关于杀死进程的方法
if (electronProcess && electronProcess.kill) {
manualRestart = true
process.kill(electronProcess.pid)
electronProcess = null
startElectron()
setTimeout(() => {
manualRestart = false
}, 5000)
}
4、 好吧他是直接通过调用process.kill
来杀死进程,然后造成这个问题,遂进行了修改,修改后代码如下,注意引入exec
,然后将延时器删除,感觉整个程序的运行速度都快了不少,哈哈哈
if (electronProcess && electronProcess.kill) {
manualRestart = true
const pid = electronProcess.pid
exec(`TASKKILL /F /IM electron.exe`, function (err, data) {
if (err) console.log(err)
else console.log('kill pid: ' + pid + ' success!')
electronProcess = null
startElectron()
manualRestart = false
})
}
总结
在解决了问题后,去看版本更新记录,在2.0.8-3.0.0的版本更新记录中并没有发现那条更新记录会导致这个问题,时间有限,也没有去看到底在哪个版本后造成这个问题,技艺拙劣,始终没有找到出现的原因
【工具安装】Chocolatey的安装
安装步骤
-
用管理员身份打开
Windows PowerShell
-
输入
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
错误及解决方案
无法加载文件 ,因为在此系统上禁止运行脚本
运行 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
PS C:\Users\Administrator> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
使用“1”个参数调用“DownloadString”时发生异常:“请求被中止: 未能创建 SSL/TLS 安全通道。”
- 先运行一次
[Net.ServicePointManager]::SecurityProtocol
查看输出是否包含Tls12
PS C:\Users\Administrator> [Net.ServicePointManager]::SecurityProtocol
Ssl3, Tls
- 如果不包含
Tls12
那么运行[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3 -bor [Net.Secu rityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
PS C:\Users\Administrator> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3 -bor [Net.Secu
rityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
- 安装完成后继续调用
[Net.ServicePointManager]::SecurityProtocol
查看是否包含Tls12
PS C:\Users\Administrator> [Net.ServicePointManager]::SecurityProtocol
Ssl3, Tls, Tls11, Tls12
使用说明
search
查看是否有某个包
choco search [NAME]
install
安装指定包
choco install [NAME]
update
升级指定包
choco update [NAME]
uninstall
卸载指定包
choco uninstall [NAME]
关于配置页面主题色的一些见解
思路
网上说的通过不同类名来导入N套主题的方式,我是接受不了的,千人千样,我不想限制了别人的想象力,所以开始自己着手来实现主题色配置。
最初想利用指定一个类名,然后通过循环该类名对应的dom来实现修改主题色的效果。
// theme.less
@background: red;
.b { background: @background; }
// index.js
const dom = document.getElementsByClassName('b');
for (let i = 0; i < dom.length; i++) {
dom[i].style.background = 'blue';
}
当然这个方式有一个诟病的: 若dom元素后生成,那么还需要重新运行一次,而且循环dom的话,在不确定项目大小的情况下,这一做法有点冒险。然后无意间发现了一个css属性:var。
随后有了一个大胆的想法:利用css实验属性(2020/1/8)var()
来统一全局样式,然后通过修改该属性值来达到修改主题色的效果。
var介绍
var()函数可以代替元素中任何属性中的值的任何部分。var()函数不能作为属性名、选择器或者其他除了属性值之外的值。(这样做通常会产生无效的语法或者一个没有关联到变量的值。) --- mdn
语法
var( <custom-property-name> , <declaration-value>? )
custom-property-name
: 自定义属性名
declaration-value
: 声明值
例子
// theme.less
html {
--themeColor: #fff; /* 不可以使用@变量 */
--fontColor: #000;
}
// index.less
body {
background: var(--themeColor);
color: var(--fontColor);
}
当需要切换主题色的时候直接利用js修改--themeColor
和--fontColor
的值就ok;
const checkTheme = (color) => {
document.getElementsByTagName('html')[0].style.setProperty('--themeColor', color.theme);
document.getElementsByTagName('html')[0].style.setProperty('--fontColor', color.font);
}
var兼容性
electron实现开机自启+通过连接调起应用
开机自启
原生
electron原生自启动
app.setLoginItemSettings
app.setLoginItemSettings({
openAtLogin: true, // Boolean 在登录时启动应用
openAsHidden: true, // Boolean (可选) mac 表示以隐藏的方式启动应用。~~~~
// path: '', String (可选) Windows - 在登录时启动的可执行文件。默认为 process.execPath.
// args: [] String Windows - 要传递给可执行文件的命令行参数。默认为空数组。注意用引号将路径换行。
})
自实现
通过修改注册表来实现开机自启和通过链接调起应用(类似百度网盘点击连接打开应用程序)
使用到的插件
node-regedit yarn add regedit
使用说明
将下方例子中的electronApp替换为自己的应用别名(可以不为exe名称)
开机自启
const regedit = require('regedit');
const { app } = require('electron');
const path = require('path');
// 开机自启动
// 查看开机自启注册表是否已经注册electronApp
regedit.list('HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run', (err, data) => {
if (err) {
console.log(err)
}
if (!data['HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'].values.electronApp ||
data['HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'].values.electronApp !==
app.getPath('exe')) { // 未注册或注册地址与现地址不一致则 进行注册
regedit.putValue({
'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run': {
'electronApp': {
value: app.getPath('exe'),
type: 'REG_SZ'
}
}
}, (error) => {
if (error) console.log(error)
})
}
});
通过链接调起应用
const regedit = require('regedit');
const { app } = require('electron');
/**
* 下文中的`electronAPP`替换为自己需要的唤起名
* `electronApp`为应用程序注册表名字 详细配置查看 ` https://github.com/suruixin/blog/issues/3 `中的nsis.guid
* 使用时直接在html中使用<a href='electronAPP://'>唤起app</a>
*/
let url = app.getPath('exe'); // 获取可运行exe存放目录
function setPath (url) {
regedit.putValue({
'HKLM\\SOFTWARE\\Classes\\electronAPP': { // 设置注册表url调用electronApp
'defaule': {
value: 'electronAPP', // 设置点击url的弹出框名字(表现不好)
type: 'REG_DEFAULT'
},
'URL Protocol': {
value: '',
type: 'REG_SZ'
},
'path': {
value: `${url}`,
type: 'REG_SZ'
}
},
'HKLM\\SOFTWARE\\Classes\\electronAPP\\shell\\open\\command': {
'defaule': {
value: `"${url}" "$1"`, // 需要唤起的应用程序路劲
type: 'REG_DEFAULT'
}
}
}, (putErr) => {
console.log(putErr)
})
}
if (url) { // 判断启动url是否正确(用户重新安装,并将安装目录修改)
regedit.list('HKLM\\SOFTWARE\\Classes\\electronAPP', (listErr, docData) => {
if (listErr) {
regedit.createKey(['HKLM\\SOFTWARE\\Classes\\electronAPP\\shell\\open\\command'], (createErr) => {
if (!createErr) {
setPath(url)
}
})
} else {
if (docData['HKLM\\SOFTWARE\\Classes\\electronAPP'].values.path.value !== url) {
setPath(url)
}
}
})
}
github项目功能说明
node
chokidar node监听文件变化
express-http-proxy 基于express数据请求中转
node-http-proxy node数据请求中转
js-base64 文件转base64
node-notifier node弹框
nodemon node热更新
node-activexnodejs使用activex
simpletts 文字合成语音
ar-cutpaste 实物复制粘贴到电脑上
node-tensorflow 谷歌机器学习
node-schedule 定时执行
npm-run-all npm并行执行
推荐库
SortableJS JavaScript 拖拽库
dayjs 轻量的处理时间和日期的 JavaScript 库
GridManager 功能强大的原生表格生成器
camera
web-camera 摄像头理论兼容ie9
camera.js js控制摄像头
vue
vue-print-nb vue打印功能
vite 尤大编写的vue组件打包工具
electron
miniblink49 miniGoogle
vue-cli-plugin-electron-builder vue-cli3 + electron
windows-build-tools node-gyp安装前依赖
typescript
typedoc typescript 文档生成器
微信相关
c++
CS-Books c++学习书籍
其他
30-seconds-of-code 前端奇淫异技
html2canvas html转图片
uirecorder 自动测试
chrome-plugin-demo Chrome插件开发
chinese-xinhua 中华新华字典数据库
node-iconv 编码格式转换
hbq-rename-cli 改变文件后缀
tfjs-examples js实现机器学习
async-validator 数据验证
autosize textarea自动高度
nodegui 桌面端应用开发
mapbox-gl-js 滚动插件
webfunny_monitor js探针
css in js
移动端
better-scroll 移动端滚动插件
nutui 京东商城
icon
tabler-icons 超过300款svg任你选择,杀人越货的不二选
loading svg 非github项目,体验比tabler-icons
好,但是付费
识别库
tracking js实现人脸检测颜色识别等
face-detection-node-opencv opencv人脸检测
fingerprintjs 获取设备唯一标识
树莓派
node-rpio GPIO接口控制
node-raspicam 摄像头控制
轮播
图像
p5.js 适合艺术家程序员
nsfwjs 鉴黄
FFCreator 短视频制作工具
ai智能
lac 词法分析工具
electron使用node-ffi常见错误
观看须知
1 本内容只针对正常安装好node-gyp
后调用dll文件常见的错误做一次总结,node-gyp
安装报错后续整理,本篇不做阐述.
2 因内容需不断完善 本内容不接受任何形式的转载 首发地址: #24
3 创建方式为vue+vue-cli-plugin-electron-builder
配置文件
{
"name": "electron-demo",
"version": "1.0.0",
"author": "四月 <[email protected]>",
"description": "demo",
"license": null,
"main": ".//main.js",
"scripts": {
"rebuild": "cd ./node_modules/.bin && electron-rebuild --force --module-dir=../../"
},
"dependencies": {
"ffi": "^2.3.0",
"ref": "^1.3.5",
"ref-array": "^1.2.0",
"ref-struct": "^1.1.0"
},
"devDependencies": {
"electron": "^4.2.4",
"electron-rebuild": "^1.8.2"
}
}
问题总结
未编译文件
// 错误信息
Uncaught Error: The module '\\?\x:\xxx\node_modules\xxx\build\Release\binding.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 64. This version of Node.js requires
NODE_MODULE_VERSION 69. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:160:31)
解决方案
运行npm run rebuild
less总结
less拼接字符串
.lh(@h){
line-height: ~'@{h}px'
}
vue+iview使用cdn加载来优化文件过大
vue版本
使用到的插件
webpack-bundle-analyzer
// /build/webpack.prod.conf.js
const WebpackBundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const webpackConfig = merge(baseWebpackConfig, {
plugins: [
new WebpackBundleAnalyzerPlugin()
]
})
这个插件主要用来查看打包后文件的大小,以及打包后的文件包含哪些第三方插件,用来优化项目
使用cdn载入vue和iview
// /build/webpack.prod.conf.js
const webpackConfig = merge(baseWebpackConfig, {
externals: {
vue: "Vue",
iview: "iview"
}
})
index.html
<head>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/[email protected]/dist/styles/iview.css">
<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/iview.min.js"></script>
</head>
此处需要注意将vue
和iview
尽量放入到head
中,不然在打包后,这两个文件如果在vendor.js
和app.js
后会导致vue
和iview
找不到,当然并不是强制要求vue
和iview
必须在head
中,只要确保这两个文件在vendor.js
和app.js
后便可以
iview
中部分标签也是需要修改的,详情参考(iview官网)[https://www.iviewui.com/docs/guide/start]
linux安装node-gyp
系统: Ubuntu 18.0.4
node: 10.13.0
node-gyp: 7.0.1
需要用到的插件
node-gyp
官网给出gcc
, python
, make
同时需要安装build-essential
, g++
安装方法:
sudo apt-get install python, gcc, make, build-essential, g++
AutoHotkey+electron常用键禁止
功能模块
// AutoHotkey.ark
LWin::return
RWin::return
Alt::return
!Tab::return
!F4::return
^Esc::return
^!Left::return
^!right::return
^!up::return
^!down::return
!left::return
!right::return
^Tab::return
常用符号及描述总结
符号 | 描述 |
---|---|
! | Alt |
# | windows |
^ | Ctrl |
+ | shift |
工具
打包
安装好AutoHotkey后右键选择Compile Script
编译为exe
使用
const { exec } = require('child_process')
let flag = true // 是否开启禁止热键功能
let fileName = 'stopkey.exe' // ahk打包完成后exe名
if (flag) {
exec(`TASKKILL /F /IM ${fileName}`)
setTimeout(m => {
exec(`${__static}\\exe\\${fileName}`) // 运行exe '${__static}\\exe'为ahk exe存放路径
}, 1000)
} else {
exec(`TASKKILL /F /IM ${fileName}`)
}
npm总结
npm命令行总结
npm config set <key> <value> // npm默认设置修改
npm config get [<key>] // npm默认设置获取
npm config delete <key> // npm删除默认设置
npm config list [--json]
npm config edit
npm set <key> <value> // npm config set缩写
npm get [<key>] // npm config get缩写
vue安装依赖挂起问题解决
set CYPRESS_INSTALL_BINARY=https://npm.taobao.org/mirrors/cypress/3.4.1/linux-x64/cypress.zip
ts+express+nodemon实现node程序热更新
nodemon简介
nodemon是一个帮助开发者基于node.js的应用程序的工具,它可以在检测到目录中的文件更改,并在文件更改时自动重新启动node应用程序。
ts+ndemon热更新
// package.json
{
scripts: {
"watch": "tsc -d -w",
"serve": "nodemon ./dist/bin/www.js", // dist为ts文件改变后入口文件位置
"build": "tsc -d"
}
}
日常积累-网站
node
关于node的相关总结
node彩色字体表 node输出彩色字体 [\x1b32m xxx [\x1b0m
vue
关于vue相关总结
electron
桌面端应用制作 可以制作mac window linux包
php相关
移动端相关
css
ui
ui库和好看的ui网站以及ui相关
highcharts echart将3d饼图删掉了,为了补全这块空缺,找到了highcharts
工具
实用工具总结
插件
总结的比较好玩的工具插件和插件库
网站
文档网站和一些有趣的网站
打包
接口网站
office
其他
ts
移动端
WebRTC协议
持续更新
electron-vue使用electron-updater实现自动更新
今天呢,给大家带来一篇干货满满的electron-vue自动升级的教程,话不多说,开始我的表演!
配置文件 "package.json"
"build" : {
"publish": [
{
"provider": "generic",
"url": "http://127.0.0.1:3000/newfile/"
}
],
},
"devDependencies": {
"electron": "^2.0.4",
"electron-updater": "3.0.0",
"electron-builder": "^20.19.2"
}
安装依赖
需要注意的是electron-vue中目前是使用electron 2.0.4的,所以最新版的electron-updater是不支持的,若手动升级electron版本的话,如果你使用了node-ffi等的话,是无法运行的,但是如果你只是使用node-ffi的话可以切换成node-ffi-napi然后对electron进行升级
yarn add [email protected] --dev(推荐)
npm i [email protected] -D
cnpm i [email protected] -D
自动更新 "update.js"
import { autoUpdater } from 'electron-updater'
import { ipcMain } from 'electron'
/**
* -1 检查更新失败 0 正在检查更新 1 检测到新版本,准备下载 2 未检测到新版本 3 下载中 4 下载暂停 5 下载暂停恢复 6 下载完成 7 下载失败 8 取消下载
* */
class Update {
mainWindow
constructor (mainWindow) {
this.mainWindow = mainWindow
autoUpdater.setFeedURL('http://127.0.0.1:3000/newfile') // 更新地址与package.json中的build.publish.url相对应
/**
* 根据自身需求选择下方方法
*/
this.error()
this.start()
this.allow()
this.unallowed()
this.listen()
this.download()
}
Message (type, data) {
this.mainWindow.webContents.send('message', type, data)
}
error () { // 当更新发生错误的时候触发。
autoUpdater.on('error', (err) => {
this.Message(-1, err)
console.log(err)
})
}
start () { // 当开始检查更新的时候触发
autoUpdater.on('checking-for-update', (event, arg) => {
this.Message(0)
})
}
allow () { // 发现可更新数据时
autoUpdater.on('update-available', (event, arg) => {
this.Message(1)
})
}
unallowed () { // 没有可更新数据时
autoUpdater.on('update-not-available', (event, arg) => {
this.Message(2)
})
}
listen () { // 下载监听
autoUpdater.on('download-progress', () => {
this.Message('下载进行中')
})
}
download () { // 下载完成
autoUpdater.on('update-downloaded', () => {
this.Message(6)
setTimeout(m => {
autoUpdater.quitAndInstall()
}, 1000)
})
}
load () { // 触发器
autoUpdater.checkForUpdates()
}
}
export default Update
update配置
若对class写法不是很熟悉的同学,可以参考阮一峰老师的es6课程class
在下载中的时候有一个问题就是下载非差异文件的时候不会触发下载监听,点击查看
主进程 "index.js"
import Update from './update'
mainWindow = new BrowserWindow({
height: 563,
useContentSize: true,
width: 1000
})
let update = new Update(mainWindow)
下面对比较常见的一些bug进行一下处理
At least electron-updater 4.0.0 is recommended by current electron-builder version. Please set electron-updater version to "^4.0.0"
electron-updater 安装在dependencies了,在package.json中将他移动到devDependencies
DOS命令总结
taskkill 杀死进程
TASKKILL [/S system [/U username [/P [password]]]]
{ [/FI filter] [/PID processid | /IM imagename] } [/T] [/F]
描述:
使用该工具按照进程 ID (PID) 或映像名称终止任务。
参数列表:
/S system 指定要连接的远程系统。
/U [domain\]user 指定应该在哪个用户上下文执行这个命令。
/P [password] 为提供的用户上下文指定密码。如果忽略,提示
输入。
/FI filter 应用筛选器以选择一组任务。
允许使用 "*"。例如,映像名称 eq acme*
/PID processid 指定要终止的进程的 PID。
使用 TaskList 取得 PID。
/IM imagename 指定要终止的进程的映像名称。通配符 '*'可用来
指定所有任务或映像名称。
/T 终止指定的进程和由它启用的子进程。
/F 指定强制终止进程。
/? 显示帮助消息。
筛选器:
筛选器名 有效运算符 有效值
----------- --------------- -------------------------
STATUS eq, ne RUNNING |
NOT RESPONDING | UNKNOWN
IMAGENAME eq, ne 映像名称
PID eq, ne, gt, lt, ge, le PID 值
SESSION eq, ne, gt, lt, ge, le 会话编号。
CPUTIME eq, ne, gt, lt, ge, le CPU 时间,格式为
hh:mm:ss。
hh - 时,
mm - 分,ss - 秒
MEMUSAGE eq, ne, gt, lt, ge, le 内存使用量,单位为 KB
USERNAME eq, ne 用户名,格式为 [domain\]user
MODULES eq, ne DLL 名称
SERVICES eq, ne 服务名称
WINDOWTITLE eq, ne 窗口标题
说明
----
1) 只有在应用筛选器的情况下,/IM 切换才能使用通配符 '*'。
2) 远程进程总是要强行 (/F) 终止。
3) 当指定远程机器时,不支持 "WINDOWTITLE" 和 "STATUS" 筛选器。
例如:
TASKKILL /IM notepad.exe
TASKKILL /PID 1230 /PID 1241 /PID 1253 /T
TASKKILL /F /IM cmd.exe /T
TASKKILL /F /FI "PID ge 1000" /FI "WINDOWTITLE ne untitle*"
TASKKILL /F /FI "USERNAME eq NT AUTHORITY\SYSTEM" /IM notepad.exe
TASKKILL /S system /U 域\用户名 /FI "用户名 ne NT*" /IM *
TASKKILL /S system /U username /P password /FI "IMAGENAME eq note*"
netstat
显示协议统计信息和当前 TCP/IP 网络连接。
NETSTAT [-a] [-b] [-e] [-f] [-n] [-o] [-p proto] [-r] [-s] [-x] [-t] [interval]
-a 显示所有连接和侦听端口。
-b 显示在创建每个连接或侦听端口时涉及的
可执行程序。在某些情况下,已知可执行程序承载
多个独立的组件,这些情况下,
显示创建连接或侦听端口时
涉及的组件序列。在此情况下,可执行程序的
名称位于底部 [] 中,它调用的组件位于顶部,
直至达到 TCP/IP。注意,此选项
可能很耗时,并且在你没有足够
权限时可能失败。
-e 显示以太网统计信息。此选项可以与 -s 选项
结合使用。
-f 显示外部地址的完全限定
域名(FQDN)。
-n 以数字形式显示地址和端口号。
-o 显示拥有的与每个连接关联的进程 ID。
-p proto 显示 proto 指定的协议的连接;proto
可以是下列任何一个: TCP、UDP、TCPv6 或 UDPv6。如果与 -s
选项一起用来显示每个协议的统计信息,proto 可以是下列任何一个:
IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 或 UDPv6。
-q 显示所有连接、侦听端口和绑定的
非侦听 TCP 端口。绑定的非侦听端口
不一定与活动连接相关联。
-r 显示路由表。
-s 显示每个协议的统计信息。默认情况下,
显示 IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 和 UDPv6 的统计信息;
-p 选项可用于指定默认的子网。
-t 显示当前连接卸载状态。
-x 显示 NetworkDirect 连接、侦听器和共享
终结点。
-y 显示所有连接的 TCP 连接模板。
无法与其他选项结合使用。
interval 重新显示选定的统计信息,各个显示间暂停的
间隔秒数。按 CTRL+C 停止重新显示
统计信息。如果省略,则 netstat 将打印当前的
配置信息一次。
cls(windows) clear(linux)
清空屏幕
github图片不显示解决方案
修改hosts
文件,目录: C:\Windows\System32\drivers\etc
# GitHub Start
192.30.253.112 github.com
192.30.253.119 gist.github.com
151.101.184.133 assets-cdn.github.com
151.101.184.133 raw.githubusercontent.com
151.101.184.133 gist.githubusercontent.com
151.101.184.133 cloud.githubusercontent.com
151.101.184.133 camo.githubusercontent.com
151.101.184.133 avatars0.githubusercontent.com
151.101.184.133 avatars1.githubusercontent.com
151.101.184.133 avatars2.githubusercontent.com
151.101.184.133 avatars3.githubusercontent.com
151.101.184.133 avatars4.githubusercontent.com
151.101.184.133 avatars5.githubusercontent.com
151.101.184.133 avatars6.githubusercontent.com
151.101.184.133 avatars7.githubusercontent.com
151.101.184.133 avatars8.githubusercontent.com
# GitHub End
本文为转载,首发
vue-cli3全局引入less
1、安装 style-resources-loader
vue add style-resources-loader
2、配置全局less并引入
// vue.config.js
const { join } = require('path');
function resolve (path) {
return join(__dirname, path)
}
module.exports = {
chainWebpack: config => {
config.resolve.alias
.set('@', resolve('/src'))
.set('_c', resolve('/src/components'))
.set('_v', resolve('/src/views'))
.set('_a', resolve('/src/api'))
.set('_assets', resolve('/src/assets'))
},
// less 全局样式引入
pluginOptions: {
'style-resources-loader': {
preProcessor: 'less',
patterns: [
'./src/assets/less/index.less' // 全局less路劲
]
}
},
devServer: {
proxy: {
"^/api": {
target: "http://localhost:3000",
changeOrigin: true, // 是否跨域
ws: true, // websocket
pathRewrite: { // 重写路径
"^/api": ''
}
}
}
}
};
3、 重新启动
使用ActiveXObject往word中插入书签
new ActiveXObject("Word.Application").Bookmarks.add(bookmard)
// bookmard 为需要添加的书签名
// 使用pageoffice
document.getElementById(pageOfficeDom).Document.Bookmarks.add(bookmard)
解决图片防盗链的问题
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.