hexo搭建next博客

引言

此博客用于搭建 hexo 的工具博客.基本不会探索深究配置的原因,敬请知悉~

hexo 安装

步骤

首先要用 npm 依赖资源管理工具安装全局命令 hexo-cli.

npm install hexo-cli -g

然后使用 hexo 初始化博客目录,比如 blog 目录,目录名要与后续个人建立的 github 上 hexo 托管代码的 repository 同名.

hexo init blog

接着 github 建库.

建立一个以 white-than-wood(我的用户名).github.io 结尾的 repository ,作为 hexo 托管代码的库, github 默认 .github.io 结尾作为用户的网站二级域名,建立一个新的分支作为创作分支(因为主分支是用来发布呈现网站的).

之后,进入生成的 blog 文件夹,与远程 github repository 建立关联,并同步远程最新资源.

git remote add origin git@github.com:white-than-wood/white-than-wood.github.io.git
git pull

再 npm 下载外部依赖包.

npm i/npm install

或者使用 yarn 下载外部依赖包.

yarn

最后启动 hexo 自身搭建的服务,生成本地的博客网站,默认端口在本地 ip 地址下的 4000 端口,假如你不想启动在 4000 端口,也可使用-p 其他端口号进行配置,比如-p 9977.

hexo server
hexo server -p 9977

PS: 最好先将本地代码上传至远程之后,再执行 hexo 配置.

git add .
git commit 'build:搭建hexo个人Github Page博客'
git push --set-upstream origin master

默认的主题风格 theme 是 landscape ,假如你想更换,可以通过https://hexo.io/themes进行筛选,筛选之后进行配置,主题配置见下文.

hexo 命令

示例

首先建立一篇名为 ‘hexo搭建next博客’ 的博客.

hexo new hexo搭建next博客

在根目录 -> source 目录底下的 _post 目录下找到名为 hexo 配置的博客文件,在里面用 markdown 进行记录个人的博客,当然可以在 hexo server 自带的服务器运行监听的情况下,进行添加和修改个人的博客.之后,进行生成静态文件.

hexo generate

生成静态文件之后,进行部署.

hexo deploy

生成静态文件和部署也可以使用一句命令执行.

hexo generate -deploy
hexo deploy -generate

为了防止存在静态文件和缓存,造成没有重新渲染页面的问题,在每一次部署之前,要运行一下清理静态文件和缓存的命令.

hexo clean
hexo generate
hexo deploy

hexo deploy 部署之后,根据项目根目录底下 _config.yml 配置文件的 deploy 配置,会提交到远程 github repository 库.

hexo 配置

PS: 以下所说的”根目录”指的就是当前创作的 repository 目录,”主题目录”就是根目录下/themes目录下的主题环境.

hexo deploy 发布配置

发布部署可以部署至 Github Page 个人网站,也可以部署至个人申请购买的云服务器中.

部署至 Github Page 个人网站.

步骤

要想部署到 Github Page 个人网站,首先要下载 hexo-git 插件.

npm install hexo-deployer-git --save

然后就要在个人的本地hexo博客的项目里面,更改根目录底下的 _config.yml 文件,全局搜索 git ,更改 deploy 发布配置,将 source 目录下面的内容进行构建发布到 repo github 地址的分支上.

deploy:
    type: git
    #你的个人网站 github 库的链接地址,最好使用 git@ 开头的, https@ 开头的会报错
    repo: git@github.com:dreamthen/dreamthen.github.io.git
    #分支名
    branch: master

部署至个人申请购买的云服务器.

步骤

将生成的网站博客项目直接通过 Royal TSX 远程链接管理工具放到云服务器中,链接成功后,下载 nginx 代理.

#我这里直接使用阿里云CentOS服务器中默认的基于RPM的软件包管理器yum来下载nginx
yum install nginx

下载之后查看全局命令 nginx 是否存在,查看 nginx 的版本.

nginx -v

如果全局命令不存在 nginx,则运行 source ~/.bash_profile,使得配置在修改了环境变量的情况下进行重置.

source ~/.bash_profile

启动 nginx.

