Hexo 基本设置
blog
本文字数:4.6k 字 | 阅读时长 ≈ 19 min

Hexo 基本设置

blog
本文字数:4.6k 字 | 阅读时长 ≈ 19 min

1. Hexo 基本命令

  1. 初始化 hexo 文件:在本地任意创建一个文件夹(这里创建名字为 hexo-blog 的文件夹),用下面命令将其初始化
hexo init hexo-blog
cd hexo-blog
npm install
  1. 创建文章: 使用下面命令创建一篇文章,当 title 里面包含一些特殊字符时,我们可以加上双引号
hexo new post <title>
hexo new post "<title>"
  1. 生成静态文件: 生成静态的 html 文件等,方便查看和部署
hexo generate
hexo g
  1. 启动本地服务器: 启动本地服务器,查看生成的网页
# 默认网址: http://localhost:4000/
hexo server
hexo s #  简写
hexo s -p 5000  # 指定端口
  1. 部署网站: 将本地生成的网页部署到服务器端
hexo deploy
hexo g -d # 可以结合g一起使用,即生成静态网页后直接部署
  1. 清除缓存: 清除缓存文件(db.json)和已生成的静态文件(public),在某些情况下(例如更换主题后),如果对网站做操作网站没反应,可以使用此命令
hexo clean

2. Hexo 的基本逻辑

执行完 hexo init <folder> 命令之后,我们的文件夹如下所示

|-- _config.yml # 配置信息,可以在这里配置网站的大多数参数
|-- package.json # 查看hexo的版本以及相关依赖包的版本信息
|-- scaffolds # 模板文件夹,新建文章时,会根据这里的模板生成文件
|-- source # 资源文件夹
|   |-- _drafts # 草稿文件夹
|   |-- _posts # 文章文件夹
|-- themes # 主题文件夹,根据主题来生成静态页面

其中 source 是资源文件夹,用于存放用户资源,例如图片,文章等等,每次编译时,_post 文件夹下中的 md 文件会被编译为 html 文件并放到 public 文件夹下,其余非下划线开头的文件和文件夹会被原封不动的复制到 public 文件夹下

Hexo 生成静态文件

如上面所述,source 是资源文件夹,public 是自动生成的静态文件夹,在执行 hexo generate 后,会将 source 中的 md 文件转化为 html 文件,再结合主题渲染成为我们最终看到的博客。

执行 hexo clean 后会删除 db.json 和 public 文件夹下的所有文件

3. 一些问题

3.1 hexo s 卡在 “Start processing” 不动

hexo s 一直卡住

INFO  Validating config
INFO  Start processing
# 然后没再出现 “Hexo is running at http://...” 之类的输出
Error: ENOSPC: System limit for number of file watchers reached, watch '/blog/hexo-blog/source/_posts/...'
    at FSWatcher.<computed> ...
    ...

不是磁盘满了,而是:Node / chokidar 想继续 watch 文件,系统的 ·inotify watcher· 上限(fs.inotify.max_user_watches)用光了

原因:hexo s时,会启动一个本地 Web 服务器监听项目目录中的文件变化,只要文件有改变,Hexo 会重新生成相关页面并通过 hexo-server 触发刷新。如果项目里放了大量图片 / 数据集 / Git 仓库,这些都被 chokidar watch 了,触发 Linux 上 inotify watcher 数量上限 —— 就会出现 ENOSPC。

解决

  1. 从使用方式上规避:
    在 VPS 上用静态模式 hexo s -s 或 Nginx 托管,不用 watch 功能,这个方案有个缺点,如果你更改本地文件,网页是不会更新的

  2. 从系统层面扩容:
    提高 fs.inotify.max_user_watches,让系统能 watch 更多文件。

    cat /proc/sys/fs/inotify/max_user_watches
    echo "fs.inotify.max_user_watches=524288" >> /etc/sysctl.conf
    # 让配置生效
    sysctl -p
    
  3. 从配置层面精细控制监听:
    在 _config.yml 中添加 watch_ignore,因为有很多文件是不需要被监听的,如果你只需要查看文章修改情况,只监听文章内容 _posts,忽略主题、node_modules、Git 仓库等。

    # 监听配置:只监听文章,不监听主题 / 大文件目录 / Git 仓库
    watch_ignore:
        # 依赖、生成输出
        - 'node_modules/**/*'
        - 'public/**/*'
    
        # 主题目录(不希望每次改主题都触发重建,可按需删掉)
        - 'themes/**/*'
    
        # Git 相关目录
        - '.git/**/*'
        - '.github/**/*'
        - '.deploy_git/**/*'
        - '.deploy.git/**/*'
        - 'blog.git/**/*'
    
        # 大型静态资源(按需调整)
        - 'source/images/**/*'
        - 'source/assets/**/*'
    
        # 大数据目录(按实际情况补充)
        - 'source/**/testing_data_final/**/*'
        - 'source/**/datasets/**/*'
        - 'fail/**/*'
    

