分类
招聘

代友招聘:广州番禺广告公司招 PHP 工程师

做 ocpx 和 rta 方面的。dsp 平台 adx 方便的接口对接。

(上面这一行我完全看不懂……)

岗位职责:

  1. 负责公司产品后端系统维护,新功能开发,广告投放API对接;
  2. 参与需求讨论,对产品原型、功能逻辑设计等提出可靠建议;
  3. 使用yii2框架实现产品的标准化。

岗位要求:

  1. 计算机相关专业大专或本科学历,有2年以上PHP开发经验,有大型网站或者数据系统开发经验者优先;
  2. 熟悉前端语言:HTML5/CSS3,JavaScript,Ajax,jQuery等;
  3. 熟悉 MVC 框架,熟悉主流 PHP 框架 yii2,有独立开发项目经验者优先;
  4. 精通 MySQL,熟悉 Linux、Apache/nginx、Redis 的管理和维护。
  5. 有开发小程序后端、广告 Marketing API 项目经验者优先;
  6. 熟悉版本控制器 git/svn 的使用;
  7. 有优秀的沟通与表达能力,突出的学习能力,较强的动手能力与逻辑分析能力;
  8. 具备良好的团队合作精神,高度的责任感,善于沟通,为人踏实,抗压能力强,拥有严谨的工作态度,能虚心学习。
  9. 具备良好的代码编程习惯,熟悉面向对象编程,及较强的文档编写能力。

工作地点在番禺,朋友的公司,很靠谱。感兴趣的同学直接联系我吧。

分类
招聘

OpenResty Inc. 诚聘中高级前端工程师

OpenResty Inc. 是一家根植于开源 DNA 的技术型公司,我们致力于机器编程。我们有世界一流的技术实力,研发全新的技术,解决工业级别的挑战,服务全球众多企业级客户。

目前我们有四大产品,本次招聘的对象主要负责其中的 OpenResty Showman。所用到的技术栈包括 Vue 全家桶,现代化前端工具链,CodeMirror,浏览器扩展等。

岗位要求

  1. 精通 HTML/CSS/JavaScript
  2. 熟练掌握 Vue,了解其生态、发展状态,具备很好的开发和调试能力
  3. 熟悉 Web 规范,具备较强的工程能力,能够妥善规划和实施前端项目开发
  4. 熟悉 Node.js,了解前端工具链的发展,具备工具链开发能力
  5. 对设计模式等软件工程知识有较深理解
  6. 理解浏览器工作原理,具备较强的分析和调优能力
  7. 具备良好的代码习惯,能够坚持最佳实践
  8. 具备良好的自我管理能力,能独立完成工作

加分项

  1. 有实现过自己的小语言,写过语言编译器,或 CodeMirror Mode
  2. 熟悉浏览器插件机制和 API,写过自己的浏览器插件
  3. 有较强的主动学习能力
  4. 英语能力佳

工作地点不限,国家不限。我们不纠结于学历和专业,只看能力和经验。远程工作模式,自由度高。我们在深圳也有办公室。

分类
nodejs

捕获 promisify `child_process.exec` 的错误

这个东西文档里没写清楚,所以写篇博客记一下。

在 Node.js 里,我们可以使用 child_process 下的命令分裂出一个进程,执行其他的命令。这些命令包括 execexecFilespawn

我比较常使用 execspawn。前者用起来比较方便,只要传入完整的命令和参数,很接近日常命令行体验;后者传参要麻烦一些,不过可以实时获取输出,包括 stdoutstderr,比较方便给用户及时反馈。

下面贴一下文档里的例子,spawn 的使用将来有机会再说。

