大家好,我是 ConardLi,不知不觉中,2021 年已经接近尾声了,不知道在 2021 这一年,你收获了什么?又失去了什么呢?
又到了开始做年终总结的时候了,今天,我来给 JavaScript 做个年终总结,大家来跟我一起回顾一下,这魔幻的一年中,JavaScript 发生了哪些大事件。

Snowpack 是一个 JavaScript 构建工具,它利用了浏览器对 ESM 的支持,让我们可以构建单个文件并将其发送到浏览器中。每一个被构建的文件都会被缓存,在我们每修改一个文件时,只有这一个文件会被 Snowpack 重新构建。
Snowpack 3.0 于 2021 年 1 月 6 日发布,这是它迄今以来最大的一次版本更新,包括很多非常重要的新特性,比如
experiments.source:按需加载 npm 导入的新方法,可以完全跳过前端的 npm install 步骤。experiments.optimize:内置打包、预加载和资产最小化能力。experiments.routes:用于 HTML 回退和 API 代理的高级配置。import 'snowpack':用于 Snowpack 集成的全新 JavaScript API。
React 的创始人 jordwalke 离开了 Facebook,去追逐新的梦想,在 Facebook 的十年中,他曾创建了 React 和 ReasonML。

npm 7.0 在 2020 年就发布了,直到2021年2月,才打上 latest 标签,这意味着大家可以在正式环境中使用了,此次更新也带来了非常多的变化
46%(npm6 有 123 个依赖 npm7 只有67个),提升了 17% 的代码覆盖率,在各种基准测试中有显著的性能改进。peerDependencies:在 npm7 之前,开发人员需要自己管理和安装 peerDependenciesyarn.lock 支持:npm7 (package-lock v2) 可以使用 yarn.lock 来记录当前状态下实际安装的各个 npm package 的具体来源和版本号,还会保持更新。workspace:支持从单个顶级软件包中管理多个子包。
Vite 1.0 虽然之前进入了 RC 阶段,但在发布之前,Vite 团队决定进行一次彻底的重构来解决一些设计缺陷,所以 Vite 2.0 其实是 Vite 的第一个稳定版本,带来了大量的改进:
Vite 提供官方的 Vue、React、Preact、Lit Element 项目模版,而 Svelte 社区也在开发 Vite 整合方案。Rollup 插件 API 的设计,可以在使用 Rollup 插件钩子之外使用一些额外的 Vite 特有的 API 来处理一些打包中不存在的需求。esbuild 的依赖预打包:使用 esbuild 来减少模块/请求数量、支持 CommonJS 依赖。尤雨溪年初曾在一个回答里预言 2021 会有很多人从 Webpack 转向 vite,如今来看,预言实现:

如今的 Vite ,已经有了非常完善的生态:


为了更快地向用户提供新功能和错误修复,Chrome 加快了其发布周期。
为了配合 Chrome 的新发布节奏,V8 将开始每 4 周(之前是 6 周)标记一个主要发布分支。
距离2020年5月发布的 jQuery 3.5.1 版本,jQuery 在2021年3月终于又发布了 3.6.0 版本,这个版本并没有新功能,也不包括安全修复、主要是对 JSONP、Ajax 等 API 的问题修复。
jQuery 的一大优势是升级不会带来任何问题(因为升级主要是在修复问题),评论区还是有很多坚定的支持者:


其中包括一些我比较感兴趣的新特性:
JavaScript 语言启用了下划线作为数字文字中的分隔符,例如:1_000_000_000_000。Promise.any:Promise.any 方法和 Promise.race 类似,只要给定的数组中的有一个 promise 成功,就采用第一个 promise 的值作为它的返回值,但与 Promise.race 的不同之处在于它会等到所有 promise 都失败之后才返回失败的值。const promises = [
fetch('/endpoint-a').then(() => 'a'),
fetch('/endpoint-b').then(() => 'b'),
fetch('/endpoint-c').then(() => 'c'),
];
try {
const first = await Promise.any(promises);
// 任何一个 Promise 为 fulfilled 状态
console.log(first);
// → 'b'
} catch (error) {
// 所有 Promise 都被 rejected 了
console.assert(error instanceof AggregateError);
// reject 结果数组
console.log(error.errors);
}
WeakMap 和 WeakSet 是JS中创建弱引用对象的唯一方法,WeakRef 是一个更高级的 API,可以用来指定目标对象不脱离垃圾收集保留它的对象。如果未通过垃圾回收回收目标对象,则 WeakRefs 可以取消引用以允许访问目标对象。另外还新增了 FinalizationRegistry 对象,可以在垃圾回收对象时请求回调。const ref = new WeakRef(targetObject)
const obj = ref.deref()
const registry = new FinalizationRegistry([callback])
registry.register(target, heldValue, [unregisterToken])
String.prototype.replaceAll:提供了一种简便的方式来替换子字符串的所有匹配,而不再需要创建全局 RegExp 。看下面的例子,以前你要把 queryString 中所有的 + 替换掉,需要创建一个全局的正则:
const queryString = 'q=query+string+parameters';
queryString.replace(/\+/g, ' ');
现在你只需要使用 replaceAll 方法:
queryString.replaceAll('+', ' ');
&&=,||=,??=):是一种新的复合赋值运算符,他可以把逻辑操作 &&,||或?? 与赋操作结合成一条命令。x &&= y;
// 等同于 x && (x = y)
x ||= y;
// 等同于 x || (x = y)
x ??= y;
// 等同于 x ?? (x = y)
Node.js 在它的前 10 年非常成功,这个项目正在努力使下一个 10 年变得更好,Node.js 官方发布了对 Node.js 未来十年的展望,并且启动了 Next-10 工作:

V8 9.0 是 V8 的一个主要版本,和 Chrome 90 Stable 一起发布,包括下面这些主要亮点:
v9.0 开始,开发者可以获取正则表达式匹配中匹配的捕获组的开始和结束位置的数组。当正则表达式带有 /d 标志时,这个数组可以通过匹配对象上的 .indices 属性获得。V8 的内联缓存系统和 TurboFan 中优化的代码生成,对 super 属性(例如 super.x )的访问进行了优化。
JS-to-Wasm 调用。for ( async of 写法。详情可以看文章:V8 9.0 版本都有哪些新东西?
Node.js 作者 Ryan Dahl 在博客中阐述了对 Deno 的未来愿景,以及 Deno 对于 Web 开发的意义。他们相信 JavaScript 将在未来很长一段时间内存在于互联网,并且会是速度最快、最受欢迎且唯一具有工业标准化流程的语言。

他还提到了曾创建的 Node.js 项目,并表示它虽然取得了一定成功,但是服务器端 JavaScript 发展得如此的支离破碎,基础设施也十分不完善,甚至未能跟上浏览器平台的发展,所以服务器端 JavaScript 一直停滞不前。
为了积极推行这些想法,Ryan Dahl 和 Bert Belder 成立了 Deno 公司,并筹集到 490 万美元的种子资金。他们会先用这笔投资组建专职的工程师团队,以改进 Deno。
该提案是阿里巴巴前端标准化小组与淘系技术部门近期在 TC39 技术委员会上提出的《Error Cause》,将开始在 JavaScript 引擎中开始实现,并在浏览器、Node.js 实验性实施。
async function doJob() {
const rawResource = await fetch('//domain/resource-a')
.catch(err => {
// How to wrap the error properly?
// 1. throw new Error('Download raw resource failed: ' + err.message);
// 2. const wrapErr = new Error('Download raw resource failed');
// wrapErr.cause = err;
// throw wrapErr;
// 3. class CustomError extends Error {
// constructor(msg, cause) {
// super(msg);
// this.cause = cause;
// }
// }
// throw new CustomError('Download raw resource failed', err);
})
const jobResult = doComputationalHeavyJob(rawResource);
await fetch('//domain/upload', { method: 'POST', body: jobResult });
}
await doJob(); // => TypeError: Failed to fetch
Error Cause 2021.4.13 进入 Stage 3,也是我国首个进入在 ECMA 进入 Stage 3 的 JavaScript 语言提案。
2021.10.26 该提案已进入
Stage 4
Node.js 16 替代 Node.js 15 成为当前的主要发布版本,同时 Node.js 10 在这个月底止维护。

带来以下主要更新:
Timers Promises API:提供了另一组返回 Promise 对象的定时器函数,不再需要使用 util.promisify()。AbortController:基于 AbortController Web API 的稳定实现Web Crypto API 试验性实现Stable Source Maps v3Node.js v16 中的 npm 版本升至 v7.10.0V8 更新至 V8 9.0React 团队在5月份宣布了 React 18 的发布计划,并且发布了 React 18 的 alpha 版本(在11月份进入 beta 版本,后面就不写了)。这个版本主要是增强了 React 应用的 并发渲染 能力。

你可以在 React 18 中尝试体验以下几个新特性:
ReactDOM.createRoot() API(替换 ReactDOM.render())startTransition API(主要用于非紧急状态更新)React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)React 几个主要阶段的重点工作内容:React 框架运行时优化方案的演进在以前,request 是在 Node.js 中发送一个 HTTP 请求的首要选择,但是这个包在 2020 年 2 月 11 日已经标记为弃用。
现在, Node.js 官方推荐 Undici4 作为在 Node.js 中发送 HTTP 请求的推荐选择,它更快速、可靠且符合规范,下面是一个小 Demo:
import { request } from 'undici'
const {
statusCode,
headers,
trailers,
body
} = await request('http://localhost:3000/code秘密花园')
console.log('response received', statusCode)
console.log('headers', headers)
for await (const data of body) {
console.log('data', data)
}
console.log('trailers', trailers)
Undici4 使用 WASM 构建 llhttp,性能得到飞速提升。