1. 更换主题

配置完 hexo 之后,我们可以自由更换主题,有很多主题的选择,官网主题,本博客使用的是hexo-theme-pure主题

安装主题,运行下面命令,pure 主题将被安装在 themes 文件夹下

git clone https://github.com/cofess/hexo-theme-pure.git themes/pure

启动 pure 主题,打开 hexo-blog 的 _config.yml 文件进行配置 theme:next,运行下面命令验证主题是否被启用

hexo g -d
hexo s

2. 使用数学公式

Hexo 的数学公式需要使用第三方库来渲染

  1. 使用 Kramed 代替 Marked
    hexo 默认的渲染引擎是 marked,但是 marked 不支持 mathjax。kramed 是在 marked 的基础上进行修改。我们在工程目录下执行以下命令来安装 kramed
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save

然后修改 ./node_modules/hexo-renderer-kramed/lib/renderer.js 函数的 return 部分如下

// Change inline math rule
function formatText(text) {
  // Fit kramed's rule: $$ + \1 + $$
  // return text.replace(/`\$(.*?)\$`/g, '$$$$$1$$$$');
  return text;
}
  1. 停用hexo-math
npm uninstall hexo-math --save  # 停用hexo-math
npm install hexo-renderer-mathjax --save  # 安装hexo-renderer-mathjax包
  1. 更新Mathjax的CDN链接
    修改./node_modules/hexo-renderer-mathjax/mathjax.html最后一行的<script>标签的src属性
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
  1. 更改默认转义规则
    因为Hexo默认的转义规则会将一些字符进行转义,比如_转为<em>,所以我们需要对默认的规则进行修改,文件路径为``./node_modules/kramed/lib/rules/inline.js`
# 第11行(上为原文,下为修改)
escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,
escape: /^\\([`*\[\]()# +\-.!_>])/,

# 第20行(上为原文,下为修改)
em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
  1. 开启 Mathjax
    在站点配置文件 _config.yml 中开启 Mathjax,在文件末尾添加如下代码
mathjax:
    enable: true

在博客中开启 Mathjax,添加以下内容

---
title: xxx
category: xxx
date: 2020-10-14 21:24:15
mathjax: true
---

可修改 ./scaffolds/post.md 模板文件,在 Front-matter 中添加 Mathjax:mathjax: true

  1. 重新生成网页即可
hexo clean
hexo g -d

3. 修改代码字体

修改文件位置为 ./themes/pure/source/css/style.css

3.1 行内代码

在代码的 5544 行 code 修改 color 和 background

code {
  text-shadow: 0 1px #fff;
  padding: 0.2em 0.4em;
  margin: 0 0.3em;
  color: #FF4500;
  /* 行内代码颜色及背景 */
  background: #F0FFFF;
  border-radius: 3px;
  font-size: 90%;
}

我之前试了很多次,以为操作不对,此时把 chrome 的缓存清空,然后重启就好了。。。

3.2 行间代码

在代码的 150 行 samp 添加 consolas 字体

samp {
  font-family: consolas,monospace;
  font-size: 1em;
}

3.3 行间代码背景颜色

在代码的 highlight 修改背景颜色 background 和字体颜色 color,自定义即可

.highlight {
  background: #e6e6fa;
  margin: 10px 0;
  padding: 15px 10px;
  overflow: auto;
  font-size: 13px;
  color: #000000;
  line-height: 1.5;
}

4. 图片居中

修改文件位置为 ./themes/pure/source/css/style.css
在代码的 125 行 img 处修改为

img {
  border: 0;
  box-sizing: border-box;
  margin: auto;
  padding: 3px;
  text-align: center;
  display: block;
}

5. 图片点击放大

