0%

一、HelloWorld

演示

二、开发环境

1
2
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
阅读全文 »

随着业务的发展,monorepo 工程越来越大~

  • git commit 时耗时会比较久,耗时是大概 1min+;
  • git merge release 分支时耗时会更久,常常是 5min+;
    所以在实际开发过程中,会发现有部分同学偶尔会跳过 git hook,跳过 lint 校验拦截,提交有类型报错的代码。

为什么会这么慢?

根据以往的工作经验,在没有用 ts 的工程里 lint 执行都是比较快的,所以这里猜想是 ts 的某些 rule 影响了整体的执行速度,终于在 typescript-eslint 找到了原因:Troubleshooting & FAQs | TypeScript ESLint
图片
图片
如果我们在工程里开启了type-aware lint,那么执行 lint 的时间将会和构建时间一样长。
typescript-eslint 的一些 rules 是依赖 type information,所以在执行 lint 前会先编译一遍ts
Linting with Type Information | TypeScript ESLint 官网这里具体描述了type-aware 是如何开启的:
图片

  1. 配置 parserOptions(tsconfigRoot、project)
  2. 配置 type-aware 相关 rules
阅读全文 »

业务发展了一年多,随着工程越来越大,发现在提交代码的时候,耗时会很久。最近在业务需求不是很紧的时候,就抽空研究了一下。

在提交代码的时候,触发了 husky 配置的 pre-commit的 git hooks。相信大家对于这个 git hook 不会很陌生,我们大部分需要团队合作的项目,为了约束大家的代码规范,通常会选择使用 husky 并且在提交前进行代码校验拦截,这个时机就刚好是 pre-commit git hooks 的时机。

所以问题一下就变得清晰起来,是 pre-commit 的 hook 执行的 lint 检查耗时过长。首先先介绍下我们工程的技术选型:yarn + learn + ts + react ,在正式排查前,猜测主要导致 lint 执行慢的因素大概有两个 monorepo(工程多、代码量大)、ts(ts 类型检查耗时)。

在开始排查问题之前,先做了个小测试:只改动了一个 tsx 文件,并尝试提交,计时发现,从开始 commit 到 commit 完成,发现竟然耗时了 1min+,晕~。这里就猜想会不会是某个 lint 规则 或 某个 lint 插件导致运行很慢的?接下来就沿着这个思路进行排查。

阅读全文 »

最近在鼓捣 eslint 规则配置的时候,有两个配置一直傻傻分不清,这两个配置就是 extendsplugins。相信大家在实践过程中也会遇到这样的困扰,今天就来一起看一看,彻底搞清楚。

首先,我们知道 eslint 是一个代码检查工具,它会根据我们在工程里配置的规则,来进行校验。我们常常在以下场景中使用到 eslint。

  • vscode、webstorm 等编辑器、IDE安装插件
  • 工程运行时,通过 eslint-loader 检查及时发现问题
  • commit 时进行代码检查校验拦截(通常会配合 husky + lint-staged 使用)

所以一个团队如果想要保持统一的代码风格、良好的编码习惯,那约定和制定自己的 lint 规则就显得很重要。

rules

在简单的场景中,我们可以不需要了解 plugins 和 extends 的概念,比如只是约定「封号」、「引号」的使用:

1
2
3
4
5
6
{
"rules": {
"semi": ["error", "always"],
"quotes": ["error", "double"]
}
}

通过这样的配置,就约定了工程里统一强制使用封号结尾和双引号。

然而渐渐的,eslint 默认的一些规则不再满足我们的需要,这时我们就需要引入更多的规则集,这就是 plugins 的概念。

阅读全文 »

最近在 React 项目中引入 @loadable/component 进行懒加载优化时,发现了一个样式优先级问题。
我们工程里使用的是公司内部组件库,在想要覆盖组件库组件的样式时,基于 styled-components 的写法如下:

1
2
3
4
5
6
7
8
import styled from 'styled-components';
import { Button } from 'xxx';

// 覆盖 Button 组件样式
export const CustomButton = styled(Button)`
width: 80px;
height: 32px;
`;

正常情况下,上述代码应该会生效,即最终展现在页面上的按钮样式宽度应该是 80 px,高度为 32 px,覆盖原 Button 组件的宽高样式。

但是在实际使用过程中,我们发现了一些异常:覆盖的样式会偶现失效的情况。有些时候自定义宽高会生效,有些时候自定义宽高不会生效。经过排查,发现如果是在CustomButton所在页面刷新,则按钮展示的宽高是符合预期的,如果是从其他页面进入的,则自定义宽高不会生效。没有生效的原因也很简单,CustomButton 的样式优先级排在了 Button 后面。

阅读全文 »

Yarn 支持在工程的 package.json 文件中的 resolutions 字段里指定包的特定版本或者版本范围。

使用场景

  • 可能工程里的某个依赖的包A不是经常更新,但是这个包所依赖的包B有一个重要更新。这这种情况下,如果这个包A指定的依赖包B的版本范围没有覆盖到包B的最新版本的话,即重新安装依赖时,也不会安装到最新的包B,这时我们可能就要一直等待包A的作者更新了。
  • 当工程里的子依赖有一个重要的安全方面的更新,并且你不想等你直接依赖的包更新时
  • 当工程中某个依赖包正常运行,但是作者不再维护了。如果这个包某个依赖包有更新时,而且我们需要这个更新时。
  • 当工程中某个依赖包定义了一个很大范围的版本时,如果子依赖此时更新了一个最新版本存在bug,我们想退回之前的版本时,

总的来说就是,我们希望指定工程直接依赖里的某个子依赖包的版本时,可以使用 resolutions

阅读全文 »

BFC 概念

BFC 即 Block Formatting Contexts(块级格式化上下文),属于普通流定位。具有BFC特性的元素可以看做是隔离了的独立容器,容器里面的元素不会再布局上影响到外面的元素。

阅读全文 »

确定包含块

  1. position 为 static 或 relative,包含块 就是它最近的祖先元素(比如:inline-block, block 或 list-item)或格式化上下文(BFC)的内容区
  2. position 为 absolute,包含块就是它最近的position 不是 static的祖先元素的内容区 + padding区
  3. position fixed,包含块是viewport
阅读全文 »

Varnish是一款高性能、开源的反向代理服务器,支持负载均衡,经常被用作缓存服务,能够极大的提高网站的响应速度。

Varnish 进程分为master进程和worker进程,master进程负责读取配置文件、创建和管理子进程等,worker进程则负责处理请求。一旦子进程挂了,master进程会立即重新启动子进程。

安装

mac 上安装可以使用Homebrew

1
$ brew install varnish
阅读全文 »

JavaScript代码是单线程运行的,因而一旦有未捕获的异常抛出线程就会挂掉,业务也就不可访问了,所以一般我们在使用koa,express,thinkjs等其他node框架时一般会使用pm2去管理node进程,保证业务的高可用性。而阿里开源的egg框架本身自带的egg-cluster模板已经帮我们做了这个事情,egg的多进程模型和进程间通信官方文档上写的已经很清楚了,今天学习一下源码,希望有所收获。

egg-bin dev

运行一个egg项目,npm run dev在package.json文件里我们发现默认其实执行的是egg-bin dev。egg-bin原来是egg提供的一个开发时使用的命令行工具,翻开egg-bin的代码,我们可以看到egg-bin其实是基于common-bin开发的,这里不赘述common-bin的用法,感兴趣的童鞋自行去查阅。在lib/cmd/dev.js里我们可以看到egg-bin dev执行的逻辑(去掉debug日志):

阅读全文 »