为什么要弄blog
因为看到一些很漂亮的博客,就想着自己也用hexo搭起来。
在这里,整理自己过去在工作和学习中积累下来的笔记,有项目经验,有开发技术,有工具的使用细节;有读书笔记的类型,有肤浅的体会,有网络检索后没有轻易解决的宝贵经验。
“一切美,都是努力不断的更新。”
- 目前的系统环境是win10,通过vmware搭建了一个ubuntu16.04的开发环境(顺便学习《鸟哥的linux私房菜》)。
常用编辑器是WebStorm和Sublime Text3- VSCode最棒了!rua!rua!rua!
认识hexo
- hexo是呆湾少年Tommy Chen的作品,其安装照着官网来非常容易,右上角还有语言切换很方便,本文不做赘述。
- 使用上也就很简单:
- 通过
hexo init [floder]
命令就可以很简单的把项目的文件结构建立起来; - 通过
hexo new [layout] <filename>
可以建立新的文章; - 在
config.yml
对配置做修改,主要可以修改blog的说明和将代码部署到git仓库的参数; - 通过
hexo s
命令在本地运行服务,进行开发;增加--debug
选项可以开启调试模式,如果出错可以在控制台获得更多的信息提示 hexo g -d
编译并且按照config.yml的配置发布。增加参数--watch
之后,只要对posts文件夹下的文件做出修改并保存,就会实时调用这个命令,直到通过ctrl + c
来停止监听。
- 通过
一些hexo命令的解释
命令
hexo g
会在pulic目录下建立以日期命名的文件夹,类似这样:1
2
3
4
5
6
7
8
9
10├── 2017
│ └── 09
│ ├── 21
│ │ └── Hello-my-blog
│ │ └── index.html
│ └── 23
│ ├── Hello1
│ │ └── index.html
│ └── Hello2
│ └── index.html默认情况下,草稿文件夹_drafts下的文件不会被展示,其变动也不会被监听——不论是草稿的创建还是修改。这就是草稿和正文的区别,直到调用了
hexo publish [layout] <filename>
命令将它发布。未免歧义,举个例子:hexo publish "关于hash的那些事"
。- 这里有一个关于
hexo g
的坑:文件的冗余。- 如上tree图,在23日,发布了文章Hello1。如果之后,比如说24日,对其再做编辑,
hexo g [--watch]
命令会在24日文件夹下生成新的Hello1,23日的Hello1就会成为冗余的旧文件。 - 这个时候,
hexo clean
命令就派上用场了。当博客的内容越来越多,而作者的习惯又不是太好,不喜欢使用”草稿“功能,而是直接编辑正文的话,这个命令可以帮助清理public下的文件。
- 如上tree图,在23日,发布了文章Hello1。如果之后,比如说24日,对其再做编辑,
hexo的部署发布
- 想要使用
hexo g -d
自动部署,需要先安装插件npm install hexo-deployer-git --save
然后在
_config.yml
文件里添加配置:1
2
3
4
5deploy:
type: git
repo: <repository url> # https://bitbucket.org/JohnSmith/johnsmith.bitbucket.io
branch: [branch] # published
message: [message]hexo g -d
的时候发生了什么:- 如果是项目第一次执行,则hexo在根目录下,新建一个
.deploy_git
文件夹,然后把编译的代码放在里面,并将它设置为一个Git仓库。 - 在hexo根目录的
.gitignore
文件里我们会注意到这个文件夹也是被hexo项目的Git忽略的。 - 这个Git仓库完全根据hexo根目录下
_config.yml
里的配置,message
作为commit的message(如不设置,会有默认值,主要反应commit的时间),随后该Git仓库会向设定的repo
的branch
分支去推送。 - 如果在本机上没有对git做全局的user设置,部署的时候会提醒要给.deploy_git里的仓库设置user.name和user.email。
- 如果是项目第一次执行,则hexo在根目录下,新建一个
那么怎么通过Git管理hexo项目比较合理呢?
- 官方文档里说:“一个推荐的方式是把master作为写作分支,另外使用public分支作为部署分支。”估计很多新手对此感到有点迷茫。
- 这个建议旨在告诉我们,我们可以仅仅用一个仓库的2个分支,同时管理部署和写作。但这听起来很不错的建议里,其实有一些细节需要特别注意:首次建立了blog并且推送到远程仓库后,如果在别处从远程仓库拉取了写作分支,(比如在另一台电脑上),写作结束后想顺手部署,想着设置都是正常的,就直接运行了
hexo g -d
会发现hexo又生成了一个.deploy文件夹。根据_config.yml
推送到同一个远程仓库的同一个分之后,你会发现原来的部署分支整个被替换掉了…之前的部署分支的commit全部消失(其实就相当于删掉了原来的远程分支) - 这是因为Git通过
.git
文件夹存放了对当前仓库的管理,hexo在部署中,如果检测到.deploy_git文件夹里有Git仓库了,就对其做一个提交;如果没有检测到就会新建一个Git仓库(如果你已经设置了global的user.name和user.email,hexo不会给你提醒,你就会忽略这一点),而这个Git仓库的当前分支,会被推送到远程仓库的部署分支上,对其进行一次彻底的覆盖。 - 其实部署和写作,完全可以算两个项目了。我们可以简单的用一个仓库一个分支管理hexo项目,而在
_congfig.yml
里配置部署到另外一个仓库另一个分支。分开管理并不会有什么问题,部署分支并不太需要版本控制,只控制写作分支完全足以保证对项目的维护。而且,鸡蛋装在2个篮子里也是一件好事。 如果你就是想用、或者只能用一个仓库管理、或者无论如何就是想要维护部署分支并保留其Git提交记录*,以下给出一个从零开始的(适合强迫症患者的)Git管理建议:
- 新建一个hexo项目,将其git仓库化,并设置好远程仓库origin
- chekout一个write分支(分支名字都随便起)作为写作使用
- 在
_config.yml
里配置,deploy指向同一个远程仓库,分支名为deploy - 在别处新拉项目时,可以直接拉写作分支
git clone -b edit [url]
- 然后再拉取部署分支,这里要这么做
git clone -b deploy [url] .deploy
这样就能吧部署分支放到.deploy文件夹里。如果回到之前的环境工作,也只需要注意更新edit分支就可以了。hexo g -d
执行时,.deploy_git
会自动跟进,就像一个普通的Git仓库那样工作。 - 再次强调:其实hexo只需要关注edit分支就可以了,hexo新建的时候,会准备好
.gitignore
文件,你不需要多余的操心。网络上很多文章,维护自己的hexo项目居然是以部署分支为核心,实属买椟还珠。如果你没有强迫症想要保留部署分支的提交记录,在别处新拉项目的时候你完全可以忽略上面的步骤。(第5步) 初次推送部署的项目里,.deploy_git里的git config是:
1
2branch.master.remote=git@github.com:username/username.github.io.git
branch.master.merge=refs/heads/master而在别处拉取新项目后,拉deploy分支到.deploy_git里,其git config是:
1
2
3
4remote.origin.url=git@github.com:username/username.github.io.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master注意以上差别,所以为了保留对部署分支的提交,你还需要更改初次推送部署的
.deploy_git
仓库的git config。否则他的每一次推送都是forced update
,会抹除其他新拉项目对部署的推送——从设计上默认的这一点也可以看出,只用一个仓库、或者说执着于部署分支的提交保留并不是作者的出发点。
- 如果使用个人帐号的GitHub Pages来展示blog,需要注意的点如下:
- 个人GitHub Pages只能关联master分支(GitHub的规则),所以上面的部署分支必须命名为master
- 远程仓库会将被推送的第一个分支展示为默选分支,但还是可以到Settings->Branches->Default branch去修改,这一条也是写给强迫症的。
- 最后,GitHub Pages只是一个单纯的前端静态服务器,功能有限,只适合初阶使用。
hexo server热加载问题
根据Hexo官网的说明,hexo server
命令可以监视文件变动并且自动刷新,但在实际的使用当中,我很遗憾地发现这个功能是存在问题的,总需要手动刷新才能生效。这就很难受了。
这可能是因为我的系统不是Mac环境:根据一些前人的经验,hexo-fs模块负责了文件系统,其依赖chokidar(一个监视文件系统的类库),又依赖fsevents去实现OS X上对文件系统事件的监听——那么linux和windows系统自然是走远了。
使用meta标签:每隔20秒自动刷新一次……pass。
1
<meta http-equiv="refresh" content="20">
hexo-browsersync
- 官网插件页里的hexo-browsersync,根据介绍,在编辑后,保存动作就会触发更新。
- 结果发现:这个插件只有在你停留在blog首页的时候才会触发更新。进入具体的页面去编辑的的时候,还是只有手动刷新能看到改动——要你何用?!
浏览器插件livereload
- 又尝试了一下浏览器的插件,这个插件需要同时在浏览器和编辑器里设置(以Sublime Text3为例)。
- 在浏览器插件设置里,勾选“允许访问文件网址”;
- 打开Sublime之后,
ctrl+shift+p
输入livereload
去手动开启功能。
初步的使用结果是需要连续保存 2 次才能触发网页的自动更新……这也太蛋疼了,F5逃过一劫,CTRL和S的命又短了,当然,不用先焦点浏览器再F5,勉强算一个进步?这可不行。
- 虽然如此,我注意到这个插件确实地实现了自动刷新。既然已经出现了“需要第二次保存才能刷新出第一次保存的改动”的情况,那就表明机制是ok的,只是项目本身的更新(毕竟hexo s展示的并不是源md文件,而是有一个编译动作)延迟于编辑器里对页面的更新。
在网络上搜索livereload相关,基本很少涉及这个问题,大部分都是简单抛出在浏览器里的安装和在sublime里的安装、启动以及配置。就像这样:
1
2
3
4
5
6{
"enabled_plugins": [
"SimpleReloadPlugin",
"SimpleRefresh"
]
}livereload本身是有着”with delay(400ms)”的模式的。开启这个模式,在配置文件中修改为:
1
2
3
4
5{
"enabled_plugins": [
"SimpleReloadPluginDelay"
]
}bingo~!成功实现热更新。需要注意的是,如果你修改了配置文件比如
_config.yml
,还是需要重新运行hexo s
的。
- 又尝试了一下浏览器的插件,这个插件需要同时在浏览器和编辑器里设置(以Sublime Text3为例)。
hexo本身就没有使用webpack来配置。这里留个期待,希望将来可以改造一下hexo的项目架构。
一些编写的细节
- yaml语言,和json的语法略有区别,他有“约定大于配置”的思想,比如:
- 配置里的冒号后面需要一个空格,否则容易报错
- 缩进表示示层级,在标签或者分类的写法里,
-
符号和名名称之间,必须有一个空格。
图片引用:
- 我认为最好的方式就是图片放cdn,直接引url。还可以借助一些hexo插件,让图片上传cdn更加快捷(图片放项目里,deploy的时候自动上传cdn)
图片少的时候直接放项目里也可以
- hexo的
_config.yml
里设置post_asset_folder: true
,效果是通过hexo new
新建文章的时候,会在同路径下建一个同名文件夹。这里的资源都可以直接在文章里引用(不需要路径)如果不改这个设置仅仅是手动增加文件夹,是不能正常显示的;而这个选项一开,不管是new还是publish,都会自动生成一个文件夹。 图片不推荐
![This is an image](image.jpg)
,而推荐使用标签语法,这样在首页也能正确解析出来:1
{% asset_img image.jpg This is an image %}
- hexo的
对自己站内文章的引用:
1
{% post_link 文章文件名(不含文件类型) 站位字符(可选) %}
使用markdown来绘制流程图:
- 首先要明白,流程图的特征是什么?
- 圆形:开始、结束
- 矩形:普通环节
- 菱形:问题判定
- 平行四边形:输入输出
- 箭头:工作流方向
- 其次,hexo并不默认支持显示流程图和序列图,需要安装插件hexo-filter-sequence和hexo-filter-flowchart
- 目前存在这样的bug:单独使用sequence是无效的,根本无法显示出序列图。但是!如果在sequence同时来一个flow——序列图就出现了!所以截止目前,在这个blog里这是一个坑:同一个md文档里,必须有一个flow图,其他sequenc图才能显现出来。
- 首先要明白,流程图的特征是什么?
markdown表格的写法
- 注意,显示有问题的时候,检查下表格整体的缩进,一般没必要缩进。
- 表头不可以省略,表头下的代码用于标示此列内容的对齐方式。
hexo对表格的支持实在不咋地,在列表里放表格更是一种灾难,实在不行可以考虑:
1
2
3{% raw %}
被包裹的 html table
{% endraw %}
优化提交:保持更新的话每日都有git操作,推荐增加shell脚本或使用git-gui来节省操作。
- 在编写内容的时候,列表和标题应该按需使用,能美化排版
一个hexo的解析问题:在shell脚本里经常出现的左花括号加井号,在hexo里是会产生歧义的,因此写shell相关文章的时候,需要把这种符号写进三个反引号表示的代码块里,才不会出问题。否则就可能面对
Template render error: (unknown path)
之类完全找不到报错地方的提示。1
2在shell里经常出现{#
但是在hexo的解析器看来 {# ... #} 表示注释,所以会导致解析错误
引入theme(next)
- 增加next主题——fork了主题的仓库,使用git submodule的形式引入自己的hexo项目。如果仅仅按照主题的安装建议直接git clone,并不会是太好的实践:)虽然git submodule会很复杂,但是仅仅引入一个主题而已的话,并不会太难。在《Git看这篇》里,我补充了相关的内容。
- next6以后使用了新的项目地址
- next文档按着这个做了简单的配置。配置文件写的还是很清楚的,文档缺少的说明也能自己看懂。
- next没有
zh-Hans.yml
,可以考虑直接复制zh-CN.yml
并且改名。
使用插件
hexo-symbols-count-time
- 一个字数统计+阅读时间估算插件,插件地址
- 在hexo里安装
npm install hexo-symbols-count-time --save
在hexo的
_config.yml
里增加配置:1
2
3
4
5
6
7
8# Extensions
## Plugins: https://hexo.io/plugins/
symbols_count_time:
symbols: true
time: true
total_symbols: true
total_time: true
exclude_codeblock: false确认next里的
_config.yml
里有配置1
2
3
4
5
6
7
8
9# Post wordcount display settings
# Dependencies: https://github.com/theme-next/hexo-symbols-count-time
symbols_count_time:
separated_meta: true
item_text_post: true
item_text_total: false
awl: 2 # 汉语写作推荐
wpm: 300 # 汉语写作推荐
suffix: mins.注意:想要插件生效,一定要运行一次
hexo clean
想要一个怎样的blog
blog里有不少TODO: 和 FIXME: 这些标记能让我更容易补充或者修改内容
blog是一种形式,也是一种态度;是一种鞭策,也是一种坚持;是自我的满足,也是慷慨的分享;是自豪的积累,也是抛砖引玉的谦卑。
我希望我的blog不仅仅是个人经验的整理,更能成为让人一看就懂,一看就有收获的分享。自己写完东西后,还会时不时的回来修订;在写的过程中,努力做到在每一段落之前,用简明扼要的语言抓住重点,辅以必要的样例;内容上既要有切实可行的操作,也要有自己踩了坑带来的小机智。
写在最后,也是写在一开始。