Hexo 建站

Hexo 安装、配置

  • 安装 Hexo、并建站

    1
    2
    3
    4
    5
    6
    7
     # 安装 Hexo
    npm install -g hexo-cli
    # 初始化 Hexo
    hexo init <folder>
    cd <folder>
    # 安装 Hexo 依赖
    npm install
  • 启动站点:https://hexo.io/zh-cn/docs/server

    1
    2
    3
    4
    # 安装独立的服务器模块(也可以不注册依赖)
    npm install hexo-server --save
    # 启动服务器
    hexo server [-p <port>]
  • 部署站点

    1
    hexo deploy

Hexo 站点结构

  • _config.yml:配置信息
  • package.jsonHexo 模块 npm 配置文件
  • scaffolds:模板文件
    • 新建文章时,尝试根据布局参数寻找相应模板建立文章
  • source:资源
  • public
  • themes:主题文件夹,一个文件夹即一个主题

Hexo 主题结构

  • _config.yml:主题配置文件
    • 修改后会自动更新
  • languages:语言文件夹
  • layout:布局文件夹,存放主题模板文件
    • Hexo 内建 Swig 模板引擎,可另外安装 EJSHamlJadePug 插件支持
    • Hexo 根据模板文件扩展名决定模板引擎
  • scripts:脚本文件夹
    • 启动时,Hexo 会载入其中 JS 文件
  • source:资源文件夹
    • 除模板外的资源,如:CSSJS 均位于此处
    • _ 开头文件、文件夹和隐藏文件被忽略
    • 若文件可被渲染,则会被解析存储到 public 文件夹,否则直接拷贝

Hexo 命令

1
2
3
4
5
6
7
8
9
10
hexo init [folder]
hexo new [layout] <title> # 新建
hexo generate # 生成静态文件
hexo publish [layout] <filename> # 发布草稿
hexo deploy [-g] # 部署
hexo render <file1> [file2] [-o <output>] # 渲染文件
hexo migrate <type> # 从其他博客系统迁移
hexo clean # 清楚缓存、静态文件
hexo list <type> # 列出站点资料
hexo version
  • 更新配置、安装依赖(如:修改渲染引擎)之后,尝试清空缓存使生效
    • $ hexo clean
    • 删除 db.json 文件

Hexo 模块

  • Markdown 渲染
    • hexo-renderer-mark:建议立刻删除,渲染能力极差
    • hexo-renderer-markdonw-it:不好用
    • hexo-renderer-markdonw-it-plus:也不好用
    • hexo-renderer-pandoc:太重,需要 pandoc 支持
    • hexo-renderer-kramed:快用,快用

NPM 总述

npm

  • npm 的三个独立组成部分
    • 网站:查找包、设置参数、管理 npm 使用体验的主要途径
    • 注册表:存储包信息
    • CLI:终端应用

npm 包管理

  • npm 包可以分为是否全局安装
    • 全局安装:适合安装命令行工具包
      • 位于 /user/localNode.js 安装目录
    • 局部安装(缺省):适合安装包依赖,且包通过 Node.jsrequire 加载
      • 位于当前目录 node_modules 目录下
    • 全局安装和局部安装互相独立
      • 若同时需要命令行、包依赖,则应分别安装或使用 npm 链接
    • 为避免污染全局环境,以下方式可以用于局部安装命令行
      • npx 包(命令):查找 noode_modules 中局部安装包
      • alias 设置别名:添加 PATH=<bin-dir>:$PATH <cmd> 别名,即每次为命令执行设置环境变量

输入命令

  • install:安装

    • -g:全局安装
    • --save:维护 package.json 中依赖项
    • --save-dev:维护 package.json 中开发依赖项
  • uninstall:卸载

    • -g:卸载全局安装包
    • --save:维护 package.json 中依赖项
    • --save-dev:维护 package.json 中开发依赖项
  • update:更新

    • -g:更新全局安装包
  • outdated:检查版本

    • -g:检查全局安装包
    • --depth=<num>:检查深度

