距离上一篇issue 已经块两月时间, 断更也主要是因为工作太忙. 由于工作忙碌, 业余也不再有啥有意思的个人项目了. 果然, 摸鱼才是第一创造力🤪
当前各家低码平台(这里讨论的是lowcode 非 nocode )技术上一般是使用结构由结构化json描述用户通过可视化编辑产生的应用, 然后再通过编译或者运行时动态将json转换成可执行代码, 这种方式技术门槛低, 生成出的产物勉强可用, 但是体验性能堪忧, 相比开发人员开发的应用, 缺陷主要在于:
所以现在低码平台面临的状况比较尴尬: 会写代码的人不会用它, 因为会显著降低开发效率; 不会写代码的人很难用起来, 处处遇到技术壁垒, 稍微有点自定义的需求即一筹莫展.
目前仅垂直领域的低码产品比较成熟, 如面向 地产、电商、OA、运维管理的产品, 特定领域有其特定的使用场景、要解决的问题、固定的交互模式及组件等, 这种平台开发起来要简单很多, 也的确能解决实际问题. 而那些愿景是大而全(什么都能做)的低码平台反而没有什么能实际落地使用的场景, 解决不了任何实际问题, 还处于玩具阶段.
即使各种低代码平台目前都不成熟, 但它依旧会继续发展、向前进步, 毕竟它的确能解决部分场景的问题、降低成本、提升效率, 未来很诱人. 说回低码的技术上, 目前出现了一些元编程的低码平台, 能有效的解决上述的五个弊端. 所谓低代码元编程, 即将源代码作为低代码可视化编辑器的产物, 而非冗长的结构化JSON对象, 同时也可以直接修改生成的源代码, 可视化编辑器会跟随动态变化. 这样的平台已经有几家了:
元编程 听起来很玄乎, 但这类产品早就面世了, Adobe 在 2005 发布的 Dreamweaver 即是这种产品: 你可以完全通过可视化界面来开发网页, 也可以直接编辑它生成的代码(它生成的代码和手写代码无异, 甚至质量更高). 另外 Visual Studio / Xcode / Android Studio 等原生客户端IDE自带的可视化开发工具也是元编程的理念. 而低码的元编程与 Dreamweaver 并无本质差异, Dreamweaver 编辑的是原生的标签、属性, 而低码元编程则是要编辑自定义标签(自定义组件)、自定义属性等. 当然低码元编程除了需要使用到最基础的语法分析技术, 还需要解决各类框架、预处理语言的问题, 有更高的技术门槛.
一般在一个设计良好的产品中, 会有统一且一致的设计风格, 这个风格可能和我们现有(或第三方)组件库风格有差异, 而组件库为了更通用更灵活会有多种风格和用法, 但我们通常只会使用组件库的某一种风格或用法, 又或者需要一种新的风格或用法. 这里有一种更好的使用方式, 能大大提高开发效率, 这也是大家很容易想到也很容易忽略的方式:
日常开发中, 经常会遇到使用的npm包依赖的npm包版本过时了, 此时除了给npm包的作者提PR, 貌似就束手无策了. 其实, 我们可以在项目的package.json中重写依赖的版本, yarn 和 npm (不思进取的npm在 8.3 才开始支持 ) 分别以不同的方式支持了:
yarn 在package.json 中声明 resolutions
字段, 参考文档:
1 | { |
npm 则使用 overrides
字段, 官方文档:
1 | { |
最近在工作中发现一个偶发问题, 一个异步函数明明已经在使用时 try-catch, 但总是无法捕获住其内的异常. 精简后的示例代码如下:
1 | async function task() { |
观察了好久才意识到调用 someAsyncSubTask
时未添加 await
关键字, 导致其根本无法捕获其内抛出的错误.
这种错误其实可以通过添加下述代码(最好添加到所有代码执行之前)来监控到:
1 | // nodejs 中 |
JavaScript Booster - Visual Studio Marketplace
这是一个可以为Javascript/Typescript代码提供书写建议的插件, 可以快速完成一些常见的机械化操作:
Tips: VSCode 中触发代码建议的快捷键是 CMD + .
(macOS) / CTRL + .
(windows, 没有尝试过, 应该默认是该快捷键😬), 你也可以在VSCode 的设置中搜索 editor.action.quickFix
来修改该快捷键
Quokka.js - Visual Studio Marketplace
日常开发Js/Ts 时, 如果要快速测试函数功能, 常见做法是使用chrome开发工具的console 或者 编写一个单独 nodejs 脚本用于测试. 该插件可以在VSCode中快速新建JS/TS 的 playground, 可即时查看执行结果及代码块是否执行到, 能极大的提高开发效率.
使用方法: 按快捷键 cmd + shift + p
(windows下则使用 ctrl + shift + p)打开命令面板, 输入 Quikka
, 选择 Quokka.js: New File
, 再根据自己需要选择自己需要的语言来新建playground.
rust 是由 Mozilla 创建的内存安全编程语言, 近年来受欢迎程度逐年攀升, 作为低级语言, 大有替代 C语言的趋势, Linux 和 Android 都已经支持使用 rust 进行内核开发. 作者针对前端开发人员编写了一份rust交互式学习教程, 由浅入深, 很容易上手. 学习 rust 可使用其来开发 webassembly , 也可以拓展自己的眼界、突破思维局限.
文章地址: codeamigo
Google 的 Chrome DevTools 开发工程师提了以上建议, 理由如下:
虽然有以上这么多好处, 但是我目前不会采取该策略, 毕竟node_modules 中的内容实在太大了, 而手中的项目也没有如此重要, 工作团队中其他成员也大概也很难接受😄
文章地址: Why you should check-in your node dependencies - Jack Franklin
当你有如下迹象时, 你该考虑了:
文章地址: 5 Signs It’s Time to Quit Your Job – Accidentally in Code
很多软件的激活码就是32位或64位的序列号, 很容易找找到各种破解工具, 可以直接产生随意数量的能正常激活软件的序列号. 作者提出了使用 RSA 非对称加密算法来产生激活码, 这样即使客户端软件被破解(甚至直接开源), 也难以制作出可以随便生成激活码的工具. 本篇文章是讲如何用 Swift 来实现这个思路.
文章地址: Creating a licensing system for paid apps in Swift
这个前端开发者的博客非常精美, 博客中有可演示代码效果的 playground, 也有可直接操作的组件. 这篇文章讲他如何做到的. 他的博客其他文章也挺好的, 推荐添加到 rss 订阅列表.
]]>unable to verify the first certificate
错误近期有用户反馈: 同一个API接口,在浏览器、安卓客户端、iOS客户端、小程序里都能正常调用,但是在Nodejs 中却遇到了 unable to verify the first certificate
错误。
经过一番研究,发现这是目标网站证书配置错误导致的问题,在Nodejs这一侧解决的方案也很简单,有两个方法:
require('https').globalAgent.options.ca = require('ssl-root-cas/latest').create()
让 Nodejs 能正确校验网站证书process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
,禁用 Nodejs 对 HTTPS 网站证书的校验。不推荐,有安全风险这个问题的根本原因在于网站的证书证书配置错误:证书信息不完整,一般是缺少中级证信息,而 Nodejs 会严格校验证书信息,导致了该错误。其他端不会出问题,则是因为他们会智能的尝试补全缺失的证书信息,反而惯坏了网站的配置管理员😒。
相关参考资料:
如果你有一个UI组件包或者一个工具包想要在小程序和Web上都可以用上,这个包大部分代码共享,只有少部分代码针对特定平台编写,那如何通过一个NPM包同时支持Web呢?
小程序官方支持在NPM包中通过package.json的miniprogram
字段来特别指定包在小程序中的入口文件所在的文件夹(注意,是文件夹而不是文件), 与标准的 main
字段含义类似。这样我们可以这样来声明package.json, 并保证打包后的目录和声明的一样:
1 | { |
参考链接: https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html
苹果的服务和功能因为各种原因会在基于地理位置进行阉割, 使用该配置可绕过相关限制.
链接: iRingo: 解锁完整的 Apple功能和集成服务
Webpack 是前端常用的构建工具, 功能强大、无所不能, 但其配置复杂、性能低下也常被人诟病, 下边推荐一些非主流的构建工具(其实都已经非常出名了)供你选择, 不同场景选择最适合的工具, 能大大提高你的工作效率.
我觉得大家(现代人类)注意力越来越涣散, 3x速、快餐文化并不是啥好事, 什么东西都是浅尝辄止、浮于表面,很难长时间集中注意力,也很难专注的去做一件事。
3倍速听书,并不会提高你的学习速度,因为人脑需要时间去理解和记忆,3倍速也只会让你听到的东西变成短暂的记忆,很难被你吸收,最后变成过眼云烟。同样的,3倍速看剧也有同样的问题,更糟糕的是,3倍速会让人物的语气、背景乐变得诡异,也将进一步让你难以理解剧情(国产注水电视剧不在讨论之列,4x看国产剧都不过分)、降低看剧的体验。
如果你觉得3倍速、看电影解说、听别人讲书籍精华等等快餐式文化消费并没有让你收获更多,那不妨试试 静下来、慢下来,用正常的速度好好看一部剧、看一本书。看的数量、速度并不是我们应当追求的,看的质量才是最重要的。
吸烟有害个人身体健康、容易上瘾,且危害社会公共卫生。如果当代有人发现了类似烟草的对身体有害且容易上瘾的产品,想在市场上销售,应当没有国家会允许。那为何我们没有禁止吸烟呢?主要有两个原因:
故,现代国家通过重税、限制吸烟场所、香烟包装盒写警示语或贴恐怖图片、禁止香烟广告等措施在逐步限制抽烟。
原文: 美国卫生研究所: Why do we still permit tobacco use?
现在, 我将再次启用博客, 不定期更新内容, 记录自己的日常及学习心得, 锻炼自己的书写能力, 也磨砺自己的思维. 文章将依旧以短文为主, 降低读者阅读时间(毕竟在这个年代, 大家的时间都过于宝贵, 精力也越难以长时间集中), 也减少我写作一篇文章的耗时.
重启的同时, 我也对本博客进行了优化, 将博客页面核心内容加载大小从原来的几百Kb降低到了不到100Kb.
博客是基于hexo构建的静态博客, 使用了tranquilpeak主题, 托管在 Github Pages, 同时还使用了 cloudflare 的免费cdn. 以下是几个优化点, 仅供参考:
avif
格式的图片压缩效果惊人, 可以将图片压缩至原图大小的 10% 以内, 图片效果并没有明显变化, 而且比较新的浏览器均已支持. 于是我将网站背景图额外压缩了 avif
、webp
(压缩率次之)两种格式的图片博客仓库地址为 https://github.com/oe/blog.evecalm.com, 感兴趣的可以前往观摩.
]]>最新的 Safari 15 已经支持了 Theme-color 特性, 可以用于设置浏览器顶部的地址栏颜色, 使地址栏和网站看起来浑然一体. 于是我又开始折腾起来.
综合搜索 已经使用了 Pexels 提供的免费API来获取背景图片, 并且会定时更新, 我希望主题色能根据背景图而变, 使用背景图的主色调作为主题色, 这样看起来整个效果更加协调. 于是我使用了之前的文章 如何获取图片上某个像素点的颜色值 中提到的获取图片平均颜色的方法, 将主题色设置为背景图的平均颜色. 下边是添加主题色前后的效果对比.
计算图片的平均颜色, 需使用 canvas 技术, 这里面需要注意两点:
img
标签加载, 但是并不一定支持跨域(需要图片请求的响应头包含 Access-Control-Allow-Origin
和 Access-Control-Allow-Methods
等头), 可访问 enable-cors 获取相关信息. 幸好 Pexels 支持跨域了img
元素需要设置 crossOrigin
属性: 一般设置为空字符串即可, 详情可访问 img#attr-crossorigin, 如果通过 js 创建 img 标签来加载图片, 则该属性必须在设置图片 src
之前因为网站背景色会不断变化, 就很容易出现网站中心内容的文字在浅色背景下难以辨认的问题, 虽然给内容区域添加了半透明背景, 但情况依旧没有改善. 于是乎, 我想到将文字颜色设置成主题色的反转色, 以此来增强文字的辨识度, 提升可读性. 这里我使用了一个css 的 filter
属性:
filter: invert(100%)
, 详细可 参考mdn
最终的效果的确令人满意, 但并非我一开始期望的主题色的反转色, 而是将文字原本的蓝色主色调反转成了某全球知名视频网站的主色调: 金黄色. 阴差阳错的发现, 这种黄色在各种背景图下辨识度都非常好. 虽然这个颜色看来有点不太舒服, 还是将错就错吧, 懒得改了. 下面是最终的效果图.
相关链接:
一番搜索后, 发现了一个神奇的API: Canvas 的 context.getImageData(x, y, width, height)
可用于获取图片的像素信息:
1 | const canvas = document.createElement('canvas') |
由上述例子可见, 一个像素点由四个数字描述, 分别为 r
g
b
a
, a
为 255 则表示完全不透明即 alpha 通道值为 255/255 = 1.
有时候我们需要知道图片的平均颜色, 用于产生对应的占位缩略图, 抑或有其他目的. 计算平均颜色的思路很简单: 分别统计每个像素点的 r
g
b
a
的总值, 再除以像素个数
1 | // 接上边的示例代码 |
由于浏览器的安全策略, 在不经过特殊处理时, canvas 是无法加载跨域图片资源的. 图片资源所在的服务器必须允许跨域请求方可被 canvas 加载
我想到两个思路, 但都不完美:
document.elementFromPoint(x, y)
获取坐标对应的dom元素, 在使用 window.getComputedStyle(element)
获取元素实际渲染的样式, 再取背景色或文字颜色. 这个方法就错更远了: 首先 elementFromPoint
取到的可能是透明蒙层元素; 再次 getComputedStyle
拿到样式后也无法确定应该取文字颜色还是背景色, 遇到颜色渐变的束手无策; 最后 对 图片、视频、画布等复杂标签同样无法处理aa:bb
中的 :
垂直居中显示针对第一个问题, 很容想到的就是使用自定义元素绘制两个垂直居中的点, 但是略显麻烦, 且不能利用字体的特性(大小/颜色/行高等). 于是还是想通过字符实现, 因为在 unicode 中有大量字符, 一般的标点字符都有多种变体以适用于不同场景, 总有一款能适合我的吧.
查阅百科发现, 冒号的确有十多种变体, 如宽度不一样的, 形状奇特的, 位置有偏移的, 等等. 可没有一个符号满足我的这个简单需求. 在尝试中, 偶然发现, 冒号两边是数字时, 冒号自然就垂直居中了, 如下图所示
(如果你想自己验证该现象, 可以在最新的macOS 上安装最新版钉钉, 在输入框中输入上述文字即可)
一切就豁然开朗了, 这就是连字 现象, 不禁觉得苹果用户体验做的很好, 极大的缓解了强迫症症状.
连字就是将两个及以上字符合成一个字符, 连字需要在下述两种条件均满足时才会显示出效果.
连字的应用其实非常普遍, 对程序员来说影响最大的就是一些编程专用字体了. 所谓编程字体, 就是:
编程字体推荐: ProgrammingFonts
代码编辑器(IDE)开启连字功能的方法: How to enable ligatures
再回到第二个问题, 其实问题的本质是: 「当我们设置 字体大小 时, 设置的是字体的宽还是高?」
经过一番试验测量(使用了PixelSnap测量, 该软件为付费用软件, 但已经包含在了SetApp中)后发现:
通过查阅资料字体解剖得知, 字体大小 所指的就是字体高度, 字体宽度是随字符及字体而变的
在显示时间时, 秒数时刻在变, 不经过特殊设置, 会明显的发现整个时间字符宽度一直在不停变化, 对强迫症来说是一种煎熬. 这时候, 把字体换成一种「等宽字体」即可解决问题.
一般设置字体时, 可以设置为某一种特定字体, 比如 Helvetica
、微软雅黑
, 也可以是某一种字体类型(一种字体类型会包含多种字体, 若指定为字体类型, 则由系统底层自行决定使用哪一个字体渲染). 一般字体类型有:
serif
: 中文字体中也称「白体」, 此类字体会有很多点缀修饰, 如 宋体、楷体. 衬线体由于多了边角修饰, 会相对美观, 但是也多了信息噪音, 容易使用户产生视觉疲劳, 一般建议仅针对需要着重强调的文字(比如 文章标题)采用该类型的字体. 同时由于衬线体的修饰元素不规则, 会产生锯齿现象, 实际使用时应结合反锯齿技术才能达到较好的显示效果.sans-serif
: 中文字体中也称「黑体」, 与衬线体相对, 该类字体没有多余的修饰, 如 微软雅黑 等. 无衬线体 适合屏幕中大量使用, 不会导致用户产生视觉疲劳问题.monospace
: 此类字体每个字符宽度一致. 由于东亚的字体的字符本身基本都是等宽的, 所以一般在说等宽字体时, 都是指西文字体. 该字体的可读性较好, 一般在 代码编辑器 及 Terminal 中使用比较普遍.当代浏览器已经禁用了 Flash, 故在浏览器中播放视频只能使用 video
标签(若有安装浏览器插件, 则有例外情况, 在此不做讨论), 而调整速度使用 playbackRate
API 即可, 原理上来说很简单.
右键点击播放器, 使用浏览器的审查功能, 快速定位到了 video
, 在开发工具的 Console 中执行代码 $0.playbackRate = 2
, 视频播放速度加倍, 一切看似OK.
然而进一步完善时, 发现情况没这么简单. 在 Console 中执行代码 document.querySelector('video')
返回为null
, 而非一个DOM节点. 通过查找 video 标签所在的父级标签, 发现了如下图所示的 #shadow-root(closed)
标记. 原来视频标签在 Shadow DOM 中, 被隔离开了, 使用JS API还是可以正常访问 Shadow DOM 中内容的.
但意外情况又发生了, 访问Shadow DOM宿主元素的 shadowRoot
时, 又返回的了 null
. 这时才留意到 #shadow-root(closed)
标记中的 (closed)
, 查阅资料后发现: closed
为 ShadowRoot 的 mode, 有 open
和 closed
两个值: open
表示 ShadowRoot 可以被JS访问, closed
则相反. 于是还需要进一步尝试.
基于以上情况, 我便考虑如何将 closed
改为 open
. ShadowRoot 的 mode
属性为只读属性, 无法直接修改, 于是猜测应当可以通过劫持原生API来实现. 再次阅资料后, 应证了我的猜想. 可以通过劫持 attachShadow
实现, 于是写下了如下代码进行劫持, 并借助浏览器插件 Tampermonkey 完善了一个用户脚本.
1 | const originalAttachShadow = Element.prototype.attachShadow |
写完用户脚本反复测试时又发现了新状况: 有时候倍速生效, 有时候又不生效 ):- . 进一步猜测是和网络加载速度有关系, 因为执行脚本用户脚本的时视频资源可能还在加载初始化中. 还要继续尝试.
尝试中, 意外发现若将 Element.prototype.attachShadow = null
, 网页不会使用Shadow DOM来创建视频标签了(即视频库做了特性检测, 有fallback方案), 此时可简单快速访问到 video
标签, 于是果断放弃了上述尝试, 最后也无缝完善了本功能.
这里还有两个小点要提一下:
attachShadow
的代码应当在使用该API的代码之前执行, 所以应当在 Tampermonkey 的用户脚本设置中修改 Run At 为 document-start
video
标签做缓冲, 缓冲完之后才会创建播放视频的 video
标签, 可以通过监听父容器DOM节点的 DOMNodeInserted
事件来判断播放视频的标签是否创建在女友的建议下, 我还给播放器增加了倍速控制按钮, 和网页自带的播放器浑然天成. 也发现了网上有其他更简便的解决方案(均未亲自测验):
videojs
的API控制速度, 但对不懂代码的人来说, 使用不便且无法随意切换播放速度我的思路从原生API出发, 更通用(有时候也会更繁琐), 不受浏览器(需要浏览器支持用户脚本, 现代浏览器均已支持)和使用的JS库限制.
]]>重启博客后的第一篇文字, 就来分享下自己获取资讯使用的软件和网站吧.
平时获取资讯主要通过 rss 阅读软件来订阅聚合多个网站的资讯, 个人使用的是 Mac 电脑 + iPhone, 故推荐的软件也都是苹果平台的软件.
如果你不了解 rss, 可以先阅读下阮一峰的这篇介绍文章.
注: 以上部分 rss 地址为 Google 服务提供, 故可能需要特殊方式才能访问
rss
或者 xml
, 若网站有提供 rss, 则一般会在 源码中的 head
标签中找到扩展已经发布至Chrome Web Store,记得使用前阅读下选项页的帮助内容。
扩展源码托管在github,https://github.com/evecalm/MyWebrequest
]]>那么,有没有什么好办法减少甚至完全屏蔽掉垃圾评论呢?这先得从垃圾评论的留言机制上说起。
流行的博客程序都有良好的内部结构,功能模块分的都很清晰。例如有专门负责输出rss的文件,专门负责处理提交的评论的文件等等,这些文件相对于网站的位置都是固定的,并且评论表单中用来标识昵称、邮箱及网站输入框的名称都一样!一般提交一条评论所需要的数据除了昵称、邮箱、网站地址及评论外,还需要知道文章的ID,以及这些数据提交到什么地方。而通过以上介绍,只要知道了你网站地址及博客程序类型,就知道了评论表单中几个输入框的标识名称,RSS的地址(wordpress的是http://域名/feed)也知道了,通过解析网站的rss就知道了文章ID,这些数据要提交到的地方当然就是处理评论的文件的地址(wordpress的是http://域名/wp-comments-post.php)了。所以知道了这些发送一条评论就够了,根本无需打开你的文章页面,甚至无需打开浏览器!对于使用C++、.Net编写的刷评论软件,一分钟刷个上百条评论是没有问题的。由于wordpress在全球范围内非常流行,所以使用wordpress搭建的博客经常会有英文、日文、俄文等外文垃圾留言的光顾。
现在,既然知道了垃圾评论的留言机制,那就可以对症下药了!最简单的办法就是让刷评论的软件找不到评论的提交地址!步骤如下:
将网站根目录下的wp-comments-post.php
文件复制一份,随便改一个名字(如abc.php),文件后缀不能改。
修改wp-comments-post.php
文件,在文件第一行<?php
后换行插入如下代码:
die();
comments.php
文件,该文件位置在[网站根目录]/wp-content/themes/[主题名]
,在该文件中找到wp-comments-post.php
,将其改成第一步改后的那个名字(这里就是abc.php了)。使用改方法能屏蔽掉大部分的垃圾评论。需要注意的是wordpress升级会在网站根目录下再次生成wp-comments-post.php
文件,升级后需要将步骤1和2重新操作一遍;切换主题后应按步骤3操作一遍。