CSS网格布局

基本概念

CSS 网格布局已经得到了主流浏览器的支持,相较于传统的布局以及 flex 布局而言,从 MDN 上可以查到下面几个概念:

  • grid container:网格容器,即放置网格项目的容器,定义 display: grid 的 HTML 元素。
  • grid item:网格项目,是网格容器的子节点
  • grid lines:网格线,分隔网格行和列的线
  • grid tracks:网格轨道,相邻网格线之间的空间
  • grid cells:网格单元格,行与列的交集区域
  • grid areas:网格区域,四个网格线组成的矩形区域

上面的术语比较抽象,直接看如何定义一个基本的网格容器:

1
<div class="grid-container"></div>
1
2
3
.grid-container {
display: grid; /* 或者 inline-grid */
}

Read More

mongodb stats

查看 MongoDB 的统计数据库信息可以用下面的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
db.stats()
{
"db" : "test", # 系统自带测试数据库
"collections" : 0, # 集合数量
"views" : 0, #
"objects" : 0, # 文档对象的个数, 所有集合的记录数之和
"avgObjSize" : 0, # 平均每个对象的大小, 通过 dataSize / Objects 得到
"dataSize" : 0, # 当前库所有集合的数据大小
"storageSize" : 0, # 磁盘存储大小
"numExtents" : 0, # 所有集合的扩展数据量统计数
"indexes" : 0, # 已建立索引数量
"indexSize" : 0, # 索引大小
"fileSize" : 0, #
"fsUsedSize" : 0, #
"fsTotalSize" : 0, #
"ok" : 1
}

其中 fsTotalSize 表示 MongoDB 存储数据的文件系统上的所有磁盘容量的总大小,而 fsUsedSize 表示用掉的磁盘空间总大小,默认都是 bytes 单位,不过该函数可接受 scale 参数来切换单位:

1
2
3
db.stats(1024) // 得到的是 k 单位的
db.stats(1024 * 1024) // 得到的是 M 单位的
db.stats(1024*1024*1024) // 得到 G 为单位 1073741824

也可以在指定表上获取统计信息:

1
db.users.stats()

服务器用流的方式传输文件

创建一个 nodejs 服务器,用于传输文件给用户,可以用下面的方法:

1
2
3
4
5
6
7
8
9
10
const fs = require('fs')
const server = require('http').createServer();

server.on('request', (req, res) => {
fs.readFile('./big.file', (err, data) => {
if (err) throw err
res.end(data)
})
})
server.listen(8000)

但是上面的方法有个弊端,就是服务器对内存的占用取决于 big.file 文件的大小,如果文件特别大的话就会导致服务器内存爆仓,更好的方式是采用流:

1
2
3
4
5
6
7
8
9
const fs = require('fs')
const server = require('http').createServer()

server.on('request', (req, res) => {
const src = fs.createReadStream('./big.file')
src.pipe(res)
})

server.listen(8000)

docker 日志收集

docker 默认的日志驱动是 json-file,即保存在文件中,路径可以通过下面的命令查看:

1
docker inspect --format='{{.LogPath}}' NAME|ID

例如:

1
2
$ docker inspect --format='{{.LogPath}}' mysql
/var/lib/docker/containers/54571b675a6b52f70aea806977359d8bcd74543cb09e1aa139853113f835d1c4/54571b675a6b52f70aea806977359d8bcd74543cb09e1aa139853113f835d1c4-json.log

json-file 驱动会在启动某个容器时自动创建一个 json 文件,用于存储容器 stdout 与 stderr 输出的内容 ,当在宿主机中运行 docker logs -f 容器名 时,就会读取该文件的内容并显示在终端上。

Read More

git 删除和重命名分支

本地分支重命名

1
git branch -m old new

删除本地分支

1
git branch -D 本地分支名

远程分支重命名

  • 删除远程分支

    1
    git push origin  :远程分支名(你要删除的远程分支名)
  • 将本地分支推送到远程分支上,如果远程分支不存在,则创建此远程分支

    1
    git push origin  本地分支名:远程分支名

如果其他开发者已经删除了远程分支,但本地 git branch -a 依然显示,用 git fetch -p 即可

require 时报错 not a constructor