输出命令

  • whoami
  • publish:发布包

npm 配置

  • config:更新、修改用户或全局 npmrc 文件

npm 配置文件

npm 用户配置文件

.npmrc

1
2
3
4
repository=<repo-URL>
init.author.email=
init.author.name=
init.license=
  • .npmrcnpm 用户配置文件,缺省为 ~/.npmrc
    • 指定 npm 本身配置:包仓库地址、用户信息

.npm-init.js

1
2
3
4
5
6
7
8
// 直接设置键值对
module.exports = {
"<custom-field>": "<field-value>",
"<custom-field>": "<field-value>",
}
// 通过 `prompts` 函数交互式设置键值对
module.exports = prompts("<Question 1>, "<Field>")
)
  • .npm-init.js:用户包初始化配置文件,缺省为 ~/.npm-init.js
    • 设置 package.json 生成内容

环境变量

  • NPM_CONFIG_PREFIX:全局包安装地址

npm 包配置文件

包配置文件

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"name": "<package-name>",
"version": "<semantic-version>",
"description""",
"main": "index.js",
"scripts": {
"tests": "echo \"Error:\" && exit 1"
},
"repository": {
"type": "git",
"url": "<URL>"
},
"keywords": [ ],
"author": "<author-name>",
"license": "<license-name>",
"bugs": {
"url": "<URL>"
},
"homepage": "<URL>"
// 以上为 `npm init` 默认生成内容
"dependencies": {
"<dep-named>": "<dep-version>",
"<dep-named>": "<dep-version>"
},
"devDependecies": {
"<dev-only-dep-named>": "<dep-version>",
"<dev-only-dep-named>": "<dep-version>"
}
}
  • package.json:局部包管理文件,位于当前包目录

    • 列出包依赖
    • 语义化 管理包版本
    • 方便迁移
  • 创建:npm init [--yes] 初始化包即默认生成 package.json

    • 包含字段可通过 .npm-init.js 设置
    • 字段值大部分为空,除非可从 npm 用户配置文件 init 字段中获取
  • 字段说明

    • name:可用 @<scope>/ 为包设置域名,方便组织相关包
    • version:应遵守语义化版本规则
    • dependencies:包依赖,安装、卸载时 --save 标志会自动维护
    • devDependencies:开发时包依赖,安装、卸载时 --save-dev 标志会自动维护

CSS

CSS属性

  • display:元素展示
    • inline:默认,内联元素
    • flex:弹性容器
    • none:不显示
    • block:块级元素,元素前后有换行符
    • inline-block:行内块元素
    • list-item:列表元素
    • run-in:根据上下文作为块级元素或内联元素
    • table:表格元素<table>,前后有换行符
      • inline-table:内联表格元素,前后无换行符
      • table-row-group
      • table-row
      • table-header-group
      • table-footer-group
      • table-column-group
      • table-column
      • table-cell
      • table-caption
    • inherit

弹性容器Flex

flex

弹性容器内元素空间分配

  • flex-grow flex-shrink flex-basis简写,只给出一个值时 相当于flex-grow
  • auto:同1 1 auto
  • none:同0 0 auto
  • initial:初始值,同0 0 auto
  • inherit

flex-grow

(弹性容器内)元素相对于其他元素项目扩展的量

  • auto
  • inherit
  • {num}:相对于其他元素的扩展量,默认为0,应该是按照比例分

flex-shrink

(弹性容器内)元素相对于其他元素收缩的量

flex-basis

(弹性容器内)元素基础长度

  • auto
  • inherit
  • 具体长度(%, px, em为单位)

flex-flow

  • flex-direction flex-wrap
  • initial
  • inherit

flex-direction

弹性容器内元素方向

  • row:默认,灵活元素水平排列
  • row-reverse:灵活元素水平反向排列
  • column:灵活元素竖直排列
  • column-reverse:灵活元素竖直反向排列
  • initial
  • inherit

flex-wrap

