Hexo+Shoka博客搭建和全功能完善

转载文章:Hexo+shoka主题+github/服务器搭建个人博客-CSDN博客

标签:Hexo | Yume Shoka = 優萌初華 = 有夢書架 (lostyu.me)

官方文档:https://hexo.io/zh-cn/docs/

shoka主题:https://shoka.lostyu.me/

我的博客:http://ai.hepingan.top
欢迎来参观,也欢迎加友链~

I、安装

  1. 安装node.js和git
  2. 下载Hexo
  1. 安装node.js和git

首先确定自己的node.js和git是否已经安装了。用一下命令检测,未安装百度一下安装即可。

1
2
3
4
node -v
npm -v
git --version
123
  1. 下载Hexo

看官网:(记得以管理员运行哦)

1
2
npm install -g hexo-cli
hexo -v

II、建站

  1. 初始化项目 hexo init
  2. 启动服务器 hexo server
  1. 初始化项目

先创建一个文件夹,myblog,进入终端

1
2
3
hexo init  #初始化hexo
# 没有提前创建文件夹可以用下面的命令
hexo init myblog

虽然有报错,但是看大概意思是一开始链接失败,后面重置了成功了。新建了hexo项目的文件目录长这样:

img

  1. 启动服务器

    在当前博客目录下运行:

1
2
3
4
npm i # 其实不知道这个是安装什么依赖
npm install hexo-deployer-git --save # 安装插件
hexo server # 启动服务器。默认情况下,访问网址为: http://localhost:4000/

这里可以不用安装依赖和插件,直接启动服务器也是可以的。

启动了服务器了,访问下地址:http://localhost:4000/

长这样,感觉不咋好看。到时候得换成那个少女粉的主题嘻嘻

III、部署到GitHub

  1. 创建个仓库 dabing85.github.io
  2. 安装 hexo-deployer-git 部署插件
  3. 修改_config.yml文件
  4. 代码部署到git并授权
  5. 访问:dabing85.github.io

先部署到github吧,后面等备案了部署到自己的服务器上去嘻嘻。应该就是修改一下配置文件就可以了。

  1. 创建个仓库 dabing85.github.io
  2. 安装 hexo-deployer-git 部署插件

刚刚就安装过了,就是这个命令:

1
npm install hexo-deployer-git --save   # 安装插件
  1. 修改_config.yml文件

部署推荐用ssh密钥的方式快一些。怎么生成公钥,可参考:

配过本机公钥就不用管了。

1
2
3
4
deploy:
type: git
repo: git@github.com:dabing85/dabing85.github.io.git
branch: main
  1. 运行下面几个命令
1
2
3
hexo clean
hexo g # 生成静态文件
hexo d # 部署代码到GitHub上,之后会跳出github授权的框
  1. 访问:dabing85.github.io

Ⅳ、美化博客

  1. 安装需要的依赖插件
  2. 下载主题
  3. 修改/_config.yml 配置切换主题
  4. 重新编译发布 hexo clean & hexo deploy
  5. 访问dabing85.github.io
  6. 修改对应的配置文件

看上这个少女粉的主题了,橙总介绍的:shoka.lostyu.me

文档说明:https://shoka.lostyu.me/computer-science/note/theme-shoka-doc/

基本配置: https://shoka.lostyu.me/computer-science/note/theme-shoka-doc/config/

页面配置: https://shoka.lostyu.me/computer-science/note/theme-shoka-doc/display/

依赖插件: https://shoka.lostyu.me/computer-science/note/theme-shoka-doc/dependents/

为了可视化,我直接用idea打开mybolg在idea的终止执行命令。也可以看看都添加了些什么文件。

1- 依赖插件安装

参考上方链接。

1
2
3
4
5
6
npm i hexo-renderer-multi-markdown-it --save
npm i hexo-autoprefixer --save
npm i hexo-algolia --save
npm i hexo-algoliasearch --save
npm i hexo-symbols-count-time --save
npm i hexo-feed --save

img

对应的依赖配置直接复制文档里的内容到 themes/shoka/_config.yml主题配置文件中。这个路径现在还没有,等会下载完主题就有了。

2- 下载主题

1
git clone https://github.com/amehime/hexo-theme-shoka.git ./themes/shoka

下载完毕多了这么个文件夹。

让这个主题起效:
修改站点配置文件 /_config.yml ,把主题改为 shoka

1
theme: shoka

重新编译部署:

1
2
hexo clean
hexo deploy

访问一下https://dabing85.github.io/呐,长这样:

img

3- 修改主题配置文件/shoka/_config.yml

参考主题:https://shoka.lostyu.me/computer-science/note/theme-shoka-doc/config/

要修改一些图片如头像,可以在\themes\shoka\source\images路径下修改,直接替换,要同名!!!

下面是我的配置文件给大家参考一些,也可能不够完善:

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
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# Alternate site name
alternate: Dabing

open_graph:
#twitter_id:
#google_plus:
#fb_admins:
#fb_app_id:

# Assets
statics: / #/ #//cdn.jsdelivr.net/gh/username/RepositoryName@latest/
css: css
js: js
images: images

# themes/shoka/source/images/***
favicon:
apple_touch_icon: /apple-touch-icon.png
#safari_pinned_tab: /logo.svg
#android_manifest: /manifest.json
#ms_browserconfig: /browserconfig.xml

# Dark Mode
# By default, the page judges whether to turn on the dark mode according to the device settings or user selection
# if `true`, the page will be displayed directly as Dark Mode, unless the user makes another choice
# 夜间模式
darkmode: false

# By default the page will automatically scroll to the last viewed position
# if `false`, automatic positioning will be turned off
# 自动定位 自动定位到上次浏览的位置
auto_scroll: true

# Whether to show the loading cat
# 是否显示页面加载动漫 就是每次都看到的那个猫猫
loader:
start: true # When entering the page
switch: true # When switching to another page

# click with Firework
# 页面特效 单击页面的烟花效果
fireworks:
enable: true
color:
# - "rgba(255,182,185,.9)"
# - "rgba(250,227,217,.9)"
# - "rgba(187,222,214,.9)"
# - "rgba(138,198,209,.9)"

