“前端微周刊”每周五更新,为前端开发者提供一些技术相关资讯及文章。
微信搜索订阅“前端微志”公众号。
🖼 趣图

如果将Ever Given号货轮树立在旧金山的摩天大楼Salesforce旁边,它们看起来会是像图中这样子。两者的数据对比如下:
Ever Given
长: 399.94米
宽: 58.8米
Salesforce Tower
长: 326.14米
宽: 50.95m
📰 资讯
Next.js 10.1发布
Next.js 10.1版本发布,带来了这些特性:
- 最快三倍刷新:在不必要的改变的情况下,刷新加快200ms
- 提升安装依赖时间:减少58%的安装大小并减少56%的依赖项
next/image优化:支持Apple Silicon(M1),添加更多布局和loader配置项- 集成电子商务
Shopify:为可组合的电子商务应用提供灵活的数据层 - 自定义
500页面:可以在异常页面添加自己的logo和商标 - 严格的
PostCSS配置:使用Webpack 5的缓存提升性能 tsconfig.json文件支持extends:为大型TypeScript应用提供可拓展的配置文件- 判断
预览模式是否开启:可在预览模式下显示自定义内容 - 路由方法自动滚动到顶部:与
next/link一样,router.push和router.replace也会自动将页面滚动到顶部 - 优化文档:新增迁移,Docker部署等内容
TypeScript 4.3 Beta发布
TypeScript 4.3 Beta版本已支持下载,这次带来了分离的get/set类型,'override'关键字,更智能的模板字符串类型,class私有元素和编辑器性能提升等。
其中有一个特性是:Promise的检查总是为真值。这样我们在使用async/await时,就不会忽略async函数的返回值其实是Promise<T>了。
示例代码:
async function foo(): Promise<boolean> {
return false;
}
async function bar(): Promise<string> {
if (foo()) {
// ~~~~~
// Error!
// 这种场景下,foo()的值总是 true
// 因为 'Promise<boolean>' 表示一个promise实例,是一个对象
// 不要忘记使用'await'?
return "true";
}
return "false";
}
Stack Overflow限制网站上代码的复制次数,再也不能愉快地复制/粘贴代码了

其实这是愚人节的玩笑,因为你还会看到Stack Overflow的另一个产品:复制粘贴键盘,实物是下面这样的。

这个键盘不是玩笑,是真的,有人发了实物的开箱视频。
GitHub自动为README.md文件创建目录

GitHub最近有一个新特性更新,在浏览代码仓库的README.md文件时,会自动地创建一个目录,并固定(类似sticky的粘性定位方式)在浏览器的顶部。
Container Query真的要来了
前端开发者对于Media Query(媒体查询)肯定不陌生,它可以让开发者根据设备的屏幕尺寸、DPR等信息对CSS样式进行分割和组合,这也正是响应式布局的由来。
Container Query这个概念来源于开发者社区,它和Media Query非常相似,只不过它要判断的主体不是整个屏幕设备,而是某一个HTML标签。来看一个例子吧:
@container (min-width: 40em) {
.card {
display: flex;
align-items: flex-start;
gap: 1.5rem;
padding: 1.5rem;
max-width: unset;
}
.card h2 {
font-size: 2.5rem;
}
}
目前跟进最快的浏览器厂商是Chrome,我们将在Chrome 91中看到第一个迭代的版本,既然Edge也使用Chromium,那Edge也可以顺带着支持一下了。
SvelteKit目前已达Beta阶段
SvelteKit是Svelte的下一代框架,在Svelte语法的基础上,已经完成SSR、路由、JS和CSS的代码分割,以及对不同的serverless平台进行了适配等。
在对比了Vite 2和Snowpack这两种理念更现代的打包工具之后,SvelteKit觉得前者的一些特性(如:主要以SSR为设计核心,CSS代码分割等)更能符合它的需要,且能更好地将这个新的框架呈现出来。
喜欢尝鲜的朋友可以查阅一下SvelteKit文档,或许它会成为未来几年中前端框架的一匹黑马。
📖 文章
从一道让我失眠的 Promise 面试题开始,深入分析 Promise 实现细节
一道Promise面试题,包含了很多JavaScript事件循环的原理,文中不止带你实现一个符合Promise A+规范的Promise,还顺带着帮你梳理一下异步执行中的宏任务和微任务。
虽然符合了Promise A+规范,但是跟原生Promise的执行结果不同,根本原因竟是一个微任务造成的。
由此带来一个思考:规范也不是面面俱到的,不能将所有可能的场景都覆盖到,我们能做的就是洞悉其不同之处,做到心里有数,避免这种问题产生。
Handling Text Over Images in CSS