弹性容器内元素是否拆行/列

  • nowrap:默认,灵活项目不拆行/列
  • wrap:灵活项目必要时拆行/列
  • wrap-reverse:灵活项目必要时反向拆行/列
  • initial
  • inherit

弹性容器Align

align-items

弹性容器内侧轴(竖直方向)对齐各项元素,适合含有单行元素

  • stretch:默认,元素拉伸对齐,元素大小确定时同 flex-start效果
  • center:元素堆叠在容器中心
  • flex-start:元素堆叠向容器开头
  • flex-end:元素堆叠向容器结尾
  • baseline:元素位于容器基线上
  • initial:初始值
  • inherit:从父类继承

align-content

align-items有相同的功能,适合多行元素 (这个好像作用单位是弹性容器的行)

  • stretch:默认,元素拉伸对齐,元素大小确定时同 flex-start效果
  • center:元素堆叠在容器中心
  • flex-start:元素堆叠向容器开头
  • flex-end:元素堆叠向容器结尾
  • space-between:元素向容器两端堆叠,元素间保持间距
  • space-around:类似space-between,但元素于容器 边界直接也有间距
  • initial:初始值
  • inherit:从父类继承

align-self

设置弹性容器内元素本身侧轴方向上的对齐方式

  • auto:默认,继承父容器align-items属性,没有 父容器则为stretch
  • stretch:元素拉伸对齐,元素大小确定时同 flex-start效果
  • center:元素堆叠在容器中心
  • flex-start:元素堆叠向容器开头
  • flex-end:元素堆叠向容器结尾
  • baseline:元素位于容器基线上
  • initial:初始值
  • inherit:从父类继承

justify

弹性容器内水平排列各项元素

  • flex-start:默认,元素位于容器开头
  • flex-end:元素堆叠向容器结尾
  • center:元素堆叠在容器中心
  • space-between:元素向容器两端堆叠,元素间保持间距
  • space-around:类似space-between,但元素于容器 边界直接也有间距
  • initial:初始值
  • inherit:从父类继承

Thrift简介

Thrift架构

  • Thrift是跨语言、C/S模式、服务器部署框架

  • 使用Interface Definition Language(IDL)定义RPC接口 、数据类型

  • 然后通过Thrift编译器生成不同语言的代码,并由生成 代码负责RPC协议层传输层实现

    • 支持服务器端和客户端编译生成代码为不同语言
    • 客户端、服务端代码调用生成代码搭建C/S
  • Thrift支持动态(执行)、静态(编译)

Thrift网络栈

thrift_structure

TTransport

传输层,定义数据传输方式

  • 可以是TPC/IP、共享内存、共享文件等,作为运行时库

  • 提供了一个简单的网络读写抽象层,使Thrift底层TTransport 从系统其他部分(如:序列化、反序列化)解耦

  • 接口方法包括

    • open
    • close
    • read
    • write
    • listen
    • accept
    • flush
传输协议
  • TSocket:阻塞式socket
  • TFramedTransport:frame为单位进行传输,非阻塞式
  • TFileTransport:文件形式传输
  • TMemoryTransport:直接对内存进行I/O
    • Java实现时使用了简单的ByteArrayOutputStream
  • TZlibTransport:使用zlib进行压缩,同其他方式联合使用
    • 目前无java实现

TProtocol

协议层,定义数据传输格式

  • 定义了一种将内存的数据结构映射成可传输格式的机制,即定义 数据类型在TTransport和自身间进行解、编码

  • 需要实现编码机制,负责对数据进行序列化、反序列化

数据格式
  • TBinaryProtocal:二进制格式
  • TCompactProtocal:压缩格式
  • TJSONProtocol:JSON格式
  • TSimpleJSONProtocal:提供JSON只写协议,生成文件容易 通过脚本语言解析
  • TDebugProtocol:简单易懂的可读文本格式,便于debug

TProcessor

封装了从输入数据流中读取、向输出数据流中写的操作

  • 读写数据流用TProtocol对象表示
  • 和服务相关的TProcessor由Thrift编译器产生
  • 工作流程
    • 使用输入TProtocol从连接中读取数据
    • 将处理授权给用户实现的handler
    • 使用输出TProtocol向连接中写入数据

