jrainlau.github.io
jrainlau.github.io copied to clipboard
My personal blog.
 最近的工作内容,是开发基于 Electron 的桌面应用。在应用开发完成后,即面临着如何进行版本迭代的问题。如果按照传统桌面应用的思路,只能在发布新版本的时候同步上架到官网和商城,通过在应用内设置引导等方式让用户手动去进行版本更新。这种方式对于新版本的覆盖率增长来说是非常被动的,绝大多数用户都会下意识地觉得,我当前版本用得好好的,为什么要这么麻烦地升级呢?还要自己下载、自己安装,麻烦死了。 万幸的是,Electron 官方自带升级模块,也就是今天要研究的 `electron-updater`。该模块允许应用自己更新自己,无需依靠用户手动下载和安装。为了探究这个模块是如何运行的,我们首先来做一个简单的 demo。 > 完成的 demo 地址在[这里](https://github.com/jrainlau/wonderland) ## 简单的 demo 实现 新建一个空目录,命名为 `/wonderland`,然后进行项目初始化: ``` yarn init -y yarn add electron electron-builder -D yarn add electron-log...
 任何的前端组件库,无论是业界内有名的 tdesign,ant-design 还是 element-ui 也好,它们都有着自己的一系列图标。经过观察发现,这些图标都是在组件库发布的时候就已经基本稳定了,鲜有调整,所以可以一直存放于组件库的 git 仓库中。 但是我们当前业务所使用组件库,是根据业务需要逐步搭建的,里面的图标也在不断地更新。在很长一段时间内,我们也是采用让图标入库的方式,随组件库一同维护。设计团队新增的每一个图标,都需要委托组件库开发者让图标入库、提交、发版本、业务侧更新组件库版本。这样的做法所带来的问题,就是操作繁琐,效率低下,还会导致组件库的版本号飞涨,CHANGELOG 几乎清一色的“新增一个图标”,不利于整体维护。 为了解决这个问题,一个思路是让组件库和图标库进行解耦,分别维护,用的时候再组合起来。tdesign 就是这么做的:  https://tdesign.tencent.com/vue-next/components/icon 但这样也还是有点麻烦,就是图标的 npm 库也是有维护成本的,也是需要设计导出图标以后,添加到 git 仓库并发布;业务侧也要及时去更新图标库。 有没有一种办法,能够把上面所说的这些步骤也省了呢?下面就来展开说说我们是怎么做的。 ## 解决思路 整体的思路上,也是遵循“解耦”的理念,让组件库和图标库相互独立。首先来分析一下我们的业务和图标的关系。 1、在我们的业务里,图标都是使用的 SVG 格式,是可以放在 CDN...
 说到 Vue 的组件库,大家肯定早已耳熟能详,随随便便就能列举出一大堆。那为什么还需要自己去搭建呢?结合自身的经验,在业务中往往需要高度定制化的组件,无论是 UI 和交互,可能都会跟市面上现有的组件库有着较大的出入。这个时候如果是基于现有的组件库进行修改的话,其理解成本和修改成本也不小,甚至比自己搭建一套还要高。因此搭建一套自己的组件库还是一个相当常见的需求。 对于一个组件库来说,除了”组件“本身以外,另个一个非常重要的东西就是文档展示。参考市面上优秀的开源组件库,无一不是既有高质量的组件,更有一套非常规范且详细的文档。文档除了对组件的功能进行说明以外,同时也具备了组件交互预览的能力,让用户的学习成本尽可能地降低。 对于许多程序员来说,最讨厌的无非是两件事。一件是别人不写文档,另一件是自己写文档。既然在组件库里文档是必不可少的,那么我们应该尽可能地减少写文档的痛苦,尤其是这种既要有代码展示、又要有文字说明的文档。 市面上对于组件文档展示的框架也有不少,比如 Story Book、Docz、Dumi 等等。它们都有一套自己的规则能够让你展示自己的组件,但是对于团队来说学习成本较高,同时它们也在一定程度上割裂了“开发”和“写文档”之间的体验。 如果在开发组件库的过程中能够一边开发一边预览调试,预览调试的内容就是文档的一部分就好了。开发者只需要关注组件本身的开发,然后再稍微补上一点必要的 API 和事件说明即可。 我们这次就要来搭建这么一套体验超级丝滑的组件库开发框架。先上一个最终成果的例子,随后再一步一步地教大家去实现。  [在线体验 ](https://jrainlau.github.io/MY-Kit/index.html#/components/Button) [Github 仓库 ](https://github.com/jrainlau/MY-Kit) [演示视频](https://user-images.githubusercontent.com/12172868/145698280-730751be-a3f8-4989-abc2-dcf467362fb1.mp4) ## 一、开发框架初始化 这一套开发框架我们把它命名为 `MY-Kit`。在技术选型上使用的是 Vite + Vue3...
 最近接到了一个需求,需要通过第三方提供的 d.ts 文件来定义对应的 JS SDK 文件,其形式如下: 第三方提供的 d.ts 文件: ```typescript export class SDK { start(account: string); close(); init(id: string): Promise } ``` 定义出来的 JS SDK 文件: ```javascript // 初始化...
在最近的需求中,设计师给了我两个 apng 格式的动图,要求是在同样的位置,第一个动图播放1遍,第二个动图循环播放,中间要自然衔接和过渡。   apng 格式的动图是我第一次使用到的,我对它的了解仅仅局限于“会动的png图片”。后来几经搜索,总算是把 apng 的一些知识点给补全了。由于网上关于 apng 的资料非常多,因此就不在这里对 apng 进行过多的介绍了。 浏览器默认没有提供 api 让我们去操纵 apng,所以我们无法直接监听 apng 的播放事件,更无法控制它的播放动作。怎么办呢?还好有万能的 npm,直接搜索 apng 就出现了一个名为 [apng-js](https://www.npmjs.com/package/apng-js) 的库,它可以满足我们的需求。 apng-js 写得很简洁,其核心原理是按照 apng 的规范解析 apng 图片的数据,然后把它们绘制到...
 在搜索领域,早已出现了“查找相似图片/相似商品”的相关功能,如 Google 搜图,百度搜图,淘宝的拍照搜商品等。要实现类似的计算图片相似度的功能,除了使用听起来高大上的“人工智能”以外,其实通过 js 和几种简单的算法,也能八九不离十地实现类似的效果。 > 在阅读本文之前,**强烈建议**先阅读完阮一峰于多年所撰写的[《相似图片搜索的原理》](http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html)相关文章,本文所涉及的算法也来源于其中。 > 体验地址:https://img-compare.netlify.com/ # 特征提取算法 为了便于理解,每种算法都会经过“特征提取”和“特征比对”两个步骤进行。接下来将着重对每种算法的“特征提取”步骤进行详细解读,而“特征比对”则单独进行阐述。 ## 平均哈希算法 参考阮大的文章,“平均哈希算法”主要由以下几步组成: > 第一步,缩小尺寸为8×8,以去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。 > > 第二步,简化色彩。将缩小后的图片转为灰度图像。 > > 第三步,计算平均值。计算所有像素的灰度平均值。 > > 第四步,比较像素的灰度。将64个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。 > > 第五步,计算哈希值。将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。...
 一直觉得 Codepen 的在线代码预览系统很神奇,能够所见即所得地实时展示代码的运行效果,无论是代码演示,还是测试功能,都是非常方便快捷的存在。刚好最近手头有业务需要用到类似 Codepen 的能力,经过一番调研之后开发了一个具有基本的在线运行代码能力的 demo 出来。 > 在线体验地址:https://jrainlau.github.io/online-code-runner/ > > 由于业务只需要执行 JS 代码,因此 demo 也只具备 JS 代码的运行能力。 # 一、原理 我们知道,浏览器是通过自带的引擎来处理 html,css 和 js 资源的,处理过程在页面载入的时候就已经开始。如果我们想要动态地运行这些资源,对于 html 和 css 我们可以用...
冒泡排序号称是最简单的排序算法,其原理要理解起来确实是非常简单,这里直接摘抄其他人总结的定义: > 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。 > ——摘抄自[菜鸟笔记](https://www.runoob.com/w3cnote/bubble-sort.html)  然后经典的冒泡排序算法可以这样写: ```javascript function bubbleSort(arr) { for (let i = 0, len = arr.length; i < len - 1; i++) { for (let j =...
 在春节假期无聊刷手机的时候,偶然间看到了一篇关于“位掩码”的文章,本身就是奇怪知识的它可以用来解决一些奇怪的问题,实在是非常有趣。 # 位运算符 在了解“位掩码”之前,首先要学会位运算符。 我们知道,在计算机中数据其实都是以二进制的形式所储存的,而位运算符则可以对二进制数据进行操作。举个简单的例子,给定两个二进制数据(其中 `0b` 是二进制数据的前缀): ```javascript const A = 0b1010 const B = 0b1111 ```  ### 1、按位非运算符 `~` 对每一位执行**非(NOT)**操作,也可以理解为取反码。  ### 2、按位与运算符 `&` 对每一位执行**与(AND)**操作,只要对应位置均为 1 时,结果才为...
 在最近的工作中,有一项内容是需要知道当前用户的网络情况以采取对应的展示策略。这块内容是我之前没有研究过的,正好趁此机会了解一下。 那么我们要怎样做才能获取到用户的网络速度呢?下面是调研到的几种方法。 ## 一、通过 `window.navigator.connection` API 获取网速 在 Chrome 浏览器种,我们可以使用 `window.navigator.connection` API 中的 `downlink` 属性来获取实时网速:    根据 [MDN](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlink) 文档的说法,该 `downlink` 属性是以每秒兆位为单位返回有效带宽估计值。比如当 `downlink` 的值是 5.0 的时候,理论下载速度可能是 5Mb/s。 遗憾的是,这个...