# 加载谷歌字体
font:
enable: true
# Font options:
# `external: true` will load this font family from `host` above.
# `family: Times New Roman`. Without any quotes.
# `size: x.x`. Use `em` as unit. Default: 1 (16px)

# Global font settings used for all elements inside <body>.
global:
external: true
family: Mulish
size:

# Font settings for alternate title.
# 备用字体
logo:
external: true
family: Fredericka the Great
size: 3.5

# Font settings for site title.
# 站点字体
title:
external: true
family: Noto Serif JP
size: 2.5

# Font settings for headlines (<h1> to <h6>).
headings:
external: true
family: Noto Serif SC
size:

# Font settings for posts.
posts:
external: true
family:

# Font settings for <code> and code blocks.
codes:
external: true
family: Inconsolata

# project of https://www.iconfont.cn/
# //at.alicdn.com/t/font_1832207_c8i9n1ulxlt.css => 1832207_c8i9n1ulxlt
iconfont: "1832207_igi8uaupcus"

# 菜单
menu:
首页: / || home
关于: /about/ || user
文章:
default: / || feather
归档: /archives/ || list-alt
分类: /categories/ || th
标签: /tags/ || tags
# friends: /friends/ || heart
# links: /links/ || magic

# Social Links
# Usage: `Key: permalink || icon || color`
# Key is the link label showing to end users.
# Value before `||` delimiter is the target permalink,
# secend value is the name of Font icon.
social:
github: https://github.com/dabing85 || github || "#191717"
#google: https://plus.google.com/yourname || google
#twitter: https://twitter.com/yourname || twitter || "#00aff0"
#zhihu: https://www.zhihu.com/people/yourname || zhihu || "#1e88e5"
#music: https://music.163.com/#/user/home?id=yourid || cloud-music || "#e60026"
#weibo: https://weibo.com/yourname || weibo || "#ea716e"
#about: https://about.me/yourname || address-card || "#3b5998"
#email: mailto:yourname@mail.com || envelope || "#55acd5"
#facebook: https://www.facebook.com/yourname || facebook
#stackoverflow: https://stackoverflow.com/yourname || stack-overflow
#youtube: https://youtube.com/yourname || youtube
#instagram: https://instagram.com/yourname || instagram
#skype: skype:yourname?call|chat || skype
#douban: https://www.douban.com/people/yourname/ || douban

sidebar:
# Sidebar Position.
# position: left
position: right
# Replace the default avatar image and set the url here.
avatar: avatar.jpg

widgets:
# if true, will show random posts
# 显示随机文章
random_posts: true
# if true, will show recent comments
# 显示最近评论
recent_comments: true

footer:
# Specify the date when the site was setup. If not defined, current year will be used.
# 页尾全站统计局
since: 2010
icon:
name: sakura rotate
# Change the color of icon, using Hex Code.
color: "#ffc0cb"
# Dependencies: https://github.com/theme-next/hexo-symbols-count-time
count: false
powered: true

# 文章界面统计
post:
# Dependencies: https://github.com/theme-next/hexo-symbols-count-time
count: false

# 奖励 这里我不需要
# Reward (Donate)
#reward:
# # If true, reward will be displayed in every article by default.
# enable: true
# account:
# wechatpay: /wechatpay.png
# alipay: /alipay.png
# paypal: /paypal.png

# TagCloud settings for tags page.
tagcloud:
# All values below are same as default, change them by yourself.
min: 16 # Minimun font size in px
max: 22 # Maxium font size in px
start: "#72cecf" # Start color (hex, rgba, hsla or color keywords)
end: "#ffbac3" # End color (hex, rgba, hsla or color keywords)
amount: 200 # Amount of tags, change it if you have more than 200 tags


# ---------------------------------------------------------------
# Third Party Plugins & Services Settings
# ---------------------------------------------------------------

# Creative Commons 4.0 International License.
# See: https://creativecommons.org/share-your-work/licensing-types-examples
# Available values of license: by | by-nc | by-nc-nd | by-nc-sa | by-nd | by-sa | zero
# You can set a language value if you prefer a translated version of CC license, e.g. deed.zh
# CC licenses are available in 39 languages, you can find the specific and correct abbreviation you need on https://creativecommons.org
creative_commons:
license: by-nc-sa
language: zh-CN # deed.zh