主题配置文件 ``./themes/pure/_config.yml自带了一个选项fancybox: false,其默认是关闭的,打开之后即可实现**点击图片查看大图**的功能。然而,打开之后,在我们不需要的地方也会这样,比如,**友情链接**板块,fancybox: true 时点击头像并没有跳转,而是当做图片打开,并且也并没有打开图片。因为图片(头像)对应的超链接是**小伙伴个人主页**,头像本身的链接是**图床上的图片**。 所以要修改源码:./themes/pure/layout/_partial/archive-link.ejs`。

其核心部分为 for (var link in site.data.links) {}这个循环,获取每一个友链 name,对应的 item 为每个友链的三个值 item.link、item.avatar、item.desc,分别渲染。

修改完成后的 archive-link.ejs 文件为如下内容

<article class="article article-links article-type-list" itemscope="">
  <header class="article-header">
    <h1 itemprop="title"><%= page.title %></h1>
    <p class="text-muted">
      <%= __('page.links-desc') %>
    </p>
  </header>
  <div class="article-body">
    <div class="row">
      <% for (var name in site.data.links) { %>
        <% var item = site.data.links[name]; %>
          <div class="col-sm-6 col-md-4">
            <div class="panel panel-default hover-shadow hover-grow">
              <figure class="media media-middle">
                <div class="media-left pr-no">
                  <a href="<%= item.avatar %>" target="_blank" class="img-burn thumb-md media-middle">
                    <img src="<%= item.avatar %>" class="w-full" alt="<%= item.desc %>">
                  </a>
                </div>
                <div class="media-body p-0x">
                  <h4 class="media-heading"><a href="<%= item.link %>" target="_blank">
                    <span style="color:#9932CC" title="点击跳转"><%= name %></span></a>
                  </h4>
                  <div class="text-muted">
                    <%= item.desc %>
                  </div>
                </div>
              </figure>
            </div>
          </div>
          <% } %>      
    </div>
  </div>
</article>
<% if (theme.comment.type && !is_home()) { %>
  <%- partial('_partial/post/comment', {post: page}) %>
<% } %>

6. 文章置顶

  1. 安装相关插件
npm uninstall hexo-generator-index --save
npm install hexo-generator-index-pin-top --save
  1. 修改标题文件:在安装了上述插件之后就已经可以实现文章置顶功能了,但是即使文章位于顶部,如果没有置顶标志的话会比较奇怪。
    找到对应的文件是 ./themes/pure/layout/_partial/post/title.ejs,在 <h1 itemprop="name"> 后添加判断:如果设置了置顶,则显示一个 📌置顶 (也可以选择其他图标),修改后的内容如下
<% if (post.link){ %>
  <h1 itemprop="name">
    <a class="<%= class_name %>" href="<%- url_for(post.link) %>" target="_blank" itemprop="url"><%= post.title %></a>
  </h1>
<% } else if (post.title){ %>
  <% if (index){ %>
    <h1 itemprop="name">
      <% if (post.top) { %>
        <span class="<%= class_name %>" style="color:#7D26CD">📌置顶</span>
      <% } %>
      <a class="<%= class_name %>" href="<%- url_for(post.path) %>"><%= post.title %></a>
    </h1>
  <% } else { %>
    <h1 class="<%= class_name %>" itemprop="name">
      <%= post.title %>
    </h1>
  <% } %>
<% } %>
  1. 使用置顶:在需要被置顶的文章 Front-matter 中添加 top: true 或 top: 999 即可,置顶排序规则为:数值越大越靠上(相同则按时间)。

7. 自定义文章目录

toc: true

8. 设置 https 访问

我是在 aliyun 上申请的证书,这里根据aliyun-ssl链接按照要求申请即可,下面截图是我已经申请好并且经过验证的证书界面了

点击下载,因为我是在 nginx 上部署的网站,所以这里下载 nginx 版本的,在服务器 /etc/nginx 目录下创建新的文件夹 cert 并将压缩包在里面解压,此时多了以 .key 和 .pem 为拓展名的两个文件,此时在 /etc/nginx/conf.d 文件夹下新建一个 wangyh.conf 文件,将下面内容 copy 进去

server {
     #HTTPS的默认访问端口443。
     #如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。
     listen 443 ssl;
     server_name wangyh.co;  #填写证书绑定的域名
 
     ssl_certificate /etc/nginx/cert/wangyh.pem;  #填写证书文件绝对路径
     ssl_certificate_key /etc/nginx/cert/wangyh.key;  #填写证书私钥文件绝对路径

     ssl_session_cache shared:SSL:1m;
     ssl_session_timeout 5m;
	 
     #自定义设置使用的TLS协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
     #TLS协议版本越高,HTTPS通信的安全性越高,但是相较于低版本TLS协议,高版本TLS协议对浏览器的兼容性较差。
     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
     ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
     
     ssl_prefer_server_ciphers on;  # 表示优先使用服务端加密套件。默认开启
 
     location / {
            root /blog/HexoBlog;
            index index.html index.htm;
    }
}

上面只是一个参考,具体的根据自己实际情况修改即可,然后检查下语法,重启 nginx 即可,此时输入 https://wangyh.co 就可以访问了

(base) root@iZuf67mlx4ftb5vohxeobnZ:/etc/nginx# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
(base) root@iZuf67mlx4ftb5vohxeobnZ:/etc/nginx# service nginx restart

遇到的各种问题

  1. 加载网页过慢:看看浏览器是否设置了代理,设置了代理的话记得去掉
  2. 网页加载不出来:检查一下防火墙是否打开了 443 和 80 端口,没打开的话记得打开
  3. 配置文件不生效:这里修改的是 conf.d 下面的文件,也可以修改 sites-available 和 sites-enabled 下面的文件,conf.d 是全局的,生效的话要求里面的子文件都以 .conf 结尾,sites-available 里面的文件不要求命名,为了模块化管理,他是不生效的,需要软连接到 sites-enabled 才能生效,也就是说,可以直接修改 conf.d 和 sites-enabled 里面的文件(创建新的或者修改旧的),我之前修改的是 sites-available,所以就一直不生效

如果不想用 aliyun 的证书怎么办?aliyun 的免费证书要 3 个月更新一次,每次都要重新下载在 copy 到服务器上,非常麻烦,这里我们用 Let's Encrypt 来申请,非常方便,并且可以自动更新

1. 安装 acme.sh 和必要工具

apt install socat -y
curl https://get.acme.sh | sh

2. 注册账号 (Let’s Encrypt)

# 切换 CA 机构为 Let's Encrypt (兼容性好)
/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt
# 注册账号 (替换成你的邮箱,即便填错了也不影响申请)
/root/.acme.sh/acme.sh --register-account -m your_email

3. 申请证书

# 利用 Nginx 自动验证 (推荐,无需停止服务) 如果你的 Nginx 配置标准,acme.sh 可以自动读取配置验证。
/root/.acme.sh/acme.sh --issue -d wangyh.co --nginx

4. 安装证书到指定位置 (关键步骤)

假设我们安装到 /etc/nginx/cert 文件夹中

mkdir -p /etc/nginx/cert
# 解释: --reloadcmd 的作用是,以后证书自动续期后,acme.sh 会自动帮你重启 Nginx,让你无需手动干预。
/root/.acme.sh/acme.sh --install-cert -d wangyh.co --ecc \
                       --key-file /etc/nginx/cert/wangyh.co.key  \
                       --fullchain-file /etc/nginx/cert/wangyh.co.pem \
                       --reloadcmd "systemctl force-reload nginx"

执行完上述步骤后,你可以输入以下命令查看证书信息,你应该能看到 wangyh.co 在列表中。并且你的目录中文件时间戳已经更新

/root/.acme.sh/acme.sh --list
ls -l /etc/nginx/cert/

如果你只是申请了证书(在 /root/.acme.sh/wangyh.co/ 目录下),但没有通过 --install-cert 命令将其“同步”到 Nginx 的目录,那么 Nginx 永远用的是旧文件。如上配置后,acme.sh 会每 60 天自动检测并更新这两个文件。如果还不好的话,可以先手动执行一下 systemctl reload nginx,避免上面没重启

9. 添加搜索引擎收录

9.1 添加 Google 收录

  1. 登陆 Google Search 网站:https://search.google.com/search-console/welcome,这里需要登陆 Google 账号,没有账号的自己创建一个
  2. 添加网址前缀:添加自己的网址前缀,如下图所示,这里我的网址是 https://wangyh.co,所以就如实填写即可
3. **验证所有权**:需要将 Google 提供的元标记粘贴至网页 `` 部分。对于 Hexo 博客而言,可以将其添加到 `./themes/pure/layout/_common/head.ejs` 中,可以使每个页面都能被收录而不仅是首页(也就是说每篇文章均有 google verification 的印记) ```css <% if (theme.douban.user && page.layout === 'books') { %> <% } %> ``` 验证成功后的图如下所示

注意:有多种验证方式可以采用,可以添加多种验证方法,从而避免验证状态丢失,验证成功后的网页如下所示

9.2 添加 Baidu 收录

  1. 登陆 Baidu Search 网站:https://ziyuan.baidu.com/,点击 搜索服务 ,然后添加自己的网站,输入 https://wangyh.co
2. **网站验证**:根据 Google 的经验进行验证,需要将 Baidu 提供的元标记粘贴至网页 `` 部分。对于 Hexo 博客而言,可以将其添加到 `./themes/pure/layout/_common/head.ejs` 中,可以使每个页面都能被收录而不仅是首页(也就是说每篇文章均有 baidu verification 的印记) ```css <% if (theme.douban.user && page.layout === 'books') { %> <% } %> ```
3. **网站验证成功**:如下显示时,就已经验证成功
4. **资源提交**:

6. 自定义左下角信息

Pure 主题的左下角原本为 Theme by cofess base on pure。这里考虑加入站点访问量和访客数,至于文章阅读量可以通过 LeanCloud 并且已经实现。文件位置:./themes/pure/layout/_common/footer.ejs。

7. 站点信息

此部分只需要关注网站 logo 头像 favicon 的图片路径,将需要使用的 logo 图片放在 ./themes/pure/source/favicon.png,然后设置为 favicon: /favicon.png 即可。
站点公告可用 HTML 格式,例如 <br> 换行、<a href="xxx" styly="xxx"> 标签等进行配置。

Sep 30, 2021