Skip to content

Kevin's Home

Hugo使用笔记

hugo, blog generator1 min read

Hugo是spf13大神写的一个静态博客生成器,拥有仅次于Hexo的用户量。相比于Hexo,Hugo使用Go编写,生成速度快了很多。除此之外,Hugo的设计更加合理,文档也比较详尽,比较适合我这种喜欢从零开始折腾的技术宅。本博客就是在hugo上搭建的,使用了自己编写的主题: canoe

迁徙博文

因为我以前使用的hexo,已经拥有相当一部分博文了,所以我需要将原来hexo格式的博文转换到hugo中。其中主要的差异在于front matter,hexo使用YAML格式,这也是支持最为广泛的格式。hugo则默认是toml,但是同时可以支持yaml和json格式。个人感觉toml格式并没有多大的方便,倒是YAML格式支持的最为广泛,所以我还是在hugo中指定了使用YAML格式的front matter:

但是仅仅这样,还是不能直接copy & paste,因为hexo的front matter中date没有包含时区信息而hugo则需要指定。直接一篇一篇的改太过繁琐,因此我写了一个小工具来做这件事,PS:需要先安装依赖 mkdirpmoment-timezonegray-matter

主题

hugo的主题大部分都是非常简陋的,看得出来都是一群后端程序员 😂,看了一圈没有我喜欢的,加上自己对博客主题设计有一些自己的想法,于是就自己动手写了当前这个主题。取名叫canoe吧,有特殊的纪念意义。

模版类型

hugo把一个博客的模版归总成了四大类: index ,single,list,terms分别代表首页模版、详情(文章)页模版、列表页模版和分类页模版(categories、tags)。而且hugo还能为页面定义不同的类型(type),不同的类型可以编写不同的模版,也可以fallback到默认的模版(如对于类型是archive的文章,首先采用的是archive\signle.html 如果前者找不到则会采用默认的文章模版_default\single.html)。

文章分类

文章分类在hugo中是一个比较抽象的概念,统称为taxonomies,是一个key-array的结构,包括categoriestags。我们可以实现terms.html来展示某一类taxonomy所包含的文章列表。

前端开发

hugo默认只提供了一个高性能的livereload服务器。但是开发主题需要用到很多前端相关的流程,包括热替换、前端资源预处理和后处理等等等,所以我还是引入了gulp 。使用了一套我最熟悉的技术组合:

  1. 使用typescriptrollup来编写脚本
  2. 使用sasspostcss来编写样式
  3. 使用browserSync来进行热替换

与hugo相关的gulp任务:

延迟加载Valine

搜索

hugo在官方文档 提到了几种实现站点搜索的方式。抛开第三方搜索工具不论只剩下lunr了。但是lunr需要一个索引文件,hugo没有像hexo那样的hexo-generate-json-content插件(其实它压根就没有插件系统)所以到最后还是用Node来干这件事情吧,而且刚好我已经搭好了一个可用的gulp workflow了。

需要注意的是lunr默认不支持中文搜索。这是一个非常蛋疼问题,网上的解决方法通常是这样的:

这里通过注册一个自定义的trimmer 方法来避免中文字符被忽略,分词算法应该写到stemmer函数中,但是中文分词算法并不是那么几行代码就能搞定的,如果全部放到线上的话,会极大的拖慢浏览器的加载速度。因此我们只能直接沿用原有的分词算法lunr.stemmer 在本地就把中文分词分好用空格分开,这样线上就可略过分词这一个步骤了。我写了一个工具来做这个,使用了nodejieba库,分词速度挺快的。主要逻辑是:

主要是利用gray-matter这个库对文档内容进行解析,然后把得到的contenttitle字段使用ChineseCut方法进行分词,将分词后的数组重新使用空格拼接成字符串返回,最后得到一个文章描述对象,包含着uritagscontenttitleoriTitle 这几个字段。

动画

动画绝大情况可以使用css3 transition解决,但是还是有一些css无能为力的情况。比如说章节滚动等。因此我用requestAnimate写了一个简单的纯动画方法:

更多的动画函数可以参考: https://gist.github.com/gre/1650294

部署

Github Pages

hugo官方教程是通过添加一个orphan的gh-pages分支,然后使用git worktree特性来将master分支里面的public目录定位到gh-pages中的。整个过程比较复杂,部署的过程中需要切换工作目录。所以官方也提供了一个shell脚本来自动干这事。

我这边直接使用了github的docs文件夹特性。在config.toml中添加一行publishDir: docs将站点文件生成至docs文件夹下,然后直接在master分支中开启github page就好了。github会自动部署docs文件夹里面的静态文件。

绑定域名和HTTPS

Github绑定域名就不说了,主要添加两条A记录,然后在Github上设置一下即可。但是Github绑定域名之后无法再使用https了(coding.net说起来这点还挺良心的),目前免费的解决方案只能使用cloudflare这种cdn了。

Netlify

使用Github Pages的方式主要不足是每次提交站点源码之前需要自己手动在本地先build一下,另外使用master/docs的方式的话还会污染每次的提交信息。

Netlify是一个不错的选择,连接了Github之后可以像TravisCL那样,持续集成部署了。另一方面,Netlify不仅能够绑定域名,提供https访问,还能支持HTTP/2协议,完全免费,国内速度也不错。官方网站

Forestry

这个挺强大的,像是把静态博客变成了一个动态博客。但是环境不能自己配置,不太适合我。官方网站