# Comments
# Valine
# For more information: https://github.com/amehime/MiniValine
valine:
appId: # 配置你的appId
appKey: # 配置你的appKey
placeholder: ヽ(○´∀`)ノ♪ # Comment box placeholder
avatar: mp # Gravatar style : mp, identicon, monsterid, wavatar, robohash, retro
pageSize: 10 # Pagination size
lang: zh-CN
visitor: true # Article reading statistic 文章阅读量统计
NoRecordIP: false # Whether to record the commenter IP
serverURLs: # When the custom domain name is enabled, fill it in here (it will be detected automatically by default, no need to fill in)
powerMode: true
tagMeta:
visitor: 新朋友
master: 主人
friend: 小伙伴
investor: 金主粑粑
tagColor:
master: "var(--color-orange)"
friend: "var(--color-aqua)"
investor: "var(--color-pink)"
tagMember:
master:
# - hash of master@email.com
# - hash of master2@email.com
friend:
# - hash of friend@email.com
# - hash of friend2@email.com
investor:
# - hash of investor1@email.com

# bgm 背景音乐
audio:
- title: 列表1
list:
- https://music.163.com/#/playlist?id=2943811283
- https://music.163.com/#/playlist?id=2297706586
- title: 列表2
list:
- https://music.163.com/#/playlist?id=2031842656

# random image api
# 随机图库
image_server: # "https://acg.xydwz.cn/api/api.php"

# Algolia Search
# For more information: https://www.algolia.com
search:
hits:
per_page: 10

# Dependencies: https://github.com/amehime/hexo-renderer-multi-markdown-it
pangu: false

# Quicklink Support
# For more information: https://github.com/GoogleChromeLabs/quicklink
quicklink:
# Custom a time in milliseconds by which the browser must execute prefetching.
timeout: 3000
# Default (true) will attempt to use the fetch() API if supported (rather than link[rel=prefetch]).
priority: true

# For more flexibility you can add some patterns (RegExp, Function, or Array) to ignores.
# See: https://github.com/GoogleChromeLabs/quicklink#custom-ignore-patterns
ignores:

# ---------------------------------------------------------------
# analytics & SEO Settings
# ---------------------------------------------------------------
baidu_analytics: # <app_id>

# Disable Baidu transformation on mobile devices.
disable_baidu_transformation: true

# Automatically add external URL with Base64 encrypt & decrypt.
exturl: true

# Google Webmaster tools verification.
# See: https://www.google.com/webmasters
google_site_verification:

# Bing Webmaster tools verification.
# See: https://www.bing.com/webmaster
bing_site_verification:

# Yandex Webmaster tools verification.
# See: https://webmaster.yandex.ru
yandex_site_verification:

# Baidu Webmaster tools verification.
# See: https://ziyuan.baidu.com/site
baidu_site_verification:

# Enable baidu push so that the blog will push the url to baidu automatically which is very helpful for SEO.
baidu_push: false

# 渲染md文件
markdown:
render: # 渲染器设置
html: false # 过滤 HTML 标签
xhtmlOut: true # 使用 '/' 来闭合单标签 (比如 <br />)。
breaks: true # 转换段落里的 '\n' 到 <br>。
linkify: true # 将类似 URL 的文本自动转换为链接。
typographer:
quotes: '“”‘’'
plugins: # markdown-it 插件设置
- plugin:
name: markdown-it-toc-and-anchor
enable: true
options: # 文章目录以及锚点应用的 class 名称,shoka 主题必须设置成这样
tocClassName: 'toc'
anchorClassName: 'anchor'
- plugin:
name: markdown-it-multimd-table
enable: true
options:
multiline: true
rowspan: true
headerless: true
- plugin:
name: ./markdown-it-furigana
enable: true
options:
fallbackParens: "()"
- plugin:
name: ./markdown-it-spoiler
enable: true
options:
title: "你知道得太多了"

# minify 配置,压缩css/js/html
minify:
html:
enable: true
exclude: # 排除 hexo-feed 用到的模板文件
- '**/json.ejs'
- '**/atom.ejs'
- '**/rss.ejs'
css:
enable: true
exclude:
- '**/*.min.css'
js:
enable: true
mangle:
toplevel: true
output:
compress:
exclude:
- '**/*.min.js'

# 代码高亮
highlight:
enable: false

prismjs:
enable: false



autoprefixer:
exclude:
- '*.min.css'

# 全局搜索
algolia:
appId: #Your appId
apiKey: #Your apiKey
adminApiKey: #Your adminApiKey
chunkSize: 5000
indexName: "" #"shoka"
fields:
- title
- path
- categories
- content:strip:truncate,0,2000
- gallery
- photos
- tags


keywords: java,git,springcloud #站点关键词,用 “,” 分隔

feed:
limit: 20
order_by: "-date"
tag_dir: false
category_dir: false
rss:
enable: true
template: "themes/shoka/layout/_alternate/rss.ejs"
output: "rss.xml"
atom:
enable: true
template: "themes/shoka/layout/_alternate/atom.ejs"
output: "atom.xml"
jsonFeed:
enable: true
template: "themes/shoka/layout/_alternate/json.ejs"
output: "feed.json"


#! ---------------------------------------------------------------
#! DO NOT EDIT THE FOLLOWING `vendors` SETTINGS
#! UNLESS YOU KNOW WHAT YOU ARE DOING
#! Script dependencies will be combined with jsDelivr (cdn.jsdelivr.net)
#! ---------------------------------------------------------------
vendors:
css:
katex: npm/katex@0.12.0/dist/katex.min.css
comment: css/comment.css
fancybox: combine/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css,npm/justifiedGallery@3.8.1/dist/css/justifiedGallery.min.css
js:
pace: npm/pace-js@1.0.2/pace.min.js
pjax: npm/pjax@0.2.8/pjax.min.js
fetch: npm/whatwg-fetch@3.4.0/dist/fetch.umd.min.js
anime: npm/animejs@3.2.0/lib/anime.min.js
algolia: npm/algoliasearch@4/dist/algoliasearch-lite.umd.js
instantsearch: npm/instantsearch.js@4/dist/instantsearch.production.min.js
lazyload: npm/lozad@1/dist/lozad.min.js
quicklink: npm/quicklink@2/dist/quicklink.umd.js
fancybox: combine/npm/jquery@3.5.1/dist/jquery.min.js,npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js,npm/justifiedGallery@3.8.1/dist/js/jquery.justifiedGallery.min.js
valine: gh/amehime/MiniValine@4.2.2-beta10/dist/MiniValine.min.js
copy_tex: npm/katex@0.12.0/dist/contrib/copy-tex.min.js
chart: npm/frappe-charts@1.5.0/dist/frappe-charts.min.iife.min.js

4-修改全局配置文件 _config.yml

参考官网:https://hexo.io/zh-cn/docs/configuration

要说明一下的分类和标签的配置:

img

基本照着官网来就好,没啥要改的。我的给参考一下。

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
# Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/

# Site
title:
subtitle: '不在能知,乃在能行'
description: '欢迎来到大冰的笔记空间~这里主要会记录编程学习笔记🌸'
keywords:
author: Dabing-He
language: zh-CN
timezone: ''

# URL
## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project'
url: http://example.com
permalink: :title/ #:year/:month/:day/:title/
permalink_defaults:
pretty_urls:
trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
trailing_html: true # Set to false to remove trailing '.html' from permalinks

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link:
enable: true # Open external links in new tab
field: site # Apply to the whole site
exclude: ''
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
highlight:
enable: false
line_number: true
auto_detect: true
tab_replace: ''
wrap: true
hljs: false
prismjs:
enable: false
preprocess: true
line_number: true
tab_replace: ''

# Home page setting
# path: Root path for your blogs index page. (default = '')
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
path: ''
per_page: 10
order_by: -date

# Category & Tag
# 这里配置分类和标签
default_category: uncategorized
category_map:
tag_map:

# Metadata elements
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
meta_generator: true

# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss
## updated_option supports 'mtime', 'date', 'empty'
updated_option: 'mtime'

# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page

# Include / Exclude file(s)
## include:/exclude: options only apply to the 'source/' folder
include:
exclude:
ignore:

# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: shoka

# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
type: git
repo: git@github.com:dabing85/dabing85.github.io.git
branch: main

再来一遍三连 hexo clean 、hexo generate、hexo deploy 即可

V、其他

1- 要写一篇文章:

如我要写一篇文章,我就这么写:

1
2
3
4
5
6
7
8
9
10
---
title: SpringCloud2020
date: 2022/04/30 20:46:25
categories:
- 微服务
tags:
- 微服务
---

balabala......

或者在根目录下cmd输入hexo new “标题”

分类

在你的根目录 /source/_post/hexo/ 下放一张该分类的封面图,它就会自动在首页显示这个分类了。

2- jsdelivr 被墙

我在shoka评论区找到的,评论内容如下:

您好,我这边大概去了解了一下,这个问题应该是与 jsdelivr 被墙有关,可参考 关于jsdeliver在国内的ICP许可证被吊销 #65 里的讨论,以及 jsDelivr静态文件CDN加速失效之后解决方案 这一博客的评论区。我目前采取的解决方案是:

  • 修改 \themes\shoka\source\js_app 路径下的 utils.js 文件:将 cdn.jsdelivr.net 替换成 fastly.jsdelivr.net
  • 修改 \themes\shoka\scripts\helpers 路径下的 asset.js 文件:将 cdn.jsdelivr.net 替换成 fastly.jsdelivr.net
  • 修改 shoka 主题 _config.yml 文件(如果没有在博客根目录新增 _config.shoka.yml 文件的话)中的 statics 设置,输入完整的 fastly.jsdelivr 静态文件网址,即,设置为 https://fastly.jsdelivr.net/gh/你的github用户名/博客对应的仓库名@latest/ ,例如我的设置:https://fastly.jsdelivr.net/gh/jiankychen/jiankychen.github.io@latest/ (注:我不太确定 \themes\shoka\source\js_app 路径下 global.js 文件中的 var statics = CONFIG.statics.indexOf(‘//‘) > 0 ? CONFIG.statics : CONFIG.root 这一行代码的逻辑,为了确保我们在 _config.yml 中设置的 statics 能够奏效,所以我在设置 _config.yml 的 statics 时加上了 https: 这一前缀,以确保 CONFIG.statics.indexOf(‘//‘) > 0 为 true )
  • 如果您配置了 valine 评论系统,则还需要将 https://fastly.jsdelivr.net/gh/amehime/MiniValine@4.2.2-beta10/dist/ 中的 MiniValine.min.js 下载到本地并做一定的修改,同时修改 shoka 主题 _config.yml 文件的 valine: js/MiniValine.min.js 这一项设置,这一部分工作我暂时也还没能解决(目前我的 valine 评论系统仍需翻墙才能加载出来),所以无法为您提供更详细的修改建议。

附注:jsdelivr 缓存刷新较慢,据说可能要 24 小时左右,所以,按照上述操作进行修改后,可能需耐心等待 jsdelivr 缓存刷新后才能 正常访问博客 ,或者也可以查找有关 刷新 jsdelivr 缓存 的资料进一步解决。

Ⅵ、添加站内搜索功能

参考文章:Hexo Shoka 主题本地搜索 - shoka - hexo | Lemonman’s Blog = 南風未起

推荐使用站内搜索方式,也有另一种使用algolia搜索:https://blog.csdn.net/m0_45234510/article/details/116885792

安装插件

本地搜索通过 hexo-generator-searchdb 插件实现,需要先安装插件。

1
npm install hexo-generator-searchdb

修改文件配置

修改page.is

shoka/source/js/_app/page.js 中 localSearch() 修改后的文件如下,将整个 localSearch 复制到主题的 shoka/source/js/_app/page.js 中即可。

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
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
const localSearch = function(pjax) {
// 参考 hexo next 主题的配置方法
// 参考 https://qiuyiwu.github.io/2019/01/25/Hexo-LocalSearch/ 博文
if(CONFIG.localSearch === null)
return

if(!siteSearch) {
siteSearch = BODY.createChild('div', {
id: 'search',
innerHTML: '<div class="inner"><div class="header"><span class="icon"><i class="ic i-search"></i></span><div class="search-input-container"><input class="search-input"autocompvare="off"placeholder="'+LOCAL.search.placeholder+'"spellcheck="false"type="text"id="local-search-input"></div><span class="close-btn"><i class="ic i-times-circle"></i></span></div><div class="results"id="search-results"><div class="inner"><div id="search-stats"></div><div id="search-hits"></div><div id="search-pagination"></div></div></div></div></div>'
});
}

var isFetched = false;
var datas;
var isXml = true;
var current_page = 0;
var pageSize = parseInt(CONFIG.localSearch.pageSize, 10);
if(isNaN(pageSize)) pageSize = 10;
var total_pages = 0;
var max_page_on_show = 7; // 一次最多显示 7 个页码
var start_page = 0;
var end_page = 0;
var resultItems = [];

// search DB path
var searchPath = CONFIG.localSearch.path;
if (searchPath.length == 0) {
searchPath = 'search.xml';
} else if (searchPath.endsWith('json')) {
isXml = false;
}

const input = $('.search-input'); // document.querySelector('.search-input');
const resultContent = document.getElementById('search-hits');
const paginationContent = document.getElementById('search-pagination');

const getIndexByWord = function(word, text, caseSensitive) {
if (CONFIG.localSearch.unescape) {
var div = document.createElement('div');
div.innerText = word;
word = div.innerHTML;
}
var wordLen = word.length;
if (wordLen === 0) {
return [];
}
var startPosition = 0;
var position = [];
var index = [];
if (!caseSensitive) {
text = text.toLowerCase();
word = word.toLowerCase();
}

while ((position = text.indexOf(word, startPosition)) > -1) {
index.push({position:position, word:word});
startPosition = position + wordLen;
}
return index;
};

// Merge hits into slices
const mergeIntoSlice = function(start, end, index, searchText) {
var item = index[index.length - 1];
var position = item.position;
var word = item.word;
var hits = [];
var searchTextCountInSlice = 0;
while (position + word.length <= end && index.length !== 0) {
if (word === searchText) {
searchTextCountInSlice++;
}
hits.push({
position:position,
length: word.length
});

var wordEnd = position + word.length;

// Move to next position of hit
index.pop();
while (index.length !== 0) {
item = index[index.length - 1];
position = item.position;
word = item.word;
if (wordEnd > position) {
index.pop();
} else {
break;
}
}
}
return {
hits:hits,
start:start,
end:end,
searchTextCount: searchTextCountInSlice
};
}

// Highlight title and content
const highlightKeyword = function(text, slice) {
var result = '';
var prevEnd = slice.start;
slice.hits.forEach(function(hit) {
result += text.substring(prevEnd, hit.position);
var end = hit.position + hit.length;
result += '<mark>'+ text.substring(hit.position, end)+'</mark>';
prevEnd = end;
});
result += text.substring(prevEnd, slice.end);
return result;
};

const pagination = function() {

const addPrevPage = function(current_page) {
var classContent = '';
var numberContent = '';
if (current_page === 0) {
classContent = '#search-pagination pagination-item disabled-item';
numberContent = '<span class="#search-pagination page-number"><i class="ic i-angle-left"></i></span>';
} else {
classContent = '#search-pagination pagination-item';
numberContent = '<a class="#search-pagination page-number" aria-label="Prev" href="#"><i class="ic i-angle-left"></i></a>';
}
var prevPage = '<li class="'+ classContent +'" id="prev-page">'+ numberContent+'</li>';
return prevPage;
};

const addNextPage = function(current_page) {
var classContent = '';
var numberContent = '';
if ((current_page + 1) === total_pages) {
classContent = '#search-pagination pagination-item disabled-item';
numberContent = '<span class="#search-pagination page-number"><i class="ic i-angle-right"></i></span>';
} else {
classContent = '#search-pagination pagination-item';
numberContent = '<a class="#search-pagination page-number"aria-label="Next"href="#"><i class="ic i-angle-right"></i></a>';
}
var nextPage = '<li class="' + classContent +'"id="next-page">'+ numberContent +'</li>';
return nextPage;
};

const addPage = function(index, current_page) {
var classContent = '';
var numberContent = '<a class="#search-pagination page-number"aria-label="'+ (index + 1) +'"href="#">'+(index+1)+'</a>';
if (index === current_page) {
classContent = '#search-pagination pagination-item current';
} else {
classContent = '#search-pagination pagination-item';
}
var page = '<li class="'+classContent+'" id="page-'+(index + 1)+'">'+numberContent+'</li>';
return page;
}

const addPaginationEvents = function(start_page, end_page) {
if (total_pages <= 0) {
return;
}
const onPrevPageClick = function(event) {
if (current_page > 0) {
current_page -= 1;
}
if (current_page < start_page) {
start_page = current_page;
end_page = Math.min(end_page, start_page + max_page_on_show);
}
pagination();
};
const onNextPageClick = function(event) {
if ((current_page + 1) < total_pages) {
current_page += 1;
}
if (current_page > end_page) {
end_page = current_page;
start_page = Math.max(0, end_page - max_page_on_show);
}
pagination();
};
const onPageClick = function(event) {
var page_number = parseInt(event.target.ariaLabel);
current_page = page_number - 1; // note minus 1 here
pagination();
};

var prevPage = document.getElementById('prev-page');
if(prevPage != null)prevPage.addEventListener('click', onPrevPageClick);

var nextPage = document.getElementById('next-page');
if(nextPage != null) nextPage.addEventListener('click', onNextPageClick);
for (var i = start_page; i < end_page; i += 1) {
var page = document.getElementById('page-'+(i + 1));
if(page != null)page.addEventListener('click', onPageClick);
}
};



paginationContent.innerHTML = ''; // clear

var begin_index = Math.min(current_page * pageSize, resultItems.length);
var end_index = Math.min(begin_index + pageSize, resultItems.length);

resultContent.innerHTML = resultItems.slice(begin_index, end_index).map(function(result) {return result.item}).join('');

start_page = Math.max(0, total_pages - max_page_on_show);
end_page = start_page + Math.min(total_pages, max_page_on_show);
var pageContent = '<div class="#search-pagination">';
pageContent += '<div class="#search-pagination pagination">';
pageContent += '<ul>';
if (total_pages > 0) {
// add prev page arrow, when no prev page not selectable
pageContent += addPrevPage(current_page);
for (var i = start_page; i < end_page; i += 1) {
pageContent += addPage(i, current_page);
}
// add next page arrow, when no next page not selectable
pageContent += addNextPage(current_page);
}
pageContent += '</ul>';
pageContent += '</div>';
pageContent += '</div>';
paginationContent.innerHTML = pageContent;
addPaginationEvents(start_page, end_page);
resultContent.scrollTop = 0; // scroll to top
window.pjax && window.pjax.refresh(resultContent);
};



const inputEventFunction = function() {
if (!isFetched) {
console.log("Data not fetched.");
return;
}

var searchText = input.value.trim().toLowerCase();
var keywords = searchText.split(/[-\s]+/);

if (keywords.length > 1) {
keywords.push(searchText);
}

resultItems = [];
if (searchText.length > 0) {
// Perform local searching
datas.forEach(function(index) {

var categories = index.categories, title=index.title, content=index.content, url=index.url;
var titleInLowerCase = title.toLowerCase();
var contentInLowerCase = content.toLowerCase();
var indexOfTitle = [];
var indexOfContent = [];
var searchTextCount = 0;
keywords.forEach( function(keyword) {
indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
});


// Show search results
if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
var hitCount = indexOfTitle.length + indexOfContent.length;
// Sort index by position of keyword
[indexOfTitle, indexOfContent].forEach(function(index) {
index.sort(function(itemLeft, itemRight) {
if (itemRight.position !== itemLeft.position) {
return itemRight.position - itemLeft.position;
}
return itemLeft.word.length - item.word.length;
});
});

var slicesOfTitle = [];
if (indexOfTitle.length !== 0) {
var tmp = mergeIntoSlice(0, title.length, indexOfTitle, searchText);
searchTextCount += tmp.searchTextCountInSlice;
slicesOfTitle.push(tmp);
}

var slicesOfContent = [];
while (indexOfContent.length !== 0) {
var item = indexOfContent[indexOfContent.length - 1];
var position = item.position;
var word = item.word;
// Cut out 100 characters
var start = position - 20;
var end = position + 30;
if (start < 0) {
start = 0;
}
if (end < position + word.length) {
end = position + word.length;
}
if (end > content.length) {
end = content.length;
}
var tmp = mergeIntoSlice(start, end, indexOfContent, searchText);
searchTextCount += tmp.searchTextCountInSlice;
slicesOfContent.push(tmp);
}


// Sort slices in content by search text's count and hits' count
slicesOfContent.sort( function(sliceLeft, sliceRight) {
if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
return sliceRight.searchTextCount - sliceLeft.searchTextCount;
} else if (sliceLeft.hits.length !== sliceRight.hits.length) {
return sliceRight.hits.length - sliceLeft.hits.length;
}
return sliceLeft.start - sliceRight.start;
});

// Select top N slices in content
var upperBound = parseInt(CONFIG.localSearch.pageSize, 10);
if (upperBound >= 0) {
slicesOfContent = slicesOfContent.slice(0, upperBound);
}


var resultItem = '';
resultItem += '<div class="#search-hits item">';
// resultItem += '<div class="#search-hits">';
// resultItem += '<ol class="item">'
resultItem += '<li>'
// resultItem += '<li>';
var cats = categories !== undefined ? '<span>' + categories.join('<i class="ic i-angle-right"></i>') + '</span>' : '<span>No categories</span>';
resultItem += '<a href="'+url+'">' + cats;
if (slicesOfTitle.length !== 0) {
// resultItem += '<li><a href="'+url}">'+highlightKeyword(title, slicesOfTitle[0])}</a>';
resultItem += '<b>'+highlightKeyword(title, slicesOfTitle[0])+'</b><br>';
} else {
// resultItem += '<li><a href="'+url}">'+title}</a>';
resultItem += '<b>'+title+'</b><br>';
}

slicesOfContent.forEach(function(slice) {
return resultItem += '<li class="#search-hits subitem">'+highlightKeyword(content, slice)+' ...</li>';
});
// resultItem += '</li>';
resultItem += '</a>';
resultItem += '</li>';
// resultItem += '</ol>';
resultItem += '</div>';
resultItems.push({
item: resultItem,
id : resultItems.length,
hitCount:hitCount,
searchTextCount:searchTextCount
});
}
});
}

if (keywords.length === 1 && keywords[0] === '') {
resultContent.innerHTML = '<div id="no-result"><i></i></div>';
} else if (resultItems.length === 0) {
resultContent.innerHTML = '<div id="no-result"><i></i></div>';
} else {
resultItems.sort(function(resultLeft, resultRight) {
if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
return resultRight.searchTextCount - resultLeft.searchTextCount;
} else if (resultLeft.hitCount !== resultRight.hitCount) {
return resultRight.hitCount - resultLeft.hitCount;
}
return resultRight.id - resultLeft.id;
});
}

// Do pagination
total_pages = Math.ceil(resultItems.length / pageSize);
pagination();
}


const fetchData = function() {
fetch(CONFIG.root + searchPath)
.then(function(response) {return response.text()} )
.then( function(res) {
// Get the contents from search data
isFetched = true;
datas = isXml ? [new DOMParser().parseFromString(res, 'text/xml').querySelectorAll('entry')].map( function(element) {
return {
title : element.querySelector('title').textContent,
content: element.querySelector('content').textContent,
url : element.querySelector('url').textContent
};
}) : JSON.parse(res);
// Only match articles with not empty titles
datas = datas.filter(function(data) {return data.title} ).map( function(data) {
data.title = data.title.trim();
data.content = data.content ? data.content.trim().replace(/<[^>]+>/g, '') : '';
data.url = decodeURIComponent(data.url).replace(/\/{2,}/g, '/');
return data;
});
// Remove loading animation
document.getElementById('search-hits').innerHTML = '<i></i>';
inputEventFunction();
});
};

if (CONFIG.localSearch.preload) {
console.log("fetch data.");
fetchData();
}

if (CONFIG.localSearch.trigger === 'auto') {
input.addEventListener('input', inputEventFunction);
} else {
document.querySelector('.search-icon').addEventListener('click', inputEventFunction);
input.addEventListener('keypress',function(event) {
if (event.key === 'Enter') {
inputEventFunction();
}
});
}

// Handle and trigger popup window
document.querySelectorAll('.popup-trigger').forEach( function(element) {
element.addEventListener('click', function() {
document.body.style.overflow = 'hidden';
document.querySelector('.search-pop-overlay').classList.add('search-active');
input.focus();
if (!isFetched) fetchData();
});
});

// Handle and trigger popup window
$.each('.search', function(element) {
element.addEventListener('click', function() {
document.body.style.overflow = 'hidden';
transition(siteSearch, 'shrinkIn', function() {
$('.search-input').focus();
}) // transition.shrinkIn
});
});

// Monitor main search box
const onPopupClose = function() {
document.body.style.overflow = '';
transition(siteSearch, 0); // "transition.shrinkOut"
};

siteSearch.addEventListener('click', function(event) {
if (event.target === siteSearch) {
onPopupClose();
}
});

$('.close-btn').addEventListener('click', onPopupClose);
window.addEventListener('pjax:success', onPopupClose);
window.addEventListener('keyup', function(event) {
if (event.key === 'Escape') {
onPopupClose();
}
});

};

修改 script.js

shoka/scripts/generaters/script.js 中主要是读取配置,找到config.algolia的配置,大概在45行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...........  // 省略若干代码
if(config.algolia) {
siteConfig.search = {
appID : config.algolia.appId,
apiKey : config.algolia.apiKey,
indexName: config.algolia.indexName,
hits : theme.search.hits
}
}
// 以下为需要添加的代码
if(config.search) {
siteConfig.localSearch = {
enable: config.search.enable,
path: config.search.path,
field: config.search.field,
format: config.search.format,
limit: config.search.limit,
content: config.search.content,
unescape: config.search.unescape,
preload: config.search.preload,
trigger: config.search.trigger,
pageSize: config.search.pageSize
}
}

其实有了这条命令就可以把page.js里的const algoliaSearch的部分给删了…占内存qwq

修改pjax.js

shoka/source/js/_app/pjax.js 中是启动搜索功能的部分,这里在两个配置都有的情况下默认使用本地搜索而不是 Algolia。修改代码位置大约在125行位置或者直接搜素algoliaSearch(pjax)将它删掉并替换成:

1
2
3
4
5
if (CONFIG.localSearch != null) {
localSearch(pjax)
}else if(CONFIG.search != null) {
algoliaSearch(pjax)
}

添加配置

最后在 hexo 配置(最外层的 _config.yml )中添加 search 配置,就大功告成了

1
2
3
4
5
6
7
8
9
10
11
search:
enable: true
path: search.json # search.xml
field: post
format: html
limit: 10000
content: true
unescape: true
preload: true
trigger: "auto"
pageSize: 10

然后重新运行即可

Ⅶ、添加博客评论模块

原文链接:无后端评论系统valine的配置参考:https://valine.js.org/quickstart.html

登录leancloud:LeanCloud,进入后需完成实名认证和邮箱认证才可使用

获取APP ID 和 APP Key

进入控制台后点击左下角创建应用

img

应用创建好以后,进入刚刚创建的应用,选择左下角的设置>应用Key,然后就能看到你的APP IDAPP Key了:

img

安全域名

为了你的数据安全,请设置自己的安全域名

设置安全域名

更多信息请查看配置项

配置_config.yml

在根目录下添加:

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

valine:
appId: #Your_appId
appKey: #Your_appkey
placeholder: ヽ(○´∀`)ノ♪ # Comment box placeholder
avatar: mp # Gravatar style : mp, identicon, monsterid, wavatar, robohash, retro
pageSize: 10 # Pagination size
lang: zh-CN
visitor: true # 文章访问量统计
NoRecordIP: false # 不记录 IP
serverURLs: # When the custom domain name is enabled, fill it in here (it will be detected automatically by default, no need to fill in)
powerMode: true # 默认打开评论框输入特效
tagMeta:
visitor: 新朋友
master: 主人
friend: 小伙伴
investor: 金主粑粑
tagColor:
master: "var(--color-orange)"
friend: "var(--color-aqua)"
investor: "var(--color-pink)"
tagMember:
master:
# - hash of master@email.com
# - hash of master2@email.com
friend:
# - hash of friend@email.com
# - hash of friend2@email.com
investor:
# - hash of investor1@email.com