nginx
  • 顺便提一下 nginx 的其他命令.重启 nginx.

    nginx -s reload
    
  • 停止 nginx.

    nginx -s stop
    
  • 通过流(pipe)查询全部用户组 nginx 完整的进程状态.

    ps -ef | grep nginx
    
  • 强制杀掉 nginx 进程.

    #28009是 nginx 进程号,通过 ps -ef | grep nginx 可以查询到
    kill -9 28009
    

配置 nginx,将服务器代理 root 页面指向我们的网站博客项目.

#通过测试 nginx,查询 nginx 配置文件所在目录
nginx -t
vim /etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#...
server {
listen 80 default_server;
listen [::]:80 default_server;
#域名配置,需要申请购买备案(国内域名需要备案,国外域名则不需要)
server_name _;
#修改root页面向我们的网站博客项目
root /usr/share/nginx/html;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
}

error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
#...

hexo theme 主题配置

示例

筛选好个人选中的主题之后,就需要在项目里面进行配置更换。首先需要下载远程 github 库里面的主题目录到项目根目录里面的 themes 文件夹底下,比如本人用的是 next 主题的 hexo.

git clone https://github.com/iissnan/hexo-theme-next.git themes/next

随后更改根目录里面的 _config.yml 文件,全局搜索 theme ,更改 theme 配置.

theme: next

接着选择主题展示的方式,需要在主题的项目目录下,更改 _config.yml 文件,全局搜索 Scheme ,更改 Scheme 配置,比如 next 主题底下的 Scheme 配置.

scheme:
    #scheme: Muse
    #scheme: Mist
    scheme: Pisces
    #scheme: Gemini

hexo language语言配置

步骤

每个主题的语言都是根据作者的母语来配置的,要想配置开发者个人国家的语言,还是更改项目根目录底下的 _config.yml 文件,全局搜索 language ,更改 language 配置.

language: zh-CN

再更改主题目录底下的 _config.yml 文件,全局搜索 language ,更改 language 配置.

language: zh-CN    

hexo page页面配置

步骤

hexo提供了几个可供筛选的页面,常用的有这么几个:home(首页)、tags(标签)、about(关于我)、archives(档案)和categories(分类),首先要创建页面.

hexo new page tags
hexo new page about
hexo new page archives
hexo new page categories

接着在主题目录下,更改 _config.yml 文件,全局搜索 menu ,更改 menu 配置,当然每个主题的配置不尽相同.

menu:
    home: / || fa fa-home
    about: /about/ || fa fa-user
    tags: /tags/ || fa fa-tags
    categories: /categories/ || fa fa-th
    archives: /archives/ || fa fa-archive

随后更改 source 目录底下创建的页面配置,以 tags 为例.

----------------------------
    title: about
    date: 2018-04-24 17:57:26
    type: "tags"
    comments: false
----------------------------

hexo avatar 头像配置

步骤

配置个人博客网站的头像,需要更改主题目录底下的 _config.yml 文件,添加 avatar 配置.

#头像url链接
avatar: https://avatars.githubusercontent.com/u/11425476?v=4

hexo search 全站搜索配置

步骤

假如想要配置hexo个人博客网站的全站搜索配置,首先要下载 hexo search 外部依赖包.

npm install hexo-generator-search --save
npm install hexo-generator-searchdb --save

更改根目录底下的 _config.yml 文件,添加 search 配置.

search:
    path: search.xml
    field: post
    format: html
    limit: 10000

开启主题目录底下的 _config.yml 文件中的 local_search 配置.

local_search:
    enable: true        

hexo new_post_name配置

步骤

假如想要更改每一篇博客的文件名称,不再是默认的:title.md的文件名,需要更改根目录底下的 _config.yml 文件,更改 new_post_name 配置.

new_post_name: :year-:month-:day-:title.md

hexo auto_excerpt阅读全文配置

步骤

博客文章一般都会很长的,所以在首页要对博客进行超长省略,要想看所有的内容,点击阅读全文或者文章标题进入全文查看.在 hexo-theme-next 主题版本7.6之前需要更改主题目录底下的 _config.yml 文件,全局搜索 auto_excerpt ,更改 auto_excerpt 配置.

auto_excerpt:
    enable: true
    length: 200