const { exec } = require('child_process');
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
  if (error) {
    console.error(`exec error: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.error(`stderr: ${stderr}`);
});

Node.js 8 之后,我们可以用 util.promisify() 命令将 exec 转换为 Promise 风格的方法,即不再需要 callback 函数,而是返回 Promise 实例,方便我们链式调用或者使用 Async function。

此时,它的样子是这样的:

const util = require('util');
const exec = util.promisify(require('child_process').exec);

async function lsExample() {
  const { stdout, stderr } = await exec('ls');
  console.log('stdout:', stdout);
  console.error('stderr:', stderr);
}
lsExample();

官方文档没解释清楚错误处理,经过我的尝试,是这样的:

  1. 命令发生错误,或者被意外中断都会引发错误
  2. 如果不出错,就会正确返回 stdoutstderr
  3. 否则,错误实例里会包含 stdoutstderrcode
  4. 1~127 是各种错误编码,128+ 则是 signal + 127 的结果,通常来说是受控于我们的操作。比如使用 FFmpeg 录屏的时候,结束录制就要 Ctrl+C,此时就会得到值为 128 的 code。所以此时很可能不是真的失败。
const util = require('util');
const exec = util.promisify(require('child_process').exec);

(async () => {
  let code, stdout, stderr;
  try {
    ({stdout, stderr} = await exec('ls'));
  } catch (e) {
    ({code, stdout, stderr} = e);
  }

  if (code && code > 127) {
    // 确实失败了
  }
  console.log('stdout:', stdout);
  console.log('stderr:', stderr);
})();
分类
应用

应用创意:家用媒体中心

(这个灵感部分来源于群里的同学)

前阵子群里有同学问,能否用 electron 搭建服务器,提供局域网内的文件共享。

我突然想到,可以做一个这样的简单家用媒体中心:

  1. 封装成 Electron 应用,分发部署会容易很多
  2. 集成 Ghost,作为 CMS,提供 API 和网页服务
  3. 启动后,选择本地视频文件,就自动提取关键信息,然后从豆瓣上抓取影片内容,并生成影片详情页
  4. 然后局域网内电脑就可以访问这个服务,然后点播视频
  5. 也可以集成一些下载工具,直接下载磁力、BT等开放格式

产品功用

从功能来说,虽然弱于同类产品,比如 NAS 服务器。但是对于我这样的用户来说,平时下片和看片不多,偶尔可能需要在家里不同设备上看片,如果有个低成本的贡献工具,会比来回拷简单很多。

教程价值

从教程价值来考虑,这个项目倒是可圈可点。

  1. Electron 跨平台、易部署,其实一直都很受人关注
  2. Ghost 可以提供完整的 RESTful API,甚至好用的界面
  3. 于是我们可以很容易的把注意力集中在:
    1. 使用 RESTful API 的 SPA 开发,Vue3 全家桶可用
    2. 从豆瓣等网站抓取内容,简单的爬虫开发
    3. 集成第三方库,开发下载工具

简单来说,就是技术选型潜力大,开发量可控,开发难度不大,覆盖面广,且最终产品有一定市场价值。似乎是个很好的教程题材。

分类
招聘

OpenResty 再次开启招聘!

以下内容来源于老板春哥,关键词:一流的技术实力研发全新的技术远程工作模式

OpenResty Inc. 公司诚邀有追求的工程师加入我们的研发团队。

我们的技术栈是 Nginx, OpenResty, Lua, C/C++, Perl, Python 等等。从高性能网关系统和 CDN 系统,小语言编译器的开发,再到内核开发和动态追踪,以及数据库分析和调优,还有视频生成和处理,可按能力和兴趣选择。我们有世界一流的技术实力,研发全新的技术,解决工业级别的挑战,服务全球众多企业级客户。

工作地点不限,国家不限。我们不纠结于学历和专业,只看能力和经验。远程工作模式,自由度高。我们在深圳也有办公室。

有兴趣的朋友欢迎发送简历至 talents@openresty.com

详情请戳:网页链接


另外老板说,前端也可以聊,欢迎投简历。

分类
应用

应用创意:视频剪辑工具 Not-Final-Cut

0. 目标视频类型

我日常要处理的视频类型和工作流程是:

  1. 教学视频、分享视频、讲解视频
  2. 我会录制一个长视频,说清楚前因后果,然后以此视频为主,进行剪辑,大部分时候往下剪,很少往上加
  3. 我也很少分镜、混入多素材等
  4. 我希望通过 STT,得到人声对应的文本。然后以文本为基础进行剪辑,自动删掉不要的内容。也以文本为基础,添加图层、剪辑、音乐等

1. 产品需求

做视频 Up 主一段时间之后,越发感觉缺少一个趁手的视频剪辑工具。结合我的日常录制流程,我需要的剪辑工具应该具备以下功能:

  1. 自动剪掉没有人声的部分。我不说话的片段基本都不需要保留
  2. STT,输出语音对应的文本
  3. 可以根据文本进行剪辑,比如我不想要保留“嗯啊哦这个那个”这种无意义的虚词,都可以剪掉。
  4. 可以使用新文本替代现有文本,作为字幕,自动对齐时间。
  5. 可以方便地插入 slide,用来显示需要强调的内容。时间用文字来标记。
  6. 可以方便地切分视频,类似插入分页符
  7. 可以方便地插入章节标题
  8. 可以方便地插入暂停、插入图片、插入其它视频等,都用文字作为标记。
  9. 可以加片头、片尾、背景音乐等。

2. 产品形态

至于产品形态,我觉得可以分三种:

2.1 命令行工具

  1. 安装:npm i @meathill/nfc
  2. 启动:nfc a.mp4
  3. 打开浏览器,编辑并保存、导出

需要用户能够自行配置 node.js 环境、自行配置 ffmpeg、自行配置云服务 key。可以开放给其它录制教学视频的开发者使用,以便收集需求、bug,说不定还有人给我发 PR。

2.2 Electron 打包

像普通软件一样使用。可以卖给普通用户,不过考虑到大家的付费意愿,不一定能收回云服务的成本。也会有大量盗版问题。

还有个办法是要求用户注册,付少量的费用,只 cover 阿里云的费用。因为转码过程在本地,不消耗我的资源。

2.3 网站

用户上传视频到网站,在线编辑,导出。成本控制会容易一些,不过运营网站挺麻烦,而且视频剪辑需要的资源不是一星半点。

3. 项目启动

项目早就启动了,不过搁置很久了,以后继续吧。

感兴趣的同学可以关注:https://github.com/meathill/not-final-cut

4. 项目进展

  1. 选定视频开始编辑
  2. 剪辑文字
  3. 剪掉没有人声的片段
  4. 导出视频
  5. 修改字幕
  6. 添加章节封面
  7. 打包发布
  8. electron 版本
  9. 网站版本
分类
职业

再谈谈远程工作,主要供老板们参考

近期有几个朋友找我咨询远程工作的问题,都是老板,因为种种原因,考虑给团队开远程的口子。我也很长时间没分享远程工作的感受了,所以再写一篇。

0. TL; DR

  • 不是所有人都适合远程工作;
  • 远程工作对团队的要求很高,对老板的管理能力要求也很高。

老板开设远程岗位、推行远程工作时务必要慎重。

1. to 老板

通用能力,集中办公也需要的能力,此处不再赘述。

1.1 加强前置沟通

首先是流程。远程工作,尤其是全员远程的情况下,充分的前置沟通非常重要。

因为彼此距离很远,沟通成本高了很多,随口一问一答不太可能,所以必须在动手前就把需求、设计、实施方案、验收标准、模块划分都沟通清楚,不然后面效率一定会收到影响。

老板要建立这样的流程并监督执行,直到大家养成习惯。

1.2 工作中沟通要积极,多留档

我厂默认异步沟通,回复时间半天内即可。所以有问题就要积极沟通;甚至不是遇到问题,自己规划了功能/界面设计,选择了技术方案,也要及时沟通。

这里的沟通可能只是发个消息给协作者,“我要 XXX 了”,“我打算 OOOO”。对方可能不回复,也没关系,因为主要目的就是加强沟通和留档。于是将来就可以回溯,其他人也能通过这里的记录了解到前因后果,做出自己的判断。

老板应该不断强调这一点,直到大家养成习惯。

1.3 要有验收工具

对技术研发来说,验收至关重要。对远程开发岗来说,自动化测试更显得重要。一方面,自动化测试可以节省大量时间,让开发人员知道自己产品的质量,并及时修改;另一方面,自动化测试可以避免 QA 和开发人员之间的矛盾,提升大家的工作效率。

测试工具推荐我厂的 Navlang 工具链。自动化工具选项比较多。

1.4 加强工具建设和流程建设

很多人不适合远程工作,很多人没有接受过远程工作的训练。招聘远程岗位,招聘成本很高,淘汰率也很高。所以与其寄望于招到合适的人才,不如加强工具建设和流程建设,提升团队管理能力,让更多人适配远程工作。

1.5 99% 想找远程工作的人,都不适合远程工作

很多人都想找远程工作,多半是因为他们对远程工作抱有不切实际的幻想。这点我深有体会。我当年也以为,远程工作,拿着现在的高工资,想在哪儿工作就在哪儿工作,只要按自己的想法完成工作,其它时间自由支配,潜水滑雪,多安逸。

实际上,远程工作会面临很多问题,比如电脑设备、网络情况,甚至办公桌椅都会成为问题。在人均颈肩腰腿痛的今天,随处工作基本上是一种奢望。

再加上工资降低,结果考核带来的工作压力,很多人可能会发现,远程工作并不如想象中美好。那么他能否应对接下来的工作,就要画一个问号。

更别提还有很多人远程之后根本无法保证工作效率。

2. to 员工

2.1 要有主动性

远程不同于集中办公,每个人都要有主动性,主动管理自己,也主动管理别人。

比如一个功能,前后端分离,我是前端,我把自己的做完了,就要去催着后端做,直到最终验收。他也一样,遇到前端 bug,他也要催着我改。绝不能被动等待对方完成。

集中办公的时候,可能有项目经理、可能有需求人、可能有领导盯着,上厕所吃午饭时随口一句就足够大家紧张起来。远程工作,必须大家互相督促才行。

2.2 远程工作并不美好

正如水往低处流,因为有引力有势能。工作也一样,如果一个工作非常爽,就会涌入一大堆竞争者,通过内卷把它的爽度抹平,直到这份工作与其它工作相比乏善可陈。

所以这世上没有很爽的工作。如果有,要么工作有问题,要么你有问题。

分类
前端

使用 SVG 制作扇形

有时候我们需要制作扇形,比如图形化数据生成饼图的时候。使用 HTML + CSS 做不到,必须借助 SVG 帮助。经过一些摸索,大概方式如下:

0. 创建 SVG

我们需要一个 SVG,然后在里面画一个园:

<svg xmlns="http://www.w3.org/2000/svg" height="600" width="600" viewBox="0 0 20 20">
  <circle r="5" cx="10" cy="10" />
</svg>

这里,我创建了一个 SVG,并且以 10,10 位圆心,画了一个半径为 5 的圆。SVG 的视窗只需要显示这个圆,所以是 0 0 20 20 的正方形。widthheight 用来定义网页中 SVG 的尺寸,SVG 是矢量图形,可以实现内容的无损缩放,所以即使显示尺寸比图形尺寸大很多,也不用担心出现锯齿。

1. 用边框画圆形

接下来,我们用给圆加边框的方式来做圆形。

<circle
  r="5"
  cx="10"
  cy="10"
  fill="transparent"
  stroke="tomato"
  stroke-linecap="butt"
  stroke-width="10"
></circle>

首先,我们用 fill="transparent" 清理掉圆形内部的颜色,然后用 stroke="tomato" 给边框加上橙色。接下来,我们通过 stroke-width="10" 设置边框宽度为 10,这也是矩形半径。

此时,屏幕上会出现一个橙色的正圆。

2. 画扇形

画扇形的方式有很多,比如画两条半径然后画弧形再填充颜色。但是利用边框画扇形最简单。

用边框画扇形说白了,其实是结合圆环和虚线,需要有扇形的地方,就填充颜色;不需要扇形的地方,就用虚线的空白。这里要用到 stroke-dasharray 属性,它的规则很简单,奇数为实偶数为虚,所以我们只要计算扇形所需的弧形长度,然后剩下的填充周长即可。

在我们这里,就是 stroke-dasharray=”calc(10 * 3.1415926 * 1/6) 31.415926",即取绘制一个 1/6 大小的扇形。

3. 修改位置

修改位置需要使用 stroke-dashoffset 属性,它会把图形从原来的位置移动若干距离,正的就往起点移动,负的就往终点移动。

在我们这里,就是 stroke-dashoffset="calc(-10 * 3.1415926 * 1/6)",将第二个扇形移到第一个扇形的旁边。

4. 其它+已知问题+扩展阅读

最终效果:https://codepen.io/meathill/pen/yLMQqBQ?editors=1000

这些属性,也可以使用 CSS 样式替换,效果一样。

Safari 问题比较多,首先半圆就不是半圆,其次偏移也不对,不知道是否只支持 CSS。

分类
nodejs

node.js 里使用 fifo

0. 需求

前两天 Showman 遇到一个需求:

  1. 我们需要在服务器端录制视频
  2. 录制视频的过程主要由 node.js 控制,借助 puppeteer 操作浏览器
  3. 但是也会需要执行一些 shell 命令,此时为安全考虑,我们会启动一个封闭的临时环境给用户执行
  4. 这些封闭环境是用户进程间共用的,不会随时启动随时销毁
  5. 所以 node.js 就需要在其它环境里执行一些操作,返回内容,等待执行完毕后再继续下面的

于是我的同事就让我用 fifo。

1. 什么是 fifo

我以前没有用过 fifo,所以搜索了一下。

FIFO 特殊文件(同具名管道)与管道类似,只是可以用访问文件系统的方式来访问它。它可以被多个进程同时打开和读写。当进程通过 FIFO 交换数据时,内核将直接在内部交换数据,而不会写入到文件系统中。因此,FIFO 特殊文件在文件系统中没有内容;文件系统的入口(即文件)只是作为引用方式,让各进程能够使用文件名来访问管道。

原文:https://man7.org/linux/man-pages/man7/fifo.7.html

管道大家应该都知道,把 A 进程的输出直接输入到 B 进程里,加快处理速度。fifo 与管道的差别就是 fifo 可以通过文件路径直接访问,用起来更简单。

2. 在命令行里使用 fifo

创建 fifo,使用 mkfifo 命令:

mkfifo xxx.fifo

写入内容到 fifo:

echo "something" > xxx.fifo

读取 fifo:

cat xxx.fifo

因为 fifo 是管道,内容直接走内核,所以实际上硬盘上不会存储任何内容。如果我们在写入之后再 cat fifo,就不会得到任何内容。

3. 在 node.js 里使用 fifo

在 node.js 里使用 fifo 需要用 fs.opennet.Socket。因为我需要在执行完毕后继续下一步,所以进行了 Promise 封装:

try {
  // 为避免执行时间过长导致进程超时,不断输出些内容
  const interval = setInterval(() => {
    log('termlang is processing...');
  }, 3E4);
  await new Promise((resolve, reject) => {
    // 打开名为 $basename-$lineno.sp.fifo 的管道
    open('./$basename-$lineno.sp.fifo', constants.O_RDONLY | constants.O_NONBLOCK, (err, fd) => {
      if (err) {
        clearInterval(interval);
        reject(err);
      }
      const pipe = new Socket({fd});
      pipe.on('data', data => {
        data = data.toString();
        // 以输出内容包括 finished 或 errored 为结束标记
        if (/(finished|errored)/.test(data)) {
          resolve(data);
        }
      });
    });
  });
  clearInterval(interval);
} catch (err) {
  log(err);
}

4. 总结

作为半路出家的前端,我对系统、对 Linux 一直缺乏了解。所以类似管道这种东西,我一直也不太熟悉,这次算学会了一个新技能,记录分享一下。

分类
js

聊聊 NPM 里的版本号和依赖

好像一直没有写过版本号和依赖相关的内容,偶尔会有同学问,所以写一篇总结一下。

0. Semver

我们目前使用的版本规范通常基于 Semver,语义化版本。官方网站:语义化版本 2.0.0 | Semantic Versioning (semver.org)。按照其规则,版本号的结构应该是:

主(大)版本号.次(小)版本号.修正(补丁版本)号

其中,

  • 主版本号一般包含架构和 API 的变化。如果 API 出现重大变化,使得依赖它的软件要重构,那么就要体现在大版本号里。不过现在的代码仓库很少有破坏式重构,API 一般能够在至少 2、3 个大版本里保持稳定。所以主版本号变化一般出现在大型重构时,仓库内部的代码架构和组织形式出现重大变化,或者基于不同系统,就需要升级主版本了。
  • 次版本号一般表达功能变化。架构没有变化,原有 API 也基本维持不变,只是新增了功能。这个时候就会上调次版本号。
  • 修订号一般表示修复 bug。

0.1 年代版本号

另一种流行的版本号规范是年代版本号,比如 Ubuntu,每年会发布两个版本,目前是 21.04,10月份会发布 21.10。偶数年的 .04 版本会最终成为 LTS,长期维护版本;奇数年的版本和 .10 版本则只维护半年,里面包含各种最新的软件组件,方便喜欢尝新的用户。

前端常见的软件和库,包括 node.js、Angular、Electron 也用这种方式确定版本号。

1. 依赖中指定版本号

我们在项目中可能会使用大量开源代码,这些开源代码通常都会使用包管理工具(比如 NPM,node package manager)安装和管理。

在 package.json 里,我们可以使用几个运算符告诉 NPM 我们希望怎么使用这些依赖:

  • 不写,repo: '1.0.0'。要求使用 1.0.0 版本的 repo,必须完全一致。
  • ~repo: ~1.0.0。要求大版本为 1,小版本为 0,修订版本不限制,比 0 高就可以。
  • ^repo: ^1.0.0。要求大版本为 1,小版本高于 0 就可以。

一般来说,使用 npm i repo 安装的依赖,默认规则是 ^;使用 npm i repo@version 安装的依赖,默认规则是写死。

2. 升级依赖

这个世界上不存在没有 Bug 的代码,也没有功能完善的代码。使用开源仓库,我们就要考虑升级依赖。一方面可以使用新功能,一方面可以解决 bug。

通常来说,直接使用 npm update 就能升级项目依赖,NPM 会按照(1)里设定的规则更新依赖。

3. 升级依赖的大版本

只使用 npm update 无法升级大版本。原因如上文所述,大版本可能包含破坏性的 API 更新,很容易导致 dev/build 失败,作为工具无法妥善处理,必须交给开发者手动完成。

很多同学因此不愿意升级大版本。但我建议大家还是要找机会做升级,尤其工具链,比如 webpack、babel。这些工具很多时候有时效性,长期不升级会导致各种问题。而且,升级工具链本身这也是我们偿还技术债务的好机会。

其实升级工具链的大版本并不复杂,大多数半天就搞定了;如果没有用到偏门功能,甚至可能直接升级就能跑。——通常来说,开源软件的作者面对使用频率高的功能,会比较保守;没人用的功能改动就会大刀阔斧一些。

升级依赖需要指定大版本,比如从 webpack 4 升级到 webpack 5,可以使用 npm i webpack@5,这样会安装大版本是 v5 的最新版本。这里有个小建议,公司的生产级别的项目,最好不要着急升级,等到 X.2 X.3 这样基本稳定的次版本发布后再升级,可以避免踩很多坑。

一般来说,开源仓库的官方也会提供迁移指南,比如 webpack v4 to v5。只要你有 v4 的配置经验,照着指南操作,大多数时候都能顺利完成。

4. 解决 npm audit 问题

开源仓库的安全问题日趋严重,GitHub 和 NPM 都会帮我们检查依赖,并且根据已知的安全问题列表发出警告。所以在安装依赖时,我们经常能看到类似下面这种警告信息:

found 5 moderate severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

这个时候,我们应该执行 npm audit 查看所有的审计结果,可能得到如下的报告:

┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Regular expression denial of service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ glob-parent                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=5.1.2                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ @vue/cli-service [dev]                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ @vue/cli-service > webpack-dev-server > chokidar >           │
│               │ glob-parent                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/1751                            │
└───────────────┴──────────────────────────────────────────────────────────────┘

这个报告说明有问题的包是 glob-parent,它由 webpack-dev-server 引入,又因为 @vue/cli-service 而最终成为项目的依赖。很明显,它是 @vue/cli 的组成部分,是前端工具链的一环。那么通常来说,它的危害层级很低,多半不会影响到项目整体安全性。

如果是 node.js 项目,就要小心了,服务器和后端都是安全重灾区,后果可能会很严重。这个时候,你可以往上翻,找到这些报告的最前面,如果可以修复,NPM 会告诉你应该运行什么命令更新问题依赖。如果不能修复,就要自己想办法了。

比如,你可以移除出问题的依赖,不过多半不可行。或者,我比较常用的方案是,在 GitHub 上找到依赖仓库,自己 fork 一份,然后升级其中的依赖,然后发布一个我个人的版本,接下来就用我自己的版本。等到官方修复后,再用回官方版本。

5. 总结

最后按惯例总结一下。依赖是我们软件产品的重要组成部分,它们的版本事关重大,必须给予足够的关注。至少,每个月要检查一次依赖的安全审计问题,如有需要,就升级依赖。

我们自己写代码的时候,也要遵守 Semver 的规定,适时上调版本号,让版本号能表示代码的发展情况。