tag 标签显示在评论者名字的后面,默认是 tagMeta.visitor 对应的值。 在 tagMeta 和 tagColor 中,除了 visitor 这个 key 不能修改外,其他 key 都可以换一换,但需要保证一致性。

1
2
3
4
5
6
7
8
9
10
11
12
13
tagMeta:
visitor: 游客
admin: 管理员
waifu: 我老婆
tagColor:
visitor: "#855194"
admin: "#a77c59"
waifu: "#ed6ea0"
tagMember:
admin:
# - hash of admin@email.com
waifu:
# - hash of waifu@email.com

在文章 Front Matter 中也可以配置上述参数,访问该文章页面时,将覆盖全局配置。 尤其可以用来配置一个特殊的 placeholder。

1
2
valine:
placeholder: "点击评论本文~"

评论通知与管理工具建议使用这个 Valine-Admin。 注意 SITE_URL 需要以 / 结尾。 如果某一篇文章需要关闭评论功能,则在文章 Front Matter 中配置:

1
2
title: xxx
comment: false

更多配置请跳转原文:Step.2 基本配置 - Theme Shoka Documentation - 二进制杂谈 - 计算机科学 | Yume Shoka = 優萌初華 = 有夢書架 (lostyu.me)

Ⅷ、域名解析github page

  1. 买域名 ✔
  2. 域名备案 ✔
  3. 解析域名 见下
  4. 到github page设置自定义域名 见下

