在繁琐的细节记录之前,先一句话总结:

首先看到的是github-pages自带支持的jekyll,在摸索试验了大半天基本成功之时,又意外发现原来还有更好的替代品hexo。。


## hexo好在哪里? 1.它是用nodejs写的,js嘛地球人都会,便于理解修改,而jekyll用的是ruby,出点问题怎么办想改都找不到地方。。 >注:后面果然印证了这句话,从css改到js,甚至包括connect插件的bug,要不是会javascript,早就吊死了……

2.默认支持分页分类和标签,而jekyll不友好(听说的)


静态博客站有什么好处?

全静态文件,性能高,同时没代码也就意味没漏洞,所以才有平台愿意免费托管吧?

当然这并不是说回到了web上古时代,真的要一个页面一个页面地去敲每一行html代码,所谓的静态文件实际是自动构建生成的,用于发布到线上。线下编辑生成仍然充斥着大量的模板变量替换过程,相当于把本该由web程序做的动态转换变成了离线生成。

简单来看一篇文章生成过程就是:

  1. 新建一个文件,使用markdown语法书写内容,同时在头部元数据区指定它所用到的html模板及相关参数
  2. 工具自动将该文件转化成最终html页面,这过程中包含加载模板、变量替换、markdown解析转换
  3. 除了文章页之外,还会提取分类标签等参数生成其它的索引页面

那么就有一个问题,线上页面全是静态的,如果需要评论之类的交互功能怎么办呢?目前只能是通过嵌入第三方评论系统来解决。其它类似需求也一样,思路就是“我只做静态的,动态的交给别人”,当然这也只适用于评论这类不重要的数据,如果做交易下单之类的操作就很难实现了,那还是用回php吧。

jekyll碰到的问题

  • ruby安装。在win10上可以直接用ubuntu子系统,linux下安装使用命令行工具方便得多,ruby也有一个rvm管理脚本,类似nodejs的nvm。
  • gem包通过代理安装,不像其它工具可以通过http-proxy/https-proxy环境变量来指定代理,它需要指定--http-proxy=<URL>参数来配置。
  • jekyll的发布。如果是自己搭服务器,那么必然先build,生成最终的静态文件目录,这个过程中包含把所用主题theme的相关文件复制、替换处理,最后上传最终的目录到web服务器。但是因为github-pages内置了对jekyll的支持,所以我们甚至不需要自己build,只要把源文件提交,github就会自己在后台跑jekyll build,并将生成的静态文件发布到对应url也就是<username>.github.io。
  • jekyll的主题theme。常规的用法,主题都是通过gem安装,与一般的gem包无异,在本地build的时候,会从gem的包目录

hexo碰到的问题

  1. 因为是nodejs写的,环境配置方面就比jekyll省事多了。但是因为非github-pages支持的框架,我们必须手动build(通过hexo generate)后再发布(通过hexo deploy),其中发布有好几种方式如git、rsync、sftp等。
  2. 关于主题theme:一般去网上找一个别人写好的主题(比如这个主题yilla),用git subtree的方式添进来放到themes目录下,这样自己可以按需要调整,也可以随时获取更新(虽然我拉下来就再没更新过)。

2018.7.4补充

有时某个文章里用到一些素材,如js文件,按规矩也会放到source/_posts/下,但js文件竟会被hexo默认也当作一篇文章来发布,这显然非我所愿。解决办法是去配置文件_config.yml里添加:

1
2
skip_render:
- '**/*.js'

注意,加完后即使重启hexo server也没效,还得先hexo clean一下!

2018.7.30补充

** 添加gitment功能: **
按照教程流程走一遍,基本都顺利,但最后初始化评论的时候会报Error: Validation Failed错误,这是issue的id长度超限了,默认使用title做id,中文title很容易超限,改成使用创建时间做id就行了。修改layout/_partial/post/gitment.ejs里相应字段就好。然后,浏览器缓存要清空一下,不然导致一直失败,其实已经创建了多个issues…… 感谢LittleQ指出。
另外,这个功能只能在正式服务器上测,在本地是测不了的,因为创建程序时填的回调地址是正式服地址,如果登录后跳转的不是正式服就登录不了。