Node-RED 是一个基于 Node.js 的低代码编程工具,可以用新颖有趣的方式将硬件设备,API和在线服务连接在一起。
它提供了一个基于浏览器的编辑器,使得我们可以轻松地使用编辑面板中的各种节点将流连接在一起,只需单击即可将其部署到其运行时。

现在,Node-RED 发布了 2.0 版本,这需要 Node.js 12.17.x 或更高版本,另外也带来了非常多的新特性。

维基媒体基金会 (Wikimedia Foundation) 宣布正式采用 Vue.js 作为未来的 JavaScript 框架 —— 用于维基百科的底层引擎 MediaWiki。
8 月 5 日,Vue.js 作者尤雨溪在博客上宣布 Vue.js 3.2 版本正式发布。

以下为更新的主要内容:
<script setup> 是一种编译时语法糖,能够极大改善在 SFC 中使用 Composition API 时的开发者体验。<style> v-bind 用于在 SFC <style> 标签中启用组件状态驱动的动态 CSS 值。<script setup>
import { ref } from 'vue'
const color = ref('red')
</script>
<template>
<button @click="color = color === 'red' ? 'green' : 'red'">
Color is: {{ color }}
</button>
</template>
<style scoped>
button {
color: v-bind(color);
}
</style>
Vue 3.2 引入了新的 defineCustomElement 方法,可以使用 Vue 组件 API 轻松创建原生自定义元素:import { defineCustomElement } from 'vue'
const MyVueElement = defineCustomElement({
})
customElements.define('my-vue-element', MyVueElement)
ref 实现(读取速度提高约 260%,写入速度提高约 50%)40%17%VNode 的速度提高约 200%hoisting早在 2020 年 8 月份,TypeScript 团队就对 TypeScript Web 现有整个构架进行了重新设计。其目的是记录 TypeScript 提供新的基础,重新组织其信息体系结构,通过一个内聚的设计将其包装在一起,历时一年,新官网上线。

Corepack 是一个处于实验阶段的工具,用于助你管理你本机 package manager 的版本。也就是用来管理「包管理工具(npm、yarn、pnpm、cnpm)」,即「包管理器的管理器」。

它为每个包管理工具都暴露了二进制代理,当 Corepack 被调用时,将读取当前项目配置的包管理工具,用户无需手动安装,最后运行它时则不需要用户额外操作。
React 以前一直被吐槽官方文档对新手不友好,而且旧文档大部分还是基于 class components 进行的讲解。

新的 React 官方文档改版耗时 1 年,在 10 月份已完成站点相关改版,部分文档已初步上线。
新文档的内容该动:
Hooks 完成文档站的技术上做了如下该动:
Gatsby 替换为了 Next.jstailwindFlow,全面 TypeScript 化jQuery Mobile 于 2010 年构思并发布,也就是 jQuery 推出三年后。当时,jQuery Mobile 宣布跨多个平台、浏览器和版本的兼容性,可谓是一个跨时代的框架。

就在 10月7号,jQuery 官方团队宣布了 jQuery Mobile 的完全弃用:

jQuery Mobile 弃用之后:
Mobile 1.4 与新的 jQuery Core 不兼容Github Issues 将被关闭,只能通过 security@jquery.com 上报严重的安全问题弃用 jQuery Mobile后,jQuery 官网推荐大家迁移至 jQuery UI,它将继续提供移动端的支持。
Parcel 是一个新型的 Web 应用打包器(bundler) ,与以往的开发人员使用的打包器有所不同。它利用多核处理提供极快的性能,并且你不需要进行任何配置。
10月13日,Parcel Team 发布了 Parcel v2 版本,延续了 Parcel 1 的零配置打包体验,并使其拥有了强大的拓展能力以适应任何规模和复杂度的项目。