第三步,域名解析:记录类型CNAME,记录值写:你的github名.github.io

第四步:到github找到你的github名.github.io仓库,setting,找到github pages,添加上你的域名即可。

等个十几分钟就去访问下你的博客看看咯。我的 blog.dabing.cool

Ⅸ、使用Github Action自动部署hexo到GitHub pages

这里默认你把上面的都做好了~

1、github创建一个私人仓库,用于存放hexo的源代码 – 配置私钥

2、github上的youname.github.io是存放hexo的静态网页文件 – 配置公钥

3、配置工作流:.github/workflows/deploy.yml

我踩太多坑了,可以参考这个做:利用GitHub Actions 自动部署 Hexo博客 全自动运行

我的配置文件这里贴一下:

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
# Action 的名字
name: Hexo Auto Deploy

on:
# 触发条件1:main 分支收到 push 后执行任务。
push:
branches:
- main
# 触发条件2:手动按钮
workflow_dispatch:

# 这里放环境变量,需要替换成你自己的
env:
# Hexo 编译后使用此 git 用户部署到 github 仓库
GIT_USER: dabing85
# Hexo 编译后使用此 git 邮箱部署到 github 仓库
GIT_EMAIL: 2261617090@qq.com
# Hexo 编译后要部署的 github 仓库
GIT_DEPLOY_REPO: dabing85/dabing85.github.io
# Hexo 编译后要部署到的分支
GIT_DEPLOY_BRANCH: main