在 hexo-theme-next 主题版本7.6之后,由于 auto_excerpt 这种超长省略不应该是主题插件应该做的,作者将此配置移除,并给出新的专门针对此配置的插件 hexo-excerpt.

excerpt:
    #显示的 markdown 代码块层数
    depth: 5
    excerpt_excludes: []
    more_excludes: []
    #设置为true: 显示超长省略,只展示部分,隐藏全文
    #设置为false: 展示全文
    hideWholePostExcerpts: true
    excerpt_description: true
    #是否显示阅读全文按钮
    read_more_btn: true

hexo browsersync开发环境创作自动更新配置

步骤

在创作博客时,需要每次手动刷新页面才能看到修改后的结果,感觉非常没有效率,如果存在类hrm热加载这种插件就太爽了! hexo-browsersync 可以直接解决这个问题.

此插件原理基于 browser-sync ,与 hexo 建立关联,当创作的文件内容发生改变时, browser-sync 就会监听到并刷新浏览器整个页面的内容,做到不需手动刷新,大大提高了创作效率.

#更改根目录底下的 _config.yml 文件,添加 browsersync 属性
#设置监听 watch 属性为 true 就可以了!
browsersync:
    watch: true
    logLevel: "warn"

hexo busuanzi_count卜算子统计配置

步骤

上线之后,需要对个人博客进行管理,阅读人数以及次数对于创作者来说是很重要反馈点.统计配置需要更改主题目录底下的 _config.yml 文件,配置 busuanzi_count 卜算子统计.

#可配置查看个人博客的阅读人数、次数以及每篇博客文章的次数
busuanzi_count:
    enable: true
    total_visitors: true
    total_visitors_icon: fa fa-user
    total_views: true
    total_views_icon: fa fa-eye
    post_views: true
    post_views_icon: fa fa-eye

hexo baidu_analytics百度统计配置

步骤

卜算子统计有时候会出现一些异常,比如pv莫名会加100,uv不再区分单个ip.为了追求更精确、更智能,我们采用百度统计. 统计配置需要更改主题目录底下的 _config.yml 文件,配置 baidu_analytics 百度统计.

根据百度统计-使用配置-代码获取,将hm.js后方自动生成的id配置至baidu_analytics.

# Baidu Analytics
# See: https://tongji.baidu.com
baidu_analytics: 31f07c2ec89d10385ec28e8eea5bbc3a

hexo Gitalk留言板配置

步骤

留言板 comments 是创作者与阅读者进行互动反馈的窗口,可以使阅读者与创作者共同进步.对于 hexo 来说,支持的留言板模式有很多种: ‘disqus | disqusjs | changyan | livere | gitalk | utterances’ ,比较常见、用户量比较大且与github关联性比较强的就是 gitalk 以及 disqus,disqusjs 需要’梯子’🐶才能评论,那么还是选用 gitalk .留言板配置需要更改主题目录下的 _config.yml 文件.

配置comments:

# Multiple Comment System Support
comments:
    # Available values: tabs | buttons
    style: tabs
    # Choose a comment system to be displayed by default.
    # Available values: disqus | disqusjs | changyan | livere | gitalk | utterances
    active: gitalk
    # Setting `true` means remembering the comment system selected by the visitor.
    storage: true
    # Lazyload all comment systems.
    lazyload: false
    # Modify texts or order for any naves, here are some examples.
    nav:
        gitalk:
            order: -2
        disqus:
            text: Load Disqus
            order: -1

配置gitalk:

# Gitalk
# For more information: https://gitalk.github.io
gitalk:
    enable: true
    github_id: white-than-wood # GitHub repo owner
    repo: white-than-wood.github.io # Repository name to store issues
    client_id: 1191ab5290535c1acb09 # GitHub Application Client ID
    client_secret: 8d2cbebac1ae1230f84d1f9f7a36f8008a42c14b # GitHub Application Client Secret
    admin_user: white-than-wood # GitHub repo owner and collaborators, only these guys can initialize gitHub issues
    distraction_free_mode: true # Facebook-like distraction free mode
    # When the official proxy is not available, you can change it to your own proxy address
    proxy: https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token
    # proxy: login/oauth/access_token # This is official proxy address
    # Gitalk's display language depends on user's browser or system environment
    # If you want everyone visiting your site to see a uniform language, you can set a force language value
    # Available values: en | es-ES | fr | ru | zh-CN | zh-TW
    language: zh-CN