2018.8.15补充

** 使用browsersync插件实时预览 **
插件是个好插件,装好后,这边md文件一保存,那边网页就会自动刷新了,跟webpack live load效果差不多。
但是这插件用到的第三方库却有个bug,导致太长的中文网页会出错,很明显这一定就是编码错误了。
跟踪调试了半天,找到定位如下:

1
2
3
4
5
6
7
8
9
10
11
--- connect-injector.js 2016-06-04 13:31:30.000000000 +0800
+++ connect-injector2.js 2018-08-15 10:11:28.147725400 +0800
@@ -89,7 +89,7 @@
this._interceptBuffer = new WritableStream();
}

- return this._interceptBuffer.write(chunk, encoding);
+ return this._interceptBuffer.write(new Buffer(chunk, encoding||'utf8'));
}

return this._super.apply(this, arguments);

当我跟踪到这里时,发现encoding为空,实际上应该为utf8;但是即使为空,默认也应该按utf8处理。然而从结果来看并不是,所以非ascii长字符串被截断了。把它改成显式用utf8就好了。

2019.3.31补充

又到了主题调整时间,起因是gitment插件出问题了,因为其自己做了一个接口页面来搞登录验证(github issue),结果它这个页面的https域名证书过期,导致脚本里对它的访问报错……

[object ProgressEvent]
gh-oauth.imsun.net链接不上

但是现在一看主题代码,有点完全摸不着头绪,竟不知道各目录文件为何用?
只好再次硬着头皮翻阅一遍,整理一份理解如下,以免下次要改又忘了:

  1. hexo g的作用将source/_post下的数据与theme下的外观合并渲染,得到public目录,也就是最终要发布的静态html站
  2. theme下的外观即layout目录,里面都是ejs文件,即hexo所用nodejs引擎的渲染模板文件,其内
    <% %>来引用数据,
    <%- js(xxx) %>来引用source目录下的js文件
    <%- css(xxx) %>来引用source目录下的css/styl文件
  3. theme下的source目录是控制样式和脚本的大头,它本身又可以是一个webpack工程的输出
  4. 所以从头到尾的生产流程是:
    source-src -> source, 这是webpack编译结果
    (layout+source)+(data) -> public, 这是hexo(ejs)编译的结果
  5. 一般来说改页面布局: 先从layout/layout.ejs开始,它里面各种partical/include,根据页面类型找到具体对应的ejs文件,这里面可以改html标记;
  6. 如果改html还不满足,要改js:首先通过ejs分析要改的js函数名,去source-src找到这个函数修改后,运行webpack,自动更新source里的文件;切记不要直接改source(通常是紧凑化的js文件一般也没法看和改了)。

好了回到正题,记录这次gitment出错的改法:

  1. 首先通过全文搜索gitment这个关键字,找到调用此功能的代码在yilla/layout/_partial/post/gitment.ejs里
  2. 它直接引用了imsun.github.io下的js文件来实现此功能,点进这个文件里去看,果然找到了对过期域名的访问代码
  3. 但是它这个文件本身也已经是webpack输出的合并文件了没法修改,难道要把它的源码拉下来自己改自己编?那就太麻烦了,也许直接拉下这个文件把那一句代码替换掉然后塞进自己的网站里作内部引用就行了,但总归有点硬来,也许有问题的地方并不只这一句呢?需要找找其它人是否已经有改好的版本。
  4. 果然找到了:https://github.com/imsun/gitment/issues/175#issuecomment-473955148,在此表示感谢!
  5. 所以,最终只要把gitment.ejs里的link和script引用换成上贴中给出的新地址即可。hexo g && hexo d发布搞定!