# # Hexo 编译后使用此 gitee 用户部署到gitee仓库
# GITEE_USER: wbsu2003
# # Hexo 编译后要部署的 gitee 仓库
# GITEE_DEPLOY_REPO: wbsu2003/wbsu2003
# # Hexo 编译后要部署到的分支
# GITEE_DEPLOY_BRANCH: master

# 注意替换为你的 GitHub 源仓库地址
GIT_SOURCE_REPO: git@github.com:dabing85/dabing85.github.io.git
# 注意替换为你的 Gitee 目标仓库地址
# GITEE_DESTINATION_REPO: git@gitee.com:wbsu2003/wbsu2003.git

jobs:
build:
name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }}
runs-on: ubuntu-latest
if: github.event.repository.owner.id == github.event.sender.id
strategy:
matrix:
os: [ubuntu-18.04]
node_version: [12.x]

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Checkout deploy repo
uses: actions/checkout@v2
with:
repository: ${{ env.GIT_DEPLOY_REPO }}
ref: ${{ env.GIT_DEPLOY_BRANCH }}
path: .deploy_git

- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node_version }}

- name: Configuration environment
env:
HEXO_DEPLOY_KEY: ${{secrets.HEXO_DEPLOY_KEY}}
run: |
sudo timedatectl set-timezone "Asia/Shanghai"
mkdir -p ~/.ssh/
echo "$HEXO_DEPLOY_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
git config --global user.name "$GIT_USER"
git config --global user.email "$GIT_EMAIL"