Parcel 提供了完整的拓展能力,允许 Parcel 从小规模项目拓展到具有复杂构建要求的大规模生产环境的应用程序Tree Shaking:包括 ES modules、CommonJS、dynamic import 和 CSS modules 的支持Rust 写的新的 JavaScript 编译器和新的多任务并行架构,能够利用所有的 CPU 内核并行执行在 Node.js16 发布的6个月后,Node.js v17.0.0 发布了。

下面是本次更新的主要内容:
readline Promise API:你现在可以用下面的方式调用 readline:import * as readline from 'node:readline/promises';
import { stdin as input, stdout as output } from 'process';
const rl = readline.createInterface({ input, output });
const answer = await rl.question('What do you think of Node.js? ');
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();
Node.js 版本信息,更方便调试问题:file:///home/ConardLi/dev/demo/main.mjs:1
throw new Error("报错了...");
^
Error: Uncaught exception
at file:///home/ConardLi/dev/demo/main.mjs:1:7
at ModuleJob.run (node:internal/modules/esm/module_job:185:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
at async loadESM (node:internal/process/esm_loader:88:5)
at async handleMainPromise (node:internal/modules/run_main:65:12)
Node.js v17.0.0
OpenSSL 3.0:特别是提供 QUIC 支持的 quictls/opensslJavaScript V8 升级到 v9.510 月 27 日,Next.js 团队官宣了 12 版本发布。

就像在 Next.js Conf 上宣布的那样,Next.js 12 是 Next.js 有史以来最大的版本,更新概览如下:
Rust 编译器:刷新速度提升 3 倍、构建速度提升约 5 倍的Middleware (beta):通过配置代码在 Next.js 中实现完全的灵活性React 18 支持:支持 Suspense、React Server Components 等新特性<Image />AVIF 支持:选择缩小 20% 的图像Bot-aware ISR Fallback:为网络爬虫优化 SEOURL Imports (alpha):支持从任何 URL 导入包(比如CDN),无需通过npm安装11 月 4 日,Angular 团队宣布Angular 13 发布。

此版本核心更新包括不再支持旧编译和渲染引擎 View Engine,全面支持新编译和渲染引擎 lvy,以及不再支持 IE11,除此之外还有包括对 APF 以及 Angular CLI 等方面的更新和修改。

TypeScript 4.5 于 11.17 发布正式版,支持 ECMAScript Module、从 node_modules 加载 lib、新的内置工具类型 Awaited、通过 Node 的 realpathSync.native 实现更快的加载速度等等。
Remix 是一个由 React Router 开发团队所开发的基于 React、 TypeScript 和 Node 的全栈框架,以解决开发者在用 React 开发时面临的一些棘手问题。

Remix 宣布关闭付费订阅模式,正式开源,绝对可以算是 Next.js 的强劲对手。
去年 10 月,我们推出了 "支持者预览版",我们得到的支持让我们感到非常激动。虽然我们可以从 Remix 的付费订阅中获得正常的开发者工资,但我们想更进一步。我们想让所有人都能使用 Remix。我们相信,将 Remix 以开源的方式发布将推动项目的创新,并使其他框架也能从我们取得的进展中受益。我们急于向他人学习,并回馈给他人。— Remix 联合创始人 Michael Jackson 和 Ryan Florence
Pinia 是 Vue.js 的轻量级状态管理库,最近很受欢迎。它的成功可以归功于其管理存储数据的独特功能(可扩展性、存储模块组织、状态变化分组、多存储创建等)。

尤雨溪 11.24 在 Twitter 上宣布:Pinia 正式成为 vuejs 官方的状态库,意味着 Pinia 就是 Vuex 5 。

12 月 4 日,是编程语言 JavaScript 面世 26 年的纪念日。
当天,Node.js 官方专门发文庆祝:“Happy 26th Birthday,JavaScript”。


Deno 将在 TC39 工作组中与其他 ECMA 成员和更广泛的 JS 社区合作,讨论 JavaScript 的下一次迭代,推动语言的功能和改进,使所有人受益,尤其是服务器端 JavaScript 的开发者用户。
Create React App 5.0.0 发布,这是一个主要版本。

包括以下支持:
webpack 5Jest 27ESLint 8PostCSS 8Fast Refresh 改进和 bug 修复Tailwind CSSNode 10 和 12不知道,上面这些事件和更新,你之前了解过多少呢?
另外,这一年 JavaScript 的变化,你怎么看?