上面的配置项中有几个需要说明的:

  • client_id 与 client_secret 是 Github 的 OAuth 认证(下一个部分会介绍).
  • github_id 与 admin_user 这里建议填一样,填成个人的 github 账号名(不是邮箱,也不是用户名).
  • proxy 默认即是上面的地址,它其实会回调到这里https://github.com/login/oauth/access_token.
  • 无论是部署至 GitHub Page 个人网站,还是部署至个人申请购买的云服务器,上面三点是必须要实行的,proxy 403 问题主要是在部署至个人申请购买的云服务器中时会遇到,部署至 GitHub Page 个人网站不能进行自定义配置反向代理,所以只能使用 Gitalk 官方搭建的代理.

Github 的 OAuth 认证.

前提是得有一个 github 账号,才能注册 OAuth application ,这是 OAuth 应用注册地址.

PS: 如果有自定义域名(如个人申请的阿里云域名),则在上图中填入自定义域名.

注册之后,点击下图中’Generate a new client secret’按钮,在个人账号下的Settings -> Developer settings -> OAuth Apps下面可以查看 OAuth 认证 client_id 与 client_secret.

Gitalk 自动初始化.

原理: 通过 sitemap 中的信息,请求 github 开放 api 达到自动产生 issues 的目的.
基本的要求: github API 需要请求 token.

  • 申请 github Token.

    我们需要使用 Personal access tokens 方式,这种方式限制每小时5000次,结合缓存功能,基本满足需求.
    从 Github 的 Personal access tokens 页面,点击 Generate new token.

  • 安装 npm 依赖项.

    npm i -D md5 moment request xml-parser
    npm i -S hexo-generator-sitemap
    
  • 配置 sitemap.

    在根目录中创建 sitemap_template.xml.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for post in posts %}