- name: Install dependencies
run: |
npm install hexo-cli -g
npm install
# 根据你安装的组件进行安装
# npm i hexo-renderer-multi-markdown-it --save
# npm i hexo-autoprefixer --save
# npm i hexo-algolia --save
# npm i hexo-algoliasearch --save
# npm i hexo-symbols-count-time --save
# npm i hexo-feed --save --egacy-peer-deps
# hexo-deployer-git --save
# 复制中文语言包,解决菜单英文的问题
# cp zh-CN.yml node_modules/hexo-theme-next/languages/

- name: Deploy hexo
run: |
hexo clean
hexo deploy

# 以下为发布到gitee
# - name: Sync to Gitee
# uses: wearerequired/git-mirror-action@master
# env:
# # 直接使用了 HEXO_DEPLOY_PRI
# SSH_PRIVATE_KEY: ${{ secrets.HEXO_DEPLOY_PRI }}
# with:
# # GitHub 源仓库地址
# source-repo: ${{ env.GIT_SOURCE_REPO }}
# # Gitee 目标仓库地址
# destination-repo: ${{ env.GITEE_DESTINATION_REPO }}

# - name: Build Gitee Pages
# uses: yanglbme/gitee-pages-action@main
# with:
# # 你的 Gitee 用户名
# gitee-username: ${{ env.GITEE_USER }}
# # 注意在 Settings->Secrets 配置 GITEE_PASSWORD
# gitee-password: ${{ secrets.GITEE_PASSWORD }}
# # 你的 Gitee 仓库,仓库名严格区分大小写,请准确填写,否则会出错
# gitee-repo: ${{ env.GITEE_DEPLOY_REPO }}
# # 要部署的分支,默认是 master,若是其他分支,则需要指定(指定的分支必须存在)
# branch: ${{ env.GITEE_DEPLOY_BRANCH }}

