《一定要看到最后》
大家好,我是 ConardLi
去年我总结了 2021 年 JavaScript 大事记 之后,最近好多小伙伴催更我的 2022
年总结,这就来了。
今年的总结不再局限于 JavaScript
生态,其中也包括了 Web
、网络等前端需要关注的领域,所以我将其更名为 《2022 年前端大事记》。
当然每个人关注的重点可能不一样,如果你有需要补充的点,欢迎在评论区和我留言~
私有网络请求指的是目标服务器的 IP
地址比请求发起者获取的 IP 地址更私密的请求。例如,从公共网站 (https://www.douyin.com
) 到内网网站 (http://argus.bytedance.net
) 的请求,或从内网网站到 localhost
的请求。
据 Chrome
统计,有数十万人遭受了针对私有网络的攻击,简单说,就是你打开一个公共的网站,这个网站里会去请求你内网里的地址,然后窃取信息。基于此类问题,Chrome
提出了私有网络控制策略,此策略会限制网站向私有网络上的服务器发送请求的能力。
你必须要部署下面两个 Header,否则所有私有网络访问都会失败:
Request
:Access-Control-Request-Private-Network: trueResonse
:Access-Control-Allow-Private-Network: true了解更多:
Vue 3
在 2022
年 2 月 7 日 成为新的默认版本!
除了 Vue
核心库以外,还几乎改进了框架的每个方面。
Vite
的极速构建工具链<script setup>
带来的开发体验更丝滑的组合式 API
语法Volar
提供的单文件组件 TypeScript IDE
支持vue-tsc
提供的针对单文件组件的命令行类型检查和生成Pinia
提供的更简洁的状态管理Vue 2/Vue 3
,并且提供一个插件系统来允许社区库自行扩展开 - 发者工具面板。了解更多:https://zhuanlan.zhihu.com/p/460055155
自 Chrome 101
版本开始,document.domain
将变为可读属性。
当两个页面的 document.domain
都设置为二级域名的时候,浏览器就会将两个来源视为同源,利用这个方法我们可以绕过浏览器的同源策略。
也就是意味着上述这种跨域的方式被禁用了,后续可以替换为 postMessage
的跨域方案。
了解更多:
Fetch API
是当前最流行的跨平台 HTTP Client API
。
在最新的 Node.js v17.5
版本中,增加了对 Fetch API
的支持,后续无需再借助 axios、needle、node-fetch、request
等第三方请求库了!
这并不是简单的支持了一个新的原生 HTTP
请求库那么简单,这意味着很多之前在 Web
中用到 Fetch
的 NPM
包也可以在 Node.js
里以同样的方式工作了,这些包同样可以实现跨平台兼容了~
了解更多:
为了减轻 User-Agent
的身份标识作用, Chrome
正在逐步减少 User-Agent
中的信息。
以下几部分信息都会逐步缩减:
浏览器会推荐大家使用新的 User-Agent Client
,里面只会包括下面几部分信息:
Sec-CH-UA
: 浏览器名称和主要/重要版本Sec-CH-UA-Mobile
: 是否为移动设备Sec-CH-UA-Platform
: 操作系统名称例如,Chrome/99.0.2345.12
这样的版本号将会被简化为 Chrome/99.0.0.0
,这大大的减轻了 UA 对用户的身份标识作用。
具体减少计划:
Chrome 92
:使用 navigator.userAgent 、navigator.appVersion 和 navigator.platform 会在控制台打印警告。
Chrome 95
:支持为的网站注册原始试用,开始对减少的 UA 字符串进行测试和反馈。
Chrome 101
:User-Agent 将会减少 Chrome MINOR.BUILD.PATCH 版本信息。推荐迁移到新的 User-Agent Client。
Chrome 107
:PC端的 User-Agent 字符串和 JS API(navigator.userAgent 、navigator.appVersion 、navigator.platform)将会直接缩减。
Chrome 110
:移动端的的 User-Agent 字符串和 JS API 将会缩减。
Chrome 113
:全面缩减。
了解更多:
JavaScript
即将推出两个新的数据类型:Record
和 Tuple
,该提案目前已经到达 Stage: 2
。
Record
和 Tuple
在用法上和对象、数据保持一致只不过他们是只读的:
// Record, 一个非常不可变的类对象结构
const myRecord = #{
name: 'ConardLi',
age: 23
}
myRecord.name = 'xxx'; // TypeError "Cannot assign to read only property 'name' of object '[object Object]'"
// Tuple, 一个非常不可变的类数组结构
const myTuple = #['1', '2', '3']
myTuple[0] = '4' // TypeError "Cannot assign to read only property '0' of object '[object Tuple]'"
另外还有一个很重要的点,当我们去比较 Record
和 Tuple
的值时,只会对比它们的值,而不再对比引用。
console.log(#{ a: 1, b: 2 } === #{ b: 2, a: 1 });
// true
了解更多:https://github.com/tc39/proposal-record-tuple
浏览器制造商 Apple、Google、Microsoft
和 Mozilla
,以及软件公司 Bocoup
和 Igalia
正在合力制定一项名为 Interop 2022
的 Web
兼容性规范,以使 Web
技术和代码在不同的设备和浏览器中有统一的渲染效果(利好前端开发)。
这是有史以来第一次,所有市场上主要的浏览器供应商和利益相关者齐心协力地解决浏览器兼容性问题。此前,互相为竞争关系的浏览器厂商常常在 Web
技术的兼容性上出现分歧,尤其是 IE
还活着的时候,前端一个页面三套代码的情况十分常见。
想要跟进规范的整体进度,可以查看 Interop 2022 dashboard
了解更多:https://web.dev/interop-2022/
在过去的 JavaScript
调查报告中,静态类型一直是 JavaScript
开发者强烈要求的一个功能。
微软 TypeScript
团队提出了一项新的提案,在提案中希望可以为 JavaScript
带来可选的类型注释语法。提案的目的是让开发者能够直接运行用 TypeScript、Flow
或其他静态类型库编写的程序,而不需要再编译一次。
如果提案能够顺利实施,将是 JavaScript
语法的一个重大变革,目前提案已经到达 Stage: 1
阶段。
提案地址:https://github.com/tc39/proposal-type-annotations
vue-cli
的依赖项 node-ipc
包的作者 RIAEvangelist
是个反战人士,他特意新建了一个 peacenotwar
仓库来宣传他的反战理念。
更过分的是,作者不只添加了反战标语,还在 node-ipc 10.1.1-10.1.2
版本中添加了恶意 JS
文件删除俄罗斯和白俄罗斯用户文件:
攻击源码在仓库中仍可找到。源码经过压缩,简单地将一些关键字符串进行了 base64
编码。其行为是利用第三方服务探测用户 IP
,针对俄罗斯和白俄罗斯 IP
,会尝试覆盖当前目录、父目录和根目录的所有文件,把所有内容替换成 ❤。
node-ipc
在 npm
上具有周百万次的下载量,这是又一次对脆弱的 npm
生态进行的一次沉痛打击。
了解更多:百万周下载量的 npm 包以反战为名进行供应链投毒!
Chrome
将在 100 到 103 版本启动 Cookie CHIPS
试用版本!
CHIPS
指的是具有独立分区状态的 Cookie
,它允许开发者将 Cookie 选择到“分区”存储中,每个顶级站点都有单独的 Cookie jar``。CHIPS
引入了一个新的 Cookie
属性:Partitioned
,它可以让顶级上下文(顶级站点或第 First-Party Sets
)决定哪些 Cookie
进行分区。
例如:在站点 A 中通过 iframe
嵌入了一个站点 C,正常情况下如果三方 Cookie
被禁用后,C 是无法在 A 站点访问到它的 Cookie
的。如果 C 在它的 Cookie
上指定了 Partitioned
属性,这个 Cookie
将保存在一个特殊的分区 jar 中。它只会在站点 A 中通过 iframe
嵌入站点 C 时才会生效,浏览器会判定只会在顶级站点为 A 时才发送该 Cookie
。当用户访问一个新站点时,例如站点 B,如果也它通过 iframe
嵌入了站点 C,这时在站点 B 下的站点 C 是无法访问到之前在 A 下面设置的那个 Cookie
的。
了解更多:谁能帮我们顺利过渡到没有三方 Cookie 的未来?
2022年3月29号,React18
正式版发布。
ReactDOM.createRoot() API
(替换 ReactDOM.render()
)startTransition API
(用于非紧急状态更新)React.lazy
的 全新 SSR
架构(支持 <Suspense>
组件)了解更多:https://reactjs.org/blog/2022/03/29/react-v18.html
版本号分析可能出现的问题:Chrome 版本即将突破100 ?这个问题不容忽视!
Google
发布了 Web 100
个令人激动的瞬间 ( https://developer.chrome.com/100/ ),同时也在推特上发起了 #100CoolWebMoments
活动。
Chrome 100
将是最后一个默认支持未删减的 User-Agent
字符串的版本。Chrome
推荐大家用新的 User-Agent Client Hints API
替换 User-Agent
字符串。
了解更多:Chrome 100:有风险也有机遇!
ShadowRealm API
是一个新的 JavaScript
提案,目前已进入 statge3
。
它允许一个 JS
运行时创建多个高度隔离的 JS 运行环境(realm
),每个 realm
具有独立的全局对象和内建对象。
每个 ShadowRealm
实例都有自己独立的运行环境,它提供了两种方法让我们来执行运行环境中的代码:
.evaluate()
:同步执行代码字符串,类似 eval()
。.importValue()
:返回一个 Promise
对象,异步执行代码字符串。const sr = new ShadowRealm();
console.assert(
sr.evaluate(`'ab' + 'cd'`) === 'abcd'
);
了解更多:
stage3
Change Array by copy
提案,目前已经处于 stage3
阶段。
该提案为数组新增了四个非破坏性(不改变原数组)方法:
toSorted()
:.sort()
的非破坏性版本;toReversed()
:.reverse()
的非破坏性版本;with()
:对数组的某个元素赋值操作的非破坏性版本;toSpliced()
:.splice()
的非破坏性版本。了解更多:
Fenced frames
是一项 隐私沙盒 提案,它建议顶级站点应该对数据进行分区。
Chrome
从 97
版本开始对 Fenced frames
提供支持。
它是一个新的 HTML
标签,使用方式和 iframe
类似:
<fencedframe src="conardli.html"></fencedframe>
从对比上来看,iframe
还是要更灵活的,Fenced frames
是无法取代 iframe
的,但是当我们需要在同一页面上显示来自不同顶级分区的数据时,建议使用 Fenced frames 作为更私有的嵌入框架。
如果嵌入的网页是受信任的,还是用 iframe
即可。
了解更多:
Chrome 101
正式发布了 Priority Hints
,用于指定页面资源的加载优先级,即 fetchpriority
属性,帮助浏览器根据优先级优化加载顺序,从而优化页面加载体验。
当浏览器开始解析网页,并开始下载图片、Script
以及 CSS
等资源的时候,浏览器会为每个资源分配一个代表资源下载优先级的 fetch priority
标志,而默认的资源下载顺序就取决于这个优先级标志。
另外浏览器还给我们提供了一些诸如 async、defer、preload
等主动干预资源下载优先级的能力,但是有些场景还是满足不了:比如网页首屏有多张轮播图,我们只希望提高第一张图片下载的优先级;CSS、Font
资源默认有相同的优先级,但是并不是所有 CSS
和 Font
资源都是一样重要的。
这个时候, Priority Hints
就派上用场了。
了解更多:如何控制Web资源加载的优先级?
React
的核心开发者 Dan
为 React
增加了一项新的提案 useEvent
。
目的是为了解决下面这个场景:
function Chat() {
const [text, setText] = useState('');
// 🟡 每次 text 变化都会产生新的函数引用
const onClick = useCallback(() => {
sendMessage(text);
}, [text]);
return <SendButton onClick={onClick} />;
}
当我们使用 useCallback
包裹事件处理函数时,每次状态发生变化,都会产生一个新的引用。
function Chat() {
const [text, setText] = useState('');
// ✅ 永远是同一个函数引用
const onClick = useEvent(() => {
sendMessage(text);
});
return <SendButton onClick={onClick} />;
}
使用 useEvent
包裹事件处理函数,可以让我们每次都能获取到最新的状态,而且状态变更后不会产生新的函数引用。
提案地址:https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md
当然,这个提案最终还是在 9
月份夭折了,因为它最大的问题是它相当于引入了一个新的概念,会增加 Hooks
的使用理解成本,你可能会从要不要使用 useCallback
的选择中增加一个要不要使用 useEvent
...
所以 React
团队计划发布一个不同的、范围更小的 RFC 来取代这个 RFC。
为了实现更安全隐私的数据预取,Google
提出了一种新的数据预取方案:Private prefetch proxy
(私有预取代理),Google Search
已经实施了这项方案,导航的 LCP
预计有 20%-30%
的提升!
了解更多:Google 最新的性能优化方案,LCP 提升30%!
Safari 15.5、Chrome 102、Firefox Nightly
目前均对 HTML inert
属性提供了支持。
<div inert>
<label for="button2">codemmhy</label>
<button id="button2">I am inert</button>
</div>
inert
是一个全局的 HTML
属性,它可以告诉浏览器忽略元素的用户输入事件,包括焦点事件和来自辅助技术的其他事件。主要是下面两种用例:
DOM
树的一部分,但在屏幕外或隐藏;DOM
树的一部分,但应该是非交互的。inert
主要是为了提升网页的可访问性,比如对于视力障碍的人,他不是依靠视觉来感知网页内容,而是借助了一些其他的辅助技术,再之前就有可能会和我们隐藏掉的内容进行一些意外的交互。
而 inert
可以让我们能够从选项卡顺序和可访问性树中直接删除元素,这就会避免上面的问题!
了解更多:
在 PyCon US 2022
的主题演讲中,Anaconda
的 CEO
Peter Wang
公布了一个相当令人兴奋的项目 — PyScript
。
PyScript
是一个 JavaScript
框架,可以为开发者提供了在标准 HTML
中嵌入编写 Python
代码的能力、使用 Python
调用 JavaScript
函数库,以及创建 Python Web
应用。
这意味着后续我们可以在浏览器直接运行 Python
代码。
了解更多:https://pyscript.net/
IETF QUIC
和 HTTP
工作组成员 Robin Mark
在推特上宣布,历时5年,HTTP/3
终于被标准化为 RFC 9114
,这是 HTTP
超文本传输协议的第三个主要版本。
HTTP/3
采用了谷歌多年探索的基于 UDP
的 QUIC
协议,原名叫 HTTP-over-QUIC
,在 2018
年被 IETF
批准更名为 HTTP/3
。目前,Chrome、Firefox
等主流浏览器均表示支持 HTTP/3
IETF
标准地址:https://www.rfc-editor.org/rfc/rfc9114.html
在本届苹果全球开发者大会(WWDC 2022
) 中,苹果宣布了 Safari 16 beta
版本的发行, WebKit
带来了诸多新的 Web 能力,包括:
Web Inspector Extensions
macOS
的 Web
推送CSS
子网格布局Flexbox Inspector
了解更多:WWDC 2022:哪些是前端开发者要关注的信息?
27
岁的微软 IE
浏览器宣告退役。6月15日晚,微软 Edge
浏览器在官网宣布,微软正式结束对网页浏览软件 “Internet Explorer(IE)”
的支持,IE
浏览器正式退役了。发布于 1995
年夏天的 IE
,最终在 2022
年的夏天,结束了它的旅程。
了解更多:微软官方声明
Chrome 102
版本正式支持了 File Handling API
、Navigation API
File Handling API
可以让已安装的 PWA
向操作系统注册文件处理程序。注册后,用户就可以单击文件然后使用已安装的 PWA
打开它了。这非常适合与文件交互的 PWA
程序,例如图像编辑器、IDE、文本编辑器等。
想要让你的 PWA
支持文件处理功能,你需要更新一下 web app manifest
,添加一个 file_handlers
数组,其中包含有关你的 PWA 可以处理的文件类型的详细信息。你需要指定要打开的 URL、MIME
类型、文件类型的图标和启动类型。启动类型定义是否应在单个客户端或多个客户端中打开多个文件。
"file_handlers": [
{
"action": "/open-csv",
"accept": {"text/csv": [".csv"]},
"icons": [
{
"src": "csv-icon.png",
"sizes": "256x256",
"type": "image/png"
}
],
"launch_type": "single-client"
}
]
然后,想要在 PWA
启动时访问这些文件,你需要为 launchQueue
对象指定一个使用者。启动被排队,直到它们被消费者处理。
// Access from Window.launchQueue.
launchQueue.setConsumer((launchParams) => {
if (!launchParams.files.length) {
// Nothing to do when the queue is empty.
return;
}
for (const fileHandle of launchParams.files) {
// Handle the file.
openFile(fileHandle);
}
});
在很多 Web
开发的场景下,我们需要在没有网页中的导航的情况下去更新页面的 URL
,特别是在 SPA
应用里面,我们在切换了导航之后,不希望刷新网页,只更新页面中的内容。之前我们一般都是用 History API
去实现的。
let stateObj = {
data: "ConardLi",
}
history.pushState(stateObj, "home", "bar.html")
但是用过的都知道,这玩意实在是太难用了,而且还很笨重,也容易出现问题。Navigation API
提供了一种更友好的方式来帮助我们操作网页的导航。
要使用 Navigation API
,我们需要在全局对象上添加一个 navigate
监听器。
navigation.addEventListener('navigate', (navigateEvent) => {
switch (navigateEvent.destination.url) {
case 'https://blog.conardli.top/':
navigateEvent.transitionWhile(loadIndexPage());
break;
case 'https://www.conardli.top/':
navigateEvent.transitionWhile(loadCatsPage());
break;
}
});
这个事件采用了集中处理的机制:它会被所有类型的导航触发,无论是用户执行了一个动作(例如点击链接、提交表单或返回和前进)还是以代码的方式触发导航。在大多数情况下,它会让你的代码覆盖浏览器对该操作的默认行为。对于 SPA
,这可能意味着让用户保持在同一页面上并加载或更改网站的内容。
了解更多:
2022
年 6 月 22 日,第 123 届 ECMA 大会批准了 ECMAScript 2022
语言规范,这意味着它现在正式成为标准。
主要特性:
Top-level Await
:允许我们在 async
函数外面使用 await
关键字;Object.hasOwn()
:一种更简洁、更可靠的检查属性是否直接设置在对象上的方法;at()
:通过给定索引来获取数组元素;了解更多:https://262.ecma-international.org/
Fresh
是一个面向 JavaScript
和 TypeScript
开发人员的全栈现代 Web
框架,基于 Deno
运行时,前端渲染基于 Preact
,由 Deno
原班人马开发,它的核心是路由框架和模板引擎的组合,可在服务器上按需渲染页面。
Fresh
可以在运行时做到按需构建,代码可以直接在服务器和客户端上运行。例如将 TypeScript
或 JSX
转换为纯 JavaScript
都可以在运行时按需完成,可以实现非常快速的迭代和部署。
了解更多:
近日,新一代 javaScript
运行时 Bun.js
发布了。和传统的 Node.js
这种传统的 javaScript
运行时不同,Bun.js
直接内置了打包器、转译器、任务运行器和 npm 客户端,这意味着你不再需要 Webpack/Rollup/esbuild/Snowpack/Parcel/Rome/swc/babel
就可以直接运行 TypeScript、JSX
!
另外,Bun.js
原生支持了数百个 Node.js
和 Web API
,包括约 90%
的 Node-API
函数(fs、path、Buffer
等)。
Bun.js
的目标是可以在浏览器之外的其他地方运行世界上大多数 JavaScript
,为你未来的基础架构带来性能和复杂性的增强,并通过更好、更简单的工具提高开发者的生产力!
了解更多:
2021
年 2
月,Evan You
式推出了 Vite 2.0
版本,自此之后 Vite
生态飞速增长,很快达到了每周 100
万的 npm
下载量,距离 v2
发布 16
个月,Vite 3
正式发布!
主要更新如下:
VitePress
文档Vite CLI
优化,默认端口变更为 5173
WebSocket
连接策略import.meta.glob
语法更新SSR
产物默认使用 ESM
Relative Base
Esbuild
构建时优化HMR Partial Accept
了解更多:https://vitejs.dev/blog/announcing-vite3.html
在今年的 12 月份,Vite 又发布了 4.0 版本,不过相比 3.0 版本更新范围较小,所以不过多介绍
HTTP 103
状态码 (Early Hints
) 是一个信息性 HTTP 状态代码,可以用于在最终响应之前发送一个初步的 HTTP
响应,它可以算作 HTTP/2 Server Push
的升级改良版。
利用 HTTP 103
状态码,可以让服务器在服务器处理主资源的同时向浏览器发送一些关键子资源(JavaScript、CSS 或字体文件)或页面可能使用的其他来源的提示。
浏览器可以使用这些提示来预热连接,并在等待主资源响应的同时请求子资源。换句话说,Early Hints
可以通过提前做一些工作来帮助浏览器利用这种服务器思考时间,从而提升页面的渲染性能。
Chrome
宣布在 Chrome 103
版本对 HTTP 103
状态码提供了支持。
了解更多:
Firefox 103
版本正式支持了 backdrop-filter
属性,可以轻松实现一个毛玻璃效果。
Firefox
是最后一个支持 backdrop-filter
属性的浏览器,目前所有浏览器均已对它提供支持。
了解更多:https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter
:has()
属性Chrome 105
新增了容器查询和 :has()
属性,这兄弟俩可以让我们能够查询父选择器的大小和样式信息,同时使子元素可以拥有响应式样式逻辑。有点类似 @media
查询,区别是它们根据的是容器的大小而不是视口的大小进行判断的。
要使用容器查询,我们可以在卡片容器上设置 container-type
为 inline-size
:
.ard-container {
container-type: inline-size;
}
然后我们就可以使用 @container
将该容器的样式应用到它的任何子节点:
.card {
display: grid;
grid-template-columns: 1fr 1fr;
}
@container (max-width: 400px) {
.card {
grid-template-columns: 1fr;
}
}
当容器小于 400px
时,它就会切换到单列布局。
我们可以使用 :has()
伪类更进一步,它可以让我们检查父元素是否包含具有特定参数的子元素。例如,p:has(span)
表示一个段落选择器,你可以使用它来设置父段落本身或其中的任何内容的样式。
p:has(span) {
/* magic styles */
}
figure:has(figcaption) {
/* this figure has a figcaption */
}
了解更多:https://developer.chrome.com/blog/has-with-cq-m105/
Astro
是一个新型的 SSR
框架,它的测试版已经运行一年多。近期 Astro 1.0
终于发布了正式版本!
Astro
采用了独特的 Island
组件架构,团队称这是一种用于构建更快网站的新型 Web
架构。与传统的 SPA
不同,Astro
的组件不会被打包到一个 JavaScript
文件中。相反,每个组件都被视为一个独立的小型应用程序,与所有其他组件隔离存在。
了解更多:
Server Push
即在浏览响应 HTML
文件的时候,服务器会同时将所需的资源文件主动推送给浏览器。
浏览器在收到推送的资源之后会缓存到本地。等解析 HTML
发现需要加载对应资源的时候会直接从本地读取,不必再等待网络传输了。
虽然这听起来很神奇,但这个方案有非常大的缺陷:Server Push
很难避免推送浏览器已经拥有的子资源,其实很多资源在浏览器第一次请求到就已经缓存下来了。这种 “过度推动” 会导致网络带宽的使用效率降低,从而显着阻碍性能优势。总体而言,Chrome 数据显示 HTTP2/Push
实际上对整个网络的性能产生了负面影响。
Chrome
宣布将在下一个主要版本(Chrome 106
)中将删除对其的支持。
了解更多:https://developer.chrome.com/blog/removing-push/
就在 useEvent Hook
刚刚夭折不久,React
又计划提供新一个新的 Hook:use
,是的就叫 use
,它可以让开发者更轻松的使用 Suspense
访问任意异步数据源。
正常情况下我们在 JavaScript
中请求异步数据一般要借助 Promise
,对应的函数就要使用 async
和 await
:
async function Note({id, isEditing}) {
const note = await db.posts.get(id);
return (
<div>
<h1>{note.title}</h1>
<section>{note.body}</section>
{isEditing ? <NoteEditor note={note} /> : null}
</div>
);
}
而新增的 use Hook
,你可以类比为 await
,正如 await
只能在 async
函数内部使用一样,use
只能在 React
组件和 Hooks
内部使用,而且你可以嵌套在条件、块和循环中使用,而无需将逻辑拆分为单独的组件,这使得我们在 React
中编写异步代码变得非常灵活:
function Note({id, shouldIncludeAuthor}) {
const note = use(fetchNote(id));
let byline = null;
if (shouldIncludeAuthor) {
const author = use(fetchNoteAuthor(note.authorId));
byline = <h2>{author.displayName}</h2>;
}
return (
<div>
<h1>{note.title}</h1>
{byline}
<section>{note.body}</section>
</div>
);
}
了解更多:
Lerna
曾经是最流行的 JS monorepo
工具之一,在去年 Lerna
的核心作者提到了 Learn
已经基本不再维护,在今年 5 月份,Nrwl
宣布接管了 Lerna
。
随后,Nrwl
接管 Lerna
后发布了第一个全新的正式版本 Lerna v6
,推出了新的网站,并宣布让 Lerna
的速度提高了 10 倍!
对页面性能的可靠洞察对于我们构建好的用户体验是至关重要的,在以前,我们通常会依靠一些复杂的启发式方法来确定资源是否阻塞页面的渲染。
在 Chrome 107
,Performance API
新增了一个 renderBlockingStatus
属性,这个属性会提供来自浏览器的直接信号,用于识别阻塞页面渲染的资源,直到它们被下载下来。
下面的代码片段显示了如何获取所有资源的列表并使用新的 renderBlockingStatus
属性列出所有阻塞页面渲染的资源。
// 获取所有资源
const res = window.performance.getEntriesByType('resource');
// 过滤出阻塞渲染的资源
const blocking = res.filter(({renderBlockingStatus}) =>
renderBlockingStatus === 'blocking');
优化这些阻塞资源的加载方式(改为异步加载或增加一些预渲染优化)对于我们网站的 Core Web Vitals
是非常有帮助的,大家可以用起来了~
在今年的 Next.js
大会上,伴随着 Next.js 13
的发布,也推出了一个新的工具:Turbopack
。
Turbopack
是针对 JavaScript
和 TypeScript
优化的增量打包工具,由 Webpack
的创建者 Tobias Koppers
和 Next.js
团队使用 Rust
编写。
在刚推出的时候, Turbopack
给出了一份性能测试数据,数据对常见的打包工具的性能做了对比,结果显示Turbopack
的性能比 Vite
快 10
倍,比 Webpack
快 700
倍。
此数据一出,在前端圈引起了巨大的争议,Vite
的作者尤雨溪也亲自回应数据不是很客观,我们现在在 Turbopack
官网看到的最新数据已经有了变化,测试基准也可以随意调整(处理 1000-30000
个 React
组组件)
可以发现在最新的测试中,相比 Vite
,Turbopack
仍然有着不错的性能优势,Turbopack
目前只用于 Next.js 13 Dev server
,未来还会推出独立的 CLI
工具,并支持其他框架,如 Svelte
和 Vue
。
了解更多:https://turbo.build/pack
多年来,Web
生态系统中已经发展出很多可用于存储的 API
,例如 IndexedDB、localStorage
和 showNotification()
等等。
whatwg
新增了 Storage
标准通过定义存储的持久化、容量估算、过期时间等能力来整合这些 API
。
// 从存储桶中访问 IndexedDB
const inboxDb = await new Promise(resolve => {
const request = inboxBucket.indexedDB.open("messages");
request.onupgradeneeded = () => { /* migration code */ };
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
// 从存储桶中使用 File API
const draftFile = await draftsBucket.createFile(
["Attachment data"], "attachment.txt",
{ type: "text/plain", lastModified: Date.now()
});
// 从存储桶中访问 cache API
const inboxCache = await inboxBucket.caches.open("attachments");
在使用 TypeScript
类型推断的时候,有很多情况下会让我们面临两难的选择:我们即希望确保某些表达式能够匹配某些类型,但也希望保留这个表达式的特定类型用来类型推断。这就让我们陷入了两难的境地,我们用更严格了类型约束了写出 bug 的可能性,但是却失去了类型推断的能力。
satisfies
关键字就是用来解决这个问题的,它既能让我们验证表达式的类型是否与某个类型匹配,也可以保留基于值进行类型推断的能力:
type Colors = "red" | "green" | "blue";
type RGB = [red: number, green: number, blue: number];
const palette = {
rad: [255, 0, 0],
// 可以捕获到错别字 rad
green: "#00ff00",
blue: [0, 0, 255]
} satisfies Record<Colors, string | RGB>;
// 都可以调用
const a = palette.red.at(0);
const b = palette.green.toUpperCase();
了解更多:TypeScript 4.9 发布!重点新特性解读
Rome
是一个使用 Rust
编写的格式化和 Lint
工具,可以用于 JavaScript、TypeScript、JSON、HTML、Markdown
和 CSS
的格式化。相比传统的 Lint 工具,它的处理速度非常快,可以在 300毫秒 - 1秒
内处理 6000
个文件。
但是它的野心不止于此,它的目标是将数十种前端语言工具(Babel、ESLint、webpack、Prettier、Jest
等)统一为一个从头开始构建的易于使用的工具。
了解更多:https://rome.tools/blog/2022/11/08/rome-10/
Nuxt3
基于 Vite、Vue3
和 Nitro
等现代框架重写,具有一流的 Typescript
支持,经过两年多研究、社区反馈、创新和实验,终于发布稳定版本。
了解更多:https://nuxt.com/v3
为了解决移动端网页滚动时,动态工具栏自动收缩的问题,CSS
工作组规定了视口的各种状态。
Large viewport
(大视口):视口大小假设任何动态工具栏都是收缩状态。Small Viewport
(小视口):视口大小假设任何动态工具栏都是扩展状态。新的视口也分配了单位:
Large viewport
的单位以 lv
为前缀:lvw、lvh、lvi、lvb、lvmin、lvmax
。Small Viewport
的单位以 sv
为前缀:svw、svh、svi、svb、svmin、svmax
。另外还有一个 Dynamic viewport
(动态视口)
当动态工具栏展开时,动态视口等于小视口的大小。当动态工具栏被缩回时,动态视口等于大视口的大小。
相应的,它的视口单位以 dv
为前缀:dvw, dvh, dvi, dvb, dvmin, dvmax
。
目前,各大浏览器均已经对新的视口单位提供了支持:
了解更多:Chrome 108 :发布新的 CSS 布局单位!
SvelteKit
是一个用 Svelte
构建 Web
应用程序的框架,可以满足不同规模的应用开发,提供了非常灵活和体验良好的基于文件系统的路由架构。Svelte
是一个 UI
组件框架,因其出色的性能和易用性而受到开发者喜爱。
经过两年的开发,SvelteKit 1.0
已正式发布,现在可用于生产环境,它提供了服务端渲染、路由管理、针对 JS 和 CSS 的代码分割,以及针对不同 Serverless
平台生成不同代码的适配器等功能。
了解更多:https://svelte.dev/blog/announcing-sveltekit-1.0
以上的前端动态大部分《code秘密花园》都第一时间为大家带来了详细的解读,想要在 2023 年持续获得更多最新最有价值的前端动态,欢迎关注《code秘密花园》公众号。
如果文章对你有所帮助,别忘了点个赞~
最后给大家安排一波福利,都是都是来自一些出版社和社区赠送给我的,我在今天的文章里送给大家吧,一共给大家送 5 个福利,包括下面这些东西:
图灵2023年程序员日历、极客时间时间管理笔记、稀土开发者大会限量礼盒、狼书、Vue.js 设计与实现。
为了避免中奖后失联,可以提前加我微信好友 ConardLi:
抽奖方式1:
文末留言(可以是2022年的技术热点、年终总结、2023的展望、或者其他任何你想说的...)点赞前二名自动获奖,另外我会再随机抽取一位精选留言获奖(点赞排名无需靠前)
抽奖方式2:
点亮右下角在看:我会在后台随机抽两位获奖
点赞、在看点这里 ⬇️⬇️