0%

1
2
3
4
5
6
7
const findData = await Assets.findOne({
where: {
barCode: {
[Op.like]: `%${getCode}%`,
},
},
});

sqlite3 就不必多介绍了,讲一下今天踩的几个坑和解决方案

https://github.com/TryGhost/node-sqlite3

Electron 中使用 sqlite3

最小安装用例,package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "sqlite3",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"electron": "^18.1.0",
"electron-builder": "^23.0.3",
"sqlite3": "^5.0.4"
},
"scripts": {
"start": "electron .",
"postinstall": "electron-builder install-app-deps"
}
}

直接运行 npm i 或者 yarn 安装依赖

非常好用的自己命令行编译的方法

方法一:官方的安装方法

--target=18.1.018.1.0 改成自己的 Electron 版本号

1
npm install sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=`brew --prefix` --runtime=electron --target=18.1.0 --dist-url=https://electronjs.org/headers

方法二,先下载,后编译

1
2
3
4
npm install node-gyp -g
npm install sqlite3 --ignore-scripts
cd node_modules/sqlite3
node-gyp rebuild --target=16.0.6 --arch=arm64 --dist-url=https://electronjs.org/headers --module_name=node_sqlite3 --module_path=../lib/binding/napi-v3-darwin-arm64

之所以加上 --ignore-scripts,是因为 sqlite3 模块在 package.json 文件中写了下载时自动执行编译的脚本,如下:

1
2
3
4
"scripts": {
"install": "node-pre-gyp install --fallback-to-build",
......
}

方法三,参数更全,自己配置 node-gyp 执行脚本路径等,具体参数需要看 node-gyp 的文档

1
"/opt/homebrew/Cellar/node/17.5.0/bin/node" "/Users/username/Documents/Temp/sqlite3/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/Users/username/Documents/Temp/sqlite3/node_modules/sqlite3/lib/binding/napi-v6-darwin-unknown-arm64/node_sqlite3.node" "--module_name=node_sqlite3" "--module_path=/Users/username/Documents/Temp/sqlite3/node_modules/sqlite3/lib/binding/napi-v6-darwin-unknown-arm64" "--napi_version=8" "--node_abi_napi=napi" "--napi_build_version=6" "--node_napi_label=napi-v6"

踩坑及解决方案

NodeJS 17 版本问题

头铁使用最新版本 NodeJS v17.x 时,sqlite3 安装失败,报错:

1
2
3
gyp: name 'openssl_fips' is not defined while evaluating condition 'openssl_fips != ""' in binding.gyp while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1

https://github.com/nodejs/node-gyp/issues/2534

官方说法是 Nodejs 17 版本对 openssl_fips 不太支持,或者说有复写操作。

https://github.com/nodejs/node-gyp/issues/2534#issuecomment-976089582

解决方法如下

https://github.com/nodejs/node-gyp/issues/2543#issuecomment-1072104626

  • node-gyp 在本地安装最新的:
1
npm install -d node-gyp@latest

binding.gyp 中,添加(在顶部):

1
2
3
4
5
6
7
{
"variables": {
"openssl_fips" : "0"
},

...
}

但是我认为最好的办法是降回正式 16.x 版本

Homebrew 问题

如果你用 Homebrew 安装了 Nodejs,那么编译的时候参数会有所变化,多出一些参数

1
"/opt/homebrew/Cellar/node/17.5.0/bin/node" "/opt/homebrew/bin/npm" "install" "sqlite3" "--build-from-source" "--sqlite_libname=sqlcipher" "--sqlite=/opt/homebrew" "--runtime=electron" "--target=18.1.0" "--dist-url=https://electronjs.org/headers"

会多出一个 "--sqlite=/opt/homebrew" 的参数,而你电脑上没装 sqlite3 就会产生报错导致编译失败。

解决方案,Homebrew 或者 brew 卸载 Nodejs,用官方的 Nodejs 安装包重新安装

其他

Mac 卸载 Nodejs

编译 Electron sqlite3

Mac 卸载 Python

问题

NestJS debug 调试

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "My application Name",
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
"args": ["${workspaceFolder}/src/main.ts"],
"autoAttachChildProcesses": true
}
]
}

参考文章

1
2
3
4
5
6
7
8
9
10
11
function isValidHttpUrl(string) {
let url;

try {
url = new URL(string);
} catch (_) {
return false;
}

return url.protocol === 'http:' || url.protocol === 'https:';
}
1
2
3
4
5
6
7
8
9
10
11
12
function validURL(str) {
var pattern = new RegExp(
'^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$',
'i'
); // fragment locator
return !!pattern.test(str);
}
阅读全文 »

问题

后端对提交的数据进行了一些转义操作,比如 <p><b>123&456</b></p> 这样的,会被转义成 &lt;p&gt;&lt;b&gt;123&amp;456&lt;/b&gt;&lt;/p&gt;

然后前端请求数据时,这些数据需要反转义一下

解决

这是我目前用到的,不必担心性能问题,见后面的研究部分。

1
2
3
4
5
6
7
8
// 反转义 bug@&amp; 这样的字符
export function HTMLDecode(text) {
var temp = document.createElement('div');
temp.innerHTML = text;
var output = temp.innerText || temp.textContent;
temp = null;
return output;
}
阅读全文 »

问题

NestJS 接收单个文件的上传和批量多个文件上传,及上传文件添加额外参数

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import {
Controller,
Post,
Body,
UseInterceptors,
UploadedFile,
UploadedFiles,
Request,
UseGuards,
StreamableFile,
Get,
Response,
Param,
} from '@nestjs/common';
import { FileInterceptor, FilesInterceptor } from '@nestjs/platform-express';

// 单文件 + 其他字段
@Post('uploadPdf')
@UseInterceptors(FileInterceptor('pdf', { dest: './uploads' }))
async uploadPdf(@UploadedFile() file, @Body() body) {
console.log(file, body);
}

// 多文件 + 其他字段
@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
{ name: 'avatar', maxCount: 1 },
{ name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
console.log(files);
}

参考文章

想做一个对象检测,和自己训练模型,目前处于查资料状态,还未开始。

问题

拦截点击play后的播放事件

解决

1
2
3
4
5
Video.addEventListener('play', event => {
console.log('视频播放器播放事件', event);
Video.pause();
Video.currentTime = 0;
});

参考文章

问题

搜集所有的图片及视频的加载状态

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let imageList = document.querySelectorAll('#q-editor img');
for (let index = 0; index < imageList.length; index++) {
const element = imageList[index];
const imageUrl = element.getAttribute('src');
element.addEventListener('load', () => {
console.log('图片加载完成,重新传高度', imageUrl);
getWebviewSize();
});
}

// 视频搜集
let videoList = document.querySelectorAll('#q-editor video');
for (let index = 0; index < videoList.length; index++) {
const element = videoList[index];
const videoUrl = element.getAttribute('src');
element.addEventListener('loadeddata', () => {
console.log('视频加载完成,重新传高度', videoUrl);
getWebviewSize();
});
}

参考文章

图片状态

视频状态