<url>
<loc>{{ post.permalink | uriencode }}</loc>
{% if post.updated %}
<lastmod>{{ post.updated.toISOString() }}</lastmod>
{% elif post.date %}
<lastmod>{{ post.date.toISOString() }}</lastmod>
{% endif %}
<date>{{ post.date }}</date>
<title>{{ post.title + ' | ' + config.title }}</title>
{# nunjucks 模版语法 https://github.com/mozilla/nunjucks #}
<desc>{{ post.description | default(post.excerpt) | default(post.content) | default(config.description) | striptags | truncate(200, true, '') }}</desc>
</url>
{% endfor %}
</urlset>
  • 修改根目录下的 _config.yml.
#Sitemap
sitemap:
    path: sitemap.xml
    template: ./sitemap_template.xml
    rel: false
    tag: true
    category: false
  • 生成 sitemap.xml 文件.
hexo clean && hexo generate
  • 根目录添加 talk-auto-init.js (注意还是不要将此文件置于github中,建议ignore).
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
const fs = require('fs');
const path = require('path');
const url = require('url');

const request = require('request');
const xmlParser = require('xml-parser');
const md5 = require('md5');

// 配置信息
const config = {
username: 'white-than-wood', // GitHub repository 所有者,可以是个人或者组织。对应 Gitalk 配置中的 owner
repo: "white-than-wood.github.io", // 储存评论 issue 的 github 仓库名,仅需要仓库名字即可。对应 Gitalk 配置中的 repo
token: 'ghp_EuXHDkOxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // 前面申请的 personal access token
sitemap: path.join(__dirname, './public/sitemap.xml'), // 个人站点的 sitemap 文件地址
cache: true, // 是否启用缓存,启用缓存会将已经初始化的数据写入配置的 gitalkCacheFile 文件,下一次直接通过缓存文件判断
gitalkCacheFile: path.join(__dirname, './gitalk-init-cache.json'), // 用于保存 gitalk 已经初始化的 id 列表
gitalkErrorFile: path.join(__dirname, './gitalk-init-error.json'), // 用于保存 gitalk 初始化报错的数据
};

const api = 'https://api.github.com/repos/' + config.username + '/' + config.repo + '/issues';

/**
* 读取 sitemap 文件
* 远程 sitemap 文件获取可参考 https://www.npmjs.com/package/sitemapper
*/
const sitemapXmlReader = (file) => {
try {
const data = fs.readFileSync(file, 'utf8');
const sitemap = xmlParser(data);
let ret = [];
sitemap.root.children.forEach(function (url) {
const loc = url.children.find(function (item) {
return item.name === 'loc';
});
if (!loc) {
return false;
}
const title = url.children.find(function (item) {
return item.name === 'title';
});
const desc = url.children.find(function (item) {
return item.name === 'desc';
});
const date = url.children.find(function (item) {
return item.name === 'date';
});
ret.push({
url: loc.content,
title: title.content,
desc: desc.content,
date: date.content,
});
});
return ret;
} catch (e) {
return [];
}
};

// 获取 gitalk 使用的 id
const getGitalkId = ({
url: u,
date
}) => {
const link = url.parse(u);
// 链接不存在,不需要初始化
if (!link || !link.pathname) {
return false;
}
if (!date) {
return false;
}
return md5(link.pathname);
};

/**
* 通过以请求判断是否已经初始化
* @param {string} gitalk 初始化的id
* @return {[boolean, boolean]} 第一个值表示是否出错,第二个值 false 表示没初始化, true 表示已经初始化
*/
const getIsInitByRequest = (id) => {
const options = {
headers: {
'Authorization': 'token ' + config.token,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Accept': 'application/json'
},
url: api + '?labels=' + id + ',Gitalk',
method: 'GET'
};
return new Promise((resolve) => {
request(options, function (err, response, body) {
if (err) {
return resolve([err, false]);
}
if (response.statusCode != 200) {
return resolve([response, false]);
}
const res = JSON.parse(body);
if (res.length > 0) {
return resolve([false, true]);
}
return resolve([false, false]);
});
});
};

/**
* 通过缓存判断是否已经初始化
* @param {string} gitalk 初始化的id
* @return {boolean} false 表示没初始化, true 表示已经初始化
*/
const getIsInitByCache = (() => {
// 判断缓存文件是否存在
let gitalkCache = false;
try {
gitalkCache = require(config.gitalkCacheFile);
} catch (e) {}
return function (id) {
if (!gitalkCache) {
return false;
}
if (gitalkCache.find(({
id: itemId
}) => (itemId === id))) {
return true;
}
return false;
};
})();

// 根据缓存,判断链接是否已经初始化
// 第一个值表示是否出错,第二个值 false 表示没初始化, true 表示已经初始化
const idIsInit = async (id) => {
if (!config.cache) {
return await getIsInitByRequest(id);
}
// 如果通过缓存查询到的数据是未初始化,则再通过请求判断是否已经初始化,防止多次初始化
if (getIsInitByCache(id) === false) {
return await getIsInitByRequest(id);
}
return [false, true];
};

// 初始化
const gitalkInit = ({
url,
id,
title,
desc
}) => {
//创建issue
const reqBody = {
'title': title,
'labels': [id, 'Gitalk'],
'body': url + '\r\n\r\n' + desc
};

const options = {
headers: {
'Authorization': 'token ' + config.token,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
},
url: api,
body: JSON.stringify(reqBody),
method: 'POST'
};
return new Promise((resolve) => {
request(options, function (err, response, body) {
if (err) {
return resolve([err, false]);
}
if (response.statusCode != 201) {
return resolve([response, false]);
}
return resolve([false, true]);
});
});
};


/**
* 写入内容
* @param {string} fileName 文件名
* @param {string} content 内容
*/
const write = async (fileName, content, flag = 'w+') => {
return new Promise((resolve) => {
fs.open(fileName, flag, function (err, fd) {
if (err) {
resolve([err, false]);
return;
}
fs.writeFile(fd, content, function (err) {
if (err) {
resolve([err, false]);
return;
}
fs.close(fd, (err) => {
if (err) {
resolve([err, false]);
return;
}
});
resolve([false, true]);
});
});
});
};

const init = async () => {
const urls = sitemapXmlReader(config.sitemap);
// 报错的数据
const errorData = [];
// 已经初始化的数据
const initializedData = [];
// 成功初始化数据
const successData = [];
for (const item of urls) {
const {
url,
date,
title,
desc
} = item;
const id = getGitalkId({
url,
date
});
if (!id) {
console.log(`id: 生成失败 [ ${id} ] `);
errorData.push({
...item,
info: 'id 生成失败',
});
continue;
}
const [err, res] = await idIsInit(id);
if (err) {
console.log(`Error: 查询评论异常 [ ${title} ] , 信息:`, err || '无');
errorData.push({
...item,
info: '查询评论异常',
});
continue;
}
if (res === true) {
// console.log(`--- Gitalk 已经初始化 --- [ ${title} ] `);
initializedData.push({
id,
url,
title,
});
continue;
}
console.log(`Gitalk 初始化开始... [ ${title} ] `);
const [e, r] = await gitalkInit({
id,
url,
title,
desc
});
if (e || !r) {
console.log(`Error: Gitalk 初始化异常 [ ${title} ] , 信息:`, e || '无');
errorData.push({
...item,
info: '初始化异常',
});
continue;
}
successData.push({
id,
url,
title,
});
console.log(`Gitalk 初始化成功! [ ${title} ] - ${id}`);
continue;
}

console.log(''); // 空输出,用于换行
console.log('--------- 运行结果 ---------');
console.log(''); // 空输出,用于换行

if (errorData.length !== 0) {
console.log(`报错数据: ${errorData.length} 条。参考文件 ${config.gitalkErrorFile}。`);
await write(config.gitalkErrorFile, JSON.stringify(errorData, null, 2));
}

console.log(`本次成功: ${successData.length} 条。`);

// 写入缓存
if (config.cache) {
console.log(`写入缓存: ${(initializedData.length + successData.length)} 条,已初始化 ${initializedData.length} 条,本次成功: ${successData.length} 条。参考文件 ${config.gitalkCacheFile}。`);
await write(config.gitalkCacheFile, JSON.stringify(initializedData.concat(successData), null, 2));
} else {
console.log(`已初始化: ${initializedData.length} 条。`);
}
};

init();
  • 修改 package.json 中 scripts 中的脚本,添加 “gitalk”:”node talk-auto-init.js”.
1
2
3
4
5
6
7
8
9
10
{
"scripts": {
"build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server",
"publish": "git push && hexo clean && hexo generate -deploy",
"gitalk": "node talk-auto-init.js"
}
}
  • 测试 gitalk.
npm run talk
  • 已经缓存过后的结果:
> hexo-site@0.0.0 gitalk
> node talk-auto-init.js


--------- 运行结果 ---------

本次成功: 0 条。
写入缓存: 7 条,已初始化 7 条,本次成功: 0 条。参考文件 /Users/yinwk/keryi/white-than-wood.github.io/gitalk-init-cache.json.

proxy 403错误

部署至个人申请购买的云服务器时,由于跨域问题,会出现 proxy 403 forbidden.解决它主要有这么几个方案.

  • nginx反向代理 解决方案(推荐).

    在云服务器 nginx 的博客配置中加入如下内容(注意个人博客的域名必须经过 https ssl 安全证书备案).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 443 ssl http2;
#...
location = /login/oauth/access_token {
add_header Access-Control-Allow-Origin 'https://white-than-wood.zone/'; //这里改成个人的域名,并删除注释
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass https://github.com/;
}
#...
}