如果要在图片上面显示文字,受图片颜色的影响,直接显示文字经常会造成文字不可读或不宜读。在业务开发中,设计师给出的设计稿可能使用了特定颜色的图片和文字(如暗色图片和白色文字),但是设计稿只是一个参考,真实场景中图片的颜色的动态多变的,而开发者无法实时分辨出图片的颜色,再适时改变文字的颜色。
如果设计师意识不到这个问题,就需要开发者主动发现,并与设计师沟通修改。以设计师的视角来看,有很多种解决方法,这些解决方案在前端技术上能不能实现,就需要开发者额外关注。
本文主要针对“图片上显示文字”这种场景,分析出了多种可能在技术上可行的解决方案,如:半透明文字层、渐变文字层、文字背景和文字阴影等。
9 Best JavaScript and TypeScript ORMs for 2021
首先解释一下什么是ORM?ORM是对象关系映射的意思,通常用于数据库字段与编程语言中的类做映射,这样就不需要直接编写复杂的SQL语句,方便进行数据的增删改查等。如Java中对应的中间件有ibatis,Hibernate等。
对JavaScript生态的开发者来说,使用Node.js开发后端应用时,也同样需要ORM工具来提升开发效率,文中介绍了9种ORM库:
Sequelize:适用于Postgres,MySQL,MariaDB,SQLite和Microsoft SQL ServerBookshelf:适用于PostgreSQL,MySQL和SQLite3Waterline:适用于Local disk/memory,MySQL,MongoDB和PostgresObjection.js:适用于SQLite3,Postgres和MySQLMongoose:适用于MongDB
有几个ORM库是支持TypeScript库的:
Typegoose:适用于MongoDBTypeORM:适用于MySQL,MariaDB,Postgres,CockroachDB,SQLite,Microsoft SQL Server,Oracle,SAP Hana,sql.js和MongoDBMikroORM:适用于MongoDB,MySQL,MariaDB,PostgreSQL和SQLitePrisma:适用于PostgreSQL,MySQL,SQLite,SQL Server
How GitHub Actions renders large-scale logs

通常日志文件中的信息,多达数千或上万行,要在Web页面中直接渲染这些日志信息,会面临很大的性能问题,可能会造成页面卡顿,滚动延时等问题。
GitHub采用了类似“按需加载”的技术方案,只在用户界面的可视区域展示内容,视图之外使用空白区块占位,在用户滚动页面时,再实时计算视图内和视图外区域的高度变化。
通常,瀑布流式的图片网站也会采用这种方案进行性能的优化,保证滚动的流畅性和页面体验的良好。
🛠 工具、插件
Responsively:让开发自适应Web加速5倍

Responsively是一个专为Web开发者设计的工具,最大的优点就是:提效。Responsively在GitHub上开源,同时还获得了ProductHunt在2021-03-16的当日最佳。
它通过将不同尺寸的设备在同一个窗口中同步展示,缩短了开发者调试页面的时间。总结几点特色是:
- 各设备在点击、滚动和导航等交互上,可随其中一个设备镜像联动
- 自定义布局
- 一键使用
Inspector选择元素(使用DevTools) - 超过30个内置设备信息,覆盖主流设备,也可自定义设备尺寸
- 一键截图
- 支持热加载
Wallace:网站CSS分析的命令行工具
可以使用npm或yarn全局安装:
npm install -g wallace-cli
# or
yarn global add wallace-cli
然后只需在命令行中输入wallace,空格之后再输入要分析的网站链接即可。
动手分析一下tinyshare.cn,嗯…,还是能发现不少问题的。

Aladino:让你的网站应用Shader Effects特效的轻量WebGL库

AI技术:由文字生成图片

不得不说,这是一个脑洞很大的项目。如果这事能成,以后拍电视/电影就不需要演员了,编剧写的稿子,直接一键生成一个电影/电视,主角有多帅都可以“吹”出来。😂
长期关注这个项目,期待它“出圈”的那一天。
iHateRegex:正则表达式的爱恨情仇
有多少人是:
- 对正则表达式100%了解
- 喜爱正则表达式
如果你的答案是否定的,那就需要这个工具了。它不止包含了非常多常用的数据正则格式,还可以通过关键字搜索的方式查找。每一个正则都有一个可视化数据流程图,更简单易懂,看上一眼,你可能就无敌了。

🥅 代码片段
使用DocumentFragment减少页面重绘
DocumentFragment不是真实的DOM树的一部分,但它却有着document一样的API,且它的变化不会触发DOM树的重绘,对性能不会产生影响。
下面通过一个示例讲解如何使用DocumentFragment减少重绘。
通常,我们循环创建一些标签,再将这些标签添加到父节点中,每个标签都需要添加一次,每添加一次都会造成页面的一次重绘。
const list = document.querySelector('#list');
const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];
fruits.forEach(fruit => {
const li = document.createElement('li');
li.innerHTML = fruit;
list.appendChild(li);
});
我们可以将所有要添加的元素都先添加到DocumentFragment标签中,最后一次性将DocumentFragment标签添加到父节点中,只会造成一次重绘。
const list = document.querySelector('#list');
const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];
const fragment = document.createDocumentFragment();
fruits.forEach(fruit => {
const li = document.createElement('li');
li.innerHTML = fruit;
fragment.appendChild(li);
});
list.appendChild(fragment);
ES6中string的搜索函数startsWith,endsWith和includes
在ES5中,我们经常使用indexOf来获取字符串中某一段文本的索引位置,在ES6中有几个更简单的方式实现这一目的。
// 判断某段文本是否存在
// ES5
'hello'.indexOf('ello') === 1;
// ES6
'hello'.startsWith('ello', 1);
// ES5
'hello'.indexOf('hell') === (4 - 'hello'.length);
// ES6
'hello'.endsWith('hell', 4);
// ES5
'hello'.indexOf('ell', 1) !== -1;
// ES6
'hello'.includes('ell', 1);