服务模型

  • 创建TTransport对象
  • 为TTransport对象创建输入、输出TProtocol对象
  • 基于输入、输出TProtocol对象创建TProcessor对象
  • 等待连接请求,交由TProcessor处理

支持的服务模型

  • TSimpleServer:简单单线程服务模型
  • TThreadPoolServer:多线程服务模型,使用标准阻塞式I/O
  • TNonblockingServer:多线程服务模型,使用非阻塞式I/O
    • 需使用TFrameTransport传输方式

Thrift语法

句法

  • 支持shell的#注释、C/C++的////**/注释

  • struct等复杂类型定义中

    • 类型名和{之间必须有空格
    • 各字段之间,分割(末尾不能有,
    • 方法可以使用;,结尾

函数

参数

  • 可以是基本类型、结构体
  • 参数是常量const,不能作为返回值

返回值

  • 可以是基本类型、结构体

数据类型

基本类型

不支持无符号整形

  • bool
  • byte
  • i16
  • i32
  • i64
  • double
  • string
  • binary:字节数组

泛型(容器)

容器中元素类型可以是除了service以外的任何类型(包括结构体、 异常)

  • map<t1, t2>:字典
  • list<t1>:列表
  • set<t1>:集合

结构体

Thrift结构体概念上同C结构体:将相关数据封装

1
2
3
4
5
6
struct Work {
1: i32 num1=0,
2: i32 num2,
3: Operation op,
4: optional string comment,
}
  • 编译为面向对象语言时:将被转换为类

  • 结构体中,每个字段包含

    • 整数ID
    • 数据类型
    • 字段名
    • 可选的默认值
  • 字段可选:规范的struct定义中,每个域都使用optionalrequired关键字标识

    • optional:字段未设置时,序列化输出时不被包括
    • required:字段未设置时,Thrift给与提示
  • 不支持继承

Exception

1
2
3
4
exception InvalidOperation {
1: i32 what,
2: string why
}
  • 异常在语法、功能上类似于结构体,使用exception声明,但 语义不同

Service

Thrift编译器根据选择的目标语言为server产生服务接口代码,为 client产生桩代码

  • 函数、参数列表定义方式同struct
  • 支持继承:extends
1
2
3
4
5
6
service Twitter {
# Twitter和`{`中需要有空格
void ping(),
bool postTweet(1: Tweet tweet);
TweetSearchResult searchTweets(1: string query);
oneway void zip();

enum

枚举类型

  • 枚举常量必须时32位正整数
1
2
3
4
5
6
enum TweetType {
TWEET,
RETWEET = 2,
DM = 0xa,
REPLY
}

const

常量

  • 复杂类型、结构体可以使用JSON标识
1
2
const i32 INT_CONST = 1234
const map<string, string> MAP_CONST = {"hello": "world", "1": "2"}

typedef

1
typedef i32 new_type

namespace

Thrift命名空间同C++中namespace类似

  • 均提供组织(隔离)代码的方式
  • 因为不同的语言有不同的命名空间定义方式(如:python中 module),Thrift允许针对特定语言定义namespace
1
2
namespace cpp com.example.project
namespace java com.example.project

PAC(Proxy Auto-Config)


pac事实上是一个js脚本,定义如何根据浏览器器访问url不同, 自动选取适当proxy

主函数

str = function FindProxyForUrl(url, host){
}
  • 参数
    • url:浏览器访问的完整url地址,如: http://bing.com
    • host:url中的host部分bing.com
  • 返回值:字符串变量,表示应该使用何种”代理“,可以是 以下元素,或者是使用;分隔的多个组合,此时浏览器依次 尝试 (“据说”每隔30min,浏览器就会尝试之前失败的“代理元素”)

    • DIRECT:不使用代理,直接连接
    • PORXY host:post:使用指定http代理@host:post
    • SOCKS host:post:使用指定socks代理
    • SOCKS5 host:post:使用指定的socks5代理

浏览器在访问每个url时都会调用该函数

可用预定义JS函数

host、domain、url相关js函数

  • bool = isPlainHostName(host)host不包含域名返回 true

    true = isPlainHostName(“www”) false = isPlainHostName(“baidu.com”)

  • bool = dnsDomainIs(host, domain)hostdomain相 匹配返回true

    true = dnsDomain(“www.google.com”, “.google.com”) false = dnsDomain(“www.apple.com”, “.google.com”)

  • bool = localHostOrDomainIs(host,domain)hostdomain匹配、host不包含domain返回true(按照函数名 理解)

    true = localHostOrDomainIs(“www.google.com”, “www.google.com”) true = localHostOrDomainIs(“www”, “www.google.com”) false = localHostOrDomainIs(“www.apple.com”, “www.google.com”)

  • bool = isResolvable(host):成功解析host返回true

  • bool = isInNet(host, pattern, mask)host处于 pattern指定网段/地址返回truehost如果不是ip 形式,将解析成ip地址后处理;mask指定匹配部分,mask 就是和子网掩码类似

    isinnet(“192.168.3.4”, “192.168.0.0”, “255.255.0.0”) -> true isinnet(“192.168.3.4”, “192.168.0.0”, “255.255.255.255”) -> false

  • str = myipaddress():字符串形式返回本机地址

  • int = dnsdomainlevels(host):返回host中域名层级数

    0 = dnsdomainlevels(“www”) 2 = dnsdomainlevels(“www.google.com”)

  • bool = shexpmatch(str, shexp)str符合shexp 正则表达式返回true

    shexpmatch(“www.apple.com/downloads/macosx/index.html”, “/macosx/“) -> true. shexpmatch(“www.apple.com/downloads/support/index.html”, “/macosx/“) -> false.

时间相关JS函数

  • bool = weekdayrange(wd1, wd2, gmt):时间处于指定时间段 返回true

    weekdayrange(“mon”, “fri”) 星期一到星期五(当地时区)为true weekdayrange(“mon”, “fri”, “gmt”) 从格林威治标准时间星期一到星期五为true weekdayrange(“sat”) 当地时间星期六为true weekdayrange(“sat”, “gmt”) 格林威治标准时间星期六为true weekdayrange(“fri”, “mon”) 从星期五到下星期一为true(顺序很重要)

  • bool = daterange(..):时间处于指定时间段返回true (包括首尾日期)

    daterange(1) 当地时区每月第一天为true daterange(1, “gmt”) gmt时间每月的第一天为true daterange(1, 15) 当地时区每月1号到15号为true daterange(24, “dec”) 在当地时区每年12月24号为true daterange(24, “dec”, 1995) 在当地时区1995年12月24号为true daterange(“jan”, “mar”) 当地时区每年第一季度(1月到3月)为true daterange(1, “jun”, 15, “aug”) 当地时区每年6月1号到8月15号为true daterange(1, “jun”, 15, 1995, “aug”, 1995) 当地时区1995年6月1号到8月15号为true daterange(“oct”, 1995, “mar”, 1996) 当地时区1995年10月到1996年3月为true daterange(1995) 当地时区1995年为true daterange(1995, 1997) 当地时区1995年初到1997年底为true

  • bool = timerange(..):时间处于指定时间段返回true

    timerange(12)中午12点到下午1点之间为true timerange(12, 13)同上例 timerange(12, “gmt”)在gmt时间中午12点到下午1点之间为true timerange(9, 17)上午9点到下午5点之间为true timerange(8, 30, 17, 00)上午8点30分到下午5点之间为true. timerange(0, 0, 0, 0, 0, 30)午夜0点到其后的30秒内为true

Web 代理

代理

  • 正向代理:模拟client的代理
  • 反向代理:模拟server的代理,通常带有负载均衡,通常不处理 用户数据,也有可能处理静态数据(图片,静态页面等),典型 就是nginx服务器