PS: nginx 反向代理之后,要将 proxy 指向代理域名下的链接回调进行修改.

proxy: https://white-than-wood.zone/https://github.com/login/oauth/access_token
  • 自建一个 workers.

    地址: CloudFlare Workers.
    参考文章: 使用 CloudFlare Workers 实现 CORS Anywhere.

  • 使用其他人搭建的代理.

    比如这个 issues 介绍到的:

     proxy: https://shielded-brushlands-08810.herokuapp.com/https://github.com/login/oauth/access_token
    
  • 使用 Gitalk 官方搭建的代理.

    据gitalk issue gitalk 授权登录后报错403,直接将使用 Gitalk 官方搭建的代理就可解决 403 forbidden 的问题,之前 Gitalk 官方搭建的代理由于太多人接入导致被官方限制使用,用户经常发现不能正常使用,现在已经对代理进行优化改进,不会出现限制使用的情况.

     https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token
    
  • 更新 gitalk 版本至1.7.2.

    据gitalk issue gitalk 授权登录后报错403,直接将 gitalk 版本升级至1.7.2就可解决 403 forbidden 的问题.

hexo GitHub Page个人网站自定义域名

部署至 GitHub Page 个人网站配置自定义域名时,需要将个人申请购买的域名(最好是通过 https ssl 安全证书备案)进行域名解析,GitHub Page也需要CNAME配置.