评论邮箱提醒功能:使用Valine-Admin实现评论邮件提醒 - Hexo | Dabing = = 笔记空间

Ⅹ、一些坑(不全)

遇到的坑也没全填平,这里总结一下一些坑:

  1. 问题: Hexo 使用 Github Actions 自动发布至 Github Pages 时,生成的 html 页面空白,没有css/js等文件。

原因: 由于主题是 git clone 下来的,主题目录下生成了 .git 目录,导致和 hexo 根目录下 .git 冲突了,commit 时没有把主题 push 上去导致的。

解决办法: 删掉主题下的.git文件夹,重新提交,目的是把next主题文件夹提交上去(删掉.git文件夹后git commit依然没有提交上,需要把next文件夹剪切出来后git add&&git commit &&git push后,再把next文件夹拷贝回来,再git add&&git commit &&git push就可以提交成功了)

注:这里如果用idea的可视化按键不行(反正我的不行)。就在idea终端打命令。按着上面的来就行。我这里做一下记录。

1
2
3
4
5
6
git status  # 查看有没有未添加的文件夹,
git add themes/shoka/ # shoka是我的主题
git commit -m "shoka主题内容"
git remote add origin git@github.com:dabing85/hexoBlog.git # 我是重新搭建的,这里才关联远程仓库,origin是远程仓库名字
git branch -M main
git push -u origin main

2.问题: 安装插件依赖失败,说啥解析失败,npm ERR! code ERESOLVE

img

解决: 后面添加 –egacy-peer-deps

参考链接: https://blog.csdn.net/m0_51969330/article/details/119186416

  1. 问题:npm install error (code EBADPLATFORM) 表示没有平台支持安装fsevents

img

解决:npm install error (code EBADPLATFORM)

这里我是只删除了package-lock.json就行了,但是还是做了警告。

  1. 问题:自动部署后,github pages上的自定义域名也会被抹掉.

解决: https://blog.csdn.net/fake_hydra/article/details/82414965

即:在source目录下建一个CNAME文件,没有后缀,里面写你的域名即可。

XI、部署到服务器

参考链接:将Hexo搭建到自己的服务器上

服务器(Linux)我是全按照上面的博客来的,没啥问题。

到客户端(Windows)我是新建了一个hexoBlog文件夹,但是内容全部复制以前github的源码,所以github上的还是起效的。

直接复制有些要注意的是:

  1. 最好删除.git文件(这里的.git是原来github远程仓库的)

  2. .idea文件夹的内容有些文件需要改,因为里面记的是原来项目的模块

    下面几个文件内容的项目名改成现在的,不放心可以每个都看一下替换一下。

image-20220813201936397

参考

GitHub Actions部署Hexo小结

用GitHub Actions自动部署Hexo

利用GitHub Actions 自动部署 Hexo博客 全自动运行

将Hexo搭建到自己的服务器上