当引用第三方库的时候,经常会遇到下面的错误:

1
xxx is not a constructor

原因是该第三方库使用 es6 语法暴露出来一个类,但是在项目中使用了 require 来引用导致的。这是 babel 在转换 importexportrequireexports 时存在的差异,举个例子,用 es6 写 processor.js 暴露一个类:

1
2
3
4
5
// processor.js
class Processor {
}

export default Processor

如果用 require 来引用:

1
2
3
// require.js
const Processor = require('./processor');
const processor = new Processor() // 会报错

Read More

react保存路由状态

在一个 React 项目中,客户希望切换路由再回来的时候,能够保持之前的状态。而保存状态有两种场景:

  1. 只保留数据状态,不保留交互状态
  2. 既保留数据状态,又保留交互状态

所谓交互状态,就是连滚动位置、input 框里面输入到一半的文字等状态也要保留。上面两种场景对应的实现方法往往是:

  1. 状态管理器中保存初始化数据,在 componentDidMount 时调用
  2. 把页面隐藏掉,即设置:display: none

对于第一种情况,一个简单的实现是把某个页面的状态参数放到 url 的 query 参数里面,同时也在全局状态对象中也存一份,组件初始化的时候先尝试从参数里面加载,如果没有参数,就从全局状态对象中取出来,示例代码如下:

首先在 utils 中写暴露两个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
export function getURLState(opts) {
const { search, history, data = {} } = opts
const params = new URLSearchParams(search)
const fields = Object.keys(data), ret = {}
for (let i = 0; i < fields.length; i++) {
const field = fields[i]
ret[field] = params.get(field) || data[field]
}
history.replace(window.location.pathname + search)
return ret
}

export function setURLState(opts) {
const { search, history, data = {} } = opts
const currentUrlParams = new URLSearchParams(search)
const fields = Object.keys(data), ret = {}
for (let i = 0; i < fields.length; i++) {
const field = fields[i]
if (field in data) currentUrlParams.set(field, data[field])
}
const newSearch = '?' + currentUrlParams.toString()
history.push(window.location.pathname + newSearch)
return newSearch
}

Read More

sudo 保持环境变量

sudo 之后环境变量就没了,但有个 -E 选项能够保持环境变量:

1
2
$ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY'

帮助页面解释如下:

1
-E, --preserve-env

Indicates to the security policy that the user wishes to preserve their existing environment variables. The security policy may return an error if the user does not have permission to preserve the environment.

Linux 路由表

route 可查看路由表:

1
2
3
4
5
# route
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
default 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
Destination 目标网段或者主机
Gateway 网关地址,”*” 表示目标是本主机所属的网络,不需要路由
Genmask 网络掩码
Flags 标记。
Metric 路由距离,到达指定网络所需的中转数(linux 内核中没有使用)
Ref 路由项引用次数(linux 内核中没有使用)
Use 此路由项被路由软件查找的次数
Iface 该路由表项对应的输出接口

Read More

在centos上安装latex

  1. 官网下载安装包并解压
  2. 删除已存在的 texlive 版本

    1
    $ yum erase texlive texlive*
  3. 安装依赖

    1
    $ yum install perl-Digest-MD5 -y
  1. 进入解压后的文件夹

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $ ./install-tl
    Installing to: /usr/local/texlive/2019
    ...
    Welcome to TeX Live!

    See /usr/local/texlive/2019/index.html for links to documentation.
    The TeX Live web site (https://tug.org/texlive/) contains any updates and
    corrections. TeX Live is a joint project of the TeX user groups around the
    world; please consider supporting it by joining the group best for you. The
    list of groups is available on the web at https://tug.org/usergroups.html.


    Add /usr/local/texlive/2019/texmf-dist/doc/man to MANPATH.
    Add /usr/local/texlive/2019/texmf-dist/doc/info to INFOPATH.
    Most importantly, add /usr/local/texlive/2019/bin/x86_64-linux
    to your PATH for current and future sessions.
    Logfile: /usr/local/texlive/2019/install-tl.log
  2. 把路径添加到环境变量

    1
    2
    # ~/.bashrc
    export PATH=/usr/local/texlive/2019/bin/x86_64-linux:$PATH