阿里云域名解析.

步骤

域名解析简单来说实际上就是通过配置,可以使用不同的域名访问同一网站.首先进入阿里云服务管理平台,对已经申请购买的域名进行解析.

添加记录或者对某一个列表项进行修改.可以使用 A记录 也可以使用 CNAME.

A记录是将域名指向一个IPV4地址.
CNAME是将域名指向另外一个域名.

这里使用的是 A记录,将 white-than-wood.github.io 的 IP 地址作为记录值.

ping white-than-wood.github.io

主机记录,解析后的域名基本上就两种,‘@’和’www’.

'@' 是源域名(主域名 white-than-wood.zone).
'www' 则是 www.white-than-wood.zone.

GitHub Page个人网站CNAME配置.

在 source 目录下新建 CNAME 文件(不带任何后缀),在文件内写入你的主域名.

1
white-than-wood.zone

或者在 Github Page 个人配置下设置自定义域名,Github 会自动添加 CNAME 文件.

这两种方式我这边是全部使用的.全部搞定之后,就可以通过 white-than-wood.zone 访问 white-than-wood.github.io GitHub Page 个人网站.

延伸

既然已经通过阿里云服务 A记录 或者 CNAME 解析域名,为什么还需要在 GitHub Page 个人网站上配置 CNAME ?

云服务 A记录 或者 CNAME 域名解析至 GitHub Page,通过 white-than-wood.zone 可以访问 GitHub Page 个人网站,那原来的 white-than-wood.github.io 域名怎么办呢? GitHub Page 也通过 CNAME 域名解析至 white-than-wood.zone. 使得 github.io 域名也可以直接访问个人申请购买的域名.

hexo 其他配置

示例

更改根目录底下的 _config.yml 文件,更改网站title(标题)、author(作者)、keywords(关键字)、description(描述)配置,比如本人的配置.

title: WTW's Frontend
author: WTW(比木白)
keywords: hexo,hexo-cli,hexo博客,hexo博客个人网站,hexo blog
subtitle: 道阻且长,行则将至
description: 前端领域内所不知道的都探索于此!

更改主题目录底下的 _config.yml 文件,设置个人的github(github托管代码网址)、google(google个人资料网址)、gmail(gmail邮箱网址)、twitter(twitter个人微博网址)等等,比如本人的配置.

social:
  GitHub: https://github.com/white-than-wood || fab fa-github
  E-Mail: https://dreamthen.00@gmail.com || fab fa-envelope
  Google: https://plus.google.com/u/0/103833130011211353424 || fab fa-google

发布到 GitHub Page 上之后,你会发现 README.md 莫名的消失,主要是因为 hexo 构建发布到远程的目录只是 source 目录,所以只要将 README.md copy 一份放到 source 目录下,并且配置渲染时跳过的 markdown 类型文件就可以了.

#hexo构建渲染时会将source目录下markdown类型文件转译为html,我们不需要将README.md转译,所以直接skip render
#更改根目录底下的_config.yml文件,修改skip_render属性
skip_render: README.md

当创作中图片过小,阅读者无法看清的情况下,放大配置就已然成为必要 .fancybox 配置可以点击使图片放大,并可同时查看全文的图片.更改主题目录下的 _config.yml 文件 fancybox 属性.

# FancyBox is a tool that offers a nice and elegant way to add zooming functionality for images.
# For more information: https://fancyapps.com/fancybox/
fancybox: true