hexo + NexT搭建博客——环境准备
1. 环境准备
1.1 在github创建Git仓库
在github托管的GithubPage,也可以托管到Gitee,但是GiteePage好像有一些限制具体看自己选择
仓库名一定要输入 username.github.io
- 一个账号只能用创建一个同名的博客
1.2 安装Git
1.3 安装node管理工具
nvm
在github官网下载,解压后直接运行.exe
安装程序
1.3.1 安装node
在命令行中输入 nvm install 版本号 32/64
如:
1 | nvm install 6.10.2 64 |
1.3.2 设置node的版本
1 | nvm use 6.10.2 |
1.4 修改镜像源
npm
默认的镜像源在国外,安装包时会卡在sill idealTree buildDeps
,最好改成国内
1 | npm config set registry https://registry.npm.taobao.org |
1.5 安装hexo
npm install hexo-cli -g
1.6 创建本地博客
初始化本地博客仓库
1 | hexo init 你的用户名.github.io |
1.7 安装NexT主题
Hexo有两份主要的配置文件,都是
_config.yml
- 一份位于 本地博客目录下,主要包含Hexo本身配置
- 另一份位于主题目录下
xx.github.io/themes/next
下
1.7.1 切换到本地博客目录下 xx.github.io
目录下
1.7.2 安装NexT主题
git clone https://github.com/iissnan/hexo-theme-next themes/next
1.7.3 使用 NexT主题
找到本地博客目录下的 _config.yml
将 theme
键值对修改为 theme: next
1.7.4 站点配置文件基本信息修改
1 | title: xxx # 博客的名字,也称站点名称 |
站点配置文件示例
1 | # Hexo Configuration |
1.7.5 本地测试
- 定位到
xxx.github.io
目录 - 输入命令:
hexo s
相当于 启动hexo服务预览
启动成功,默认在 http://localhost:4000
就能打开博客
1.7.6 NexT主题个性化
1 | # 挑一些有必要的属性列一下 |
1.7.7 创建分类与标签
命令行定位到
xxx.github.io
目录,输入hexo new page categories
这样在
\source
目录下创建新建对应的目录,找到目录对应的index.md
文件1
2
3
4
5
6
7
8
9
10title: 分类
date: 2022-02-22 08:05:53
type: "categories"
2. 命令行定位到 `xxx.github.io` 目录,输入 `hexo new page "tags"` ,这样在 `source` 目录下新建对应的目录
```yaml
title: 标签
date: 2022-02-22 08:05:42
type: "tags"
上述两个操作相当于创建了给所有博客添加了两个分类依据 categories
以及 tags
,用于文章的归类管理
某一篇文章要归类或者打标签,只需要在抬头配置对应属性即可,如本篇文章所述:
这两个页面是NexT自动维护的,只要文章按照规矩来就不会报错
2. 写文章与上传
2.1 写文章
2.2 本地运行测试
命令行定位到 xxx.github.io
目录中,输入命令 hexo s
2.3 在浏览器中查看效果
在浏览器地址栏输入 http://localhost:4000
访问本地博客
2.4 安装自动部署发布工具
1 | npm install hexo-deployer-git --save |
为了自动部署到 GithubPage,这里我们需要 hexo-deployer-git
工具,将 md文件 转化为 静态网页文件 ,并保存在 /public
文件夹中,文件夹上传到 github的相应仓库 xxx.github.io
,等待github部署完成之后,就可以访问 http://xxx.github.io
查看部署完成的博客了
1 | hexo clean #清楚缓存,网页正常情况可以忽略这条命令 |
3. 文章链接
Hexo默认使用的文章链接是
1 | year/:month/:day/:title/ |
但分享之后会使一堆转义字符,而且一旦修改文章发布日期或者标题,则立马失效,所以需要生成真正的永久链接
abbrlink
工具 https://github.com/rozbo/hexo-abbrlink
3.1 安装abbrlink插件
在博客根目录安装插件
1 | npm install hexo-abbrlink --save |
3.2 编辑站点配置文件
1 | # 默认的永久链接 |
设置的示例:
1 | crc16 & hex |
4. 自动化构建
5. 图片问题
5.1 安装插件
1 | npm install hexo-asset-image --save |
5.2 站点配置文件修改 post_asset_folder
为 true
5.3 打开替换内容
1 | /node_modules/hexo-asset-image/index.js |
替换为以下内容
1 | ; |
5.4 修改typora的图片保存方式
一定要记得修改为相对路径,否则无法正常显示图片
6. 点击图片放大
效果如图:
6.1 切换到lib目录
1 | cd xxx.github.io\themes\next\source\lib |
6.2 下载插件
1 | git clone https://github.com/theme-next/theme-next-fancybox3 fancybox |
6.3 更换主题配置文件
1 | fancybox: true |
7. 数学公式
7.1 hexo转化错误
Hexo默认使用 hexo-render-marked
引擎渲染网页(将一些特殊的makrdown语法转化为html标签),如markdown中的 _
代表斜体,会被渲染引擎处理为 <em>
MathJax引擎在渲染数学公式的时候就会出错。例如,$x_i$在开始被渲染的时候,处理为$x<em>
i</em>
$,这样MathJax引擎就认为该公式有语法错误,因为不会渲染。
类似的语义冲突的符号还有 *
,{
,}
,\\
7.2 解决方法
Hexo渲染主题的两个重要因素:mathjax和kramed,前者是数学公式渲染引擎,后者是Hexo的markdown渲染引擎,hexo默认渲染引擎是marked,但是它不支持mathjax,因此需要替换为 kramed
引擎。
7.2.1 Hexo添加数学公式解析插件mathjax
如果hexo安装有
hexo-math
,需要先卸载它1
npm uninstall hexo-math --save
安装
mathjax
1
npm install hexo-renderer-mathjax --save
hexo主题开启mathjax
进入主题目录,编辑
_config.yml
,开启mathjax1
2
3
4# MathJax Support
mathjax:
enable: true
per_page: true在博客文章的开头加入
mathjax: true
即可使用mathjax
7.2.2 hexo渲染引擎切换为 kramed
卸载 marked 引擎
1
npm uninstall hexo-renderer-marked --save
安装kramed引擎
1
npm install hexo-renderer-kramed --save
修改引擎bug
修改文件
node_modules\kramed\lib\rules\inline.js
中escape
和em
两行1
2
3
4
5// escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,
escape: /^\\([`*\[\]()#$+\-.!_>])/,
// em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,重启hexo
1
hexo clean && hexo g -d
8. mermaid
8.1 安装hexo插件
在博客的根目录下,安装 hexo-filter-mermaid-diagrams
插件
1 | npm install hexo-filter-mermaid-diagrams --save |
8.2 NexT启用Mermaid
打开NexT主题的 _config.xml
配置文件,找到 mermaid
的配置项,设置 enable: true
1 | # Mermaid tag |
9. 文章置顶
9.1 使用
Hexo 只提供了按发布日期的排序,所以需要修改依赖文件,在每篇文章的配置项设置 top: 数字
赋权(升序)
9.2 修改
在 node_modules/hexo-generator-index/lib/generator.js
目录下新增
1 | posts.data = posts.data.sort(function(a, b) { |
如图:
10. Hexo添加helper-live2d动态模型插件
10.1 安装模块
在hexo根目录执行命令
1 | npm install --save hexo-helper-live2d |
10.2 下载模型
需要哪个模型就安装哪个
1 | npm install live2d-widget-model-hibiki |
10.3 配置
在主题配置文件或者博客配置文件的 _config.xml
都可以
如:
1 | # Live2D |
11. 压缩静态资源
11.1 gulp
11.1.1 全局安装gulp
1 | npm install glup -g |
11.1.2 在站点目录下安装
1 | npm install gulp-minify-css --save |
11.1.3 安装gulp插件
1 | npm install gulp --save |
11.1.4 创建 gulp.js
文件
在 Hexo
站点下创建 gulpfile.js
文件
相关问题与解决参考:
imagemin.jpegtran is not a function
注意:
- 图片压缩:由于我使用了图片插件
hexo-asset-image
,所以不适合用这种方式压缩,仅做记录
1 | import gulp from 'gulp'; |
11.1.4 创建 .babelrc
文件
1 | { |
目前问题:
11.2 hexo-neat
我们利用Hexo生成的博客文件中存在大量的空格和空行,从而使得博客资源中有很多不必要的内存消耗,使得网站加载变慢,所以可以利用neat进行博文压缩,
已知 BUG:
- 压缩 md 文件会使 markdown 语法的代码块消失
- 会删除全角空格
首先安装:
1 | npm install hexo-neat --save |
为了在开启hexo-neat
的同时,不要将我们的动态配置压缩了,可在站点配置文件中加入:
1 | # hexo-neat |
在 hexo g
时自动调用
12. NexT主题优化
12.1 简单配置(主题配置文件)
12.1.1 主题选择
Next提供了四中主题风格scheme,可以在主题配置文件blog/themes/next/_config.yml文件中进行选择,分别是Muse、Mist、Pisces、Gemini:
12.1.2 添加博客自定义图标
博客网站的图标可以是一些矢量图标,然后选择或者创建相应大小的图标文件,放置在 blog/themes/next/sources/images
目录下,并在主题配置文件中进行配置
1 | favicon: |
12.1.3 修改标签样式
博客底部的标签样式默认为#tag
,我们可以将其改成:
只需要修改模板 /themes/next/layout/_macro/post.swig
,搜索 rel="tag">#
,将 #
换成 <i class="fa fa-tag"></i>
12.1.4 文章结束标志
在路径 \themes\next\layout\_macro
中新建 passage-end-tag.swig
文件,并添加以下内容
1 | <div> |
接着打开\themes\next\layout\_macro\post.swig
文件,在post-body
之后(END POST BODY
), post-footer
之前添加如代码:
1 | <div> |
然后打开主题配置文件(_config.yml
),在末尾添加:
1 | # 文章末尾添加“本文结束”标记 |
12.1.5 侧边栏设置
设置主题配置文件,其中 social
表示社交信息,我们可以填入我们相关的链接,格式为 链接名:链接地址 || 链接图标
,其中链接图标必须是FontAwesome网站中存在的图标名
1 | # Posts / Categories / Tags in sidebar. |
12.1.6 添加文章版权信息
要想开启博客的版权功能,需要设置主题配置文件:
1 | creative_commons: |
12.1.7 设置博客底部布局
1 | footer: |
12.1.8 设置博客摘要显示
对于摘要显示,首先我们需要开启摘要功能,修改主题配置文件:
1 | # Automatically scroll page to section which is under <!-- more --> mark. |
12.1.9 修改文章链接样式
修改文件 themes\next\source\css\_common\components\post\post.styl
,在末尾添加如下css样式,:
1 | // 文章内链接文本样式 |
12.1.10 修改分类层级显示
修改
post.swig
\hexo-theme\next\layout\_macro\post.swig
查找
1
{{ __('symbol.comma') }}
改为
1
{{('>') }}
修改
custom.styl
\themes\next\source\css\_common\components\pages
1
2
3
4
5
6.category-list ul {
list-style: none;
li:before {
content: '>>';
}
}
12.1.11 更改标签云颜色
/blog/themes/next/layout/page.swig
1 | {{ tagcloud({ |
hexo 颜色配置:https://hexo.io/zh-cn/docs/helpers.html#tagcloud
12.2 添加懒加载
lazylod可以在用户不查看的时候,不加载相关部分,从而提升网站加载速度:
在themes/next/下执行
1 | git clone https://github.com/theme-next/theme-next-jquery-lazyload source/lib/jquery_lazyload |
然后配置博客文件:
1 | lazyload: true |
12.3 网站动态元素延时加载
我们的网站添加了许多动态元素之后,加载速度会变慢,所以可以先不加载动态元素,等静态元素加载完之后再加载动态元素,这样就加速了网站的登入。可设置主题文件:
1 | # Use velocity to animate everything. |
12.4 添加站内静态搜索
Next集成了站内搜索功能,可先安装依赖:
1 | npm install hexo-generator-searchdb --save |
然后设置主题配置文件:
1 | # Local search |
12.5. 侧边栏目录
12.5.1 显示侧边目录
主题文件配置文件
1 | sidebar: |
12.5.2 中文目录不跳转
主题目录:
1 | const navItems = document.querySelectorAll('.post-toc li'); |
12.6 统计功能
安装插件,在hexo根目录下执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18npm install hexo-wordcount --save
2. 在主题配置文件 `_coinfig.xml` 下搜索 `Post wordcount` ,并配置以下参数:
`wordcount` :字数统计
`min2read` :阅读时长统计
`totalcount` :总子树统计
# 12.7 鼠标点击特效
![5308475-78e64c0a80bb559e-16675764477622](hexo+NexT博客/5308475-78e64c0a80bb559e-16675764477622.gif)
1. 在`/themes/next/source/js/src`下新建文件 clicklove.js ,接着把下面的代码拷贝粘贴到 clicklove.js 文件中:
```js
!function(e,t,a){function n(){c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){for(var e=0;e<d.length;e++)d[e].alpha<=0?(t.body.removeChild(d[e].el),d.splice(e,1)):(d[e].y--,d[e].scale+=.004,d[e].alpha-=.013,d[e].el.style.cssText="left:"+d[e].x+"px;top:"+d[e].y+"px;opacity:"+d[e].alpha+";transform:scale("+d[e].scale+","+d[e].scale+") rotate(45deg);background:"+d[e].color+";z-index:99999");requestAnimationFrame(r)}function o(){var t="function"==typeof e.onclick&&e.onclick;e.onclick=function(e){t&&t(),i(e)}}function i(e){var a=t.createElement("div");a.className="heart",d.push({el:a,x:e.clientX-5,y:e.clientY-5,scale:1,alpha:1,color:s()}),t.body.appendChild(a)}function c(e){var a=t.createElement("style");a.type="text/css";try{a.appendChild(t.createTextNode(e))}catch(t){a.styleSheet.cssText=e}t.getElementsByTagName("head")[0].appendChild(a)}function s(){return"rgb("+~~(255*Math.random())+","+~~(255*Math.random())+","+~~(255*Math.random())+")"}var d=[];e.requestAnimationFrame=function(){return e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)}}(),n()}(window,document);在
\themes\next\layout\_layout.swig
文件末尾添加1
2<!-- 页面点击小红心 -->
<script type="text/javascript" src="/js/src/clicklove.js"></script>
跟那个红心是差不多的,首先在
themes/next/source/js/src
里面建一个叫fireworks.js
的文件,代码如下:1
function updateCoords(e){pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){var a={};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){var a={};return a.x=e,a.y=t,a.color="#F00",a.radius=0.1,a.alpha=0.5,a.lineWidth=6,a.draw=function(){ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){for(var t=0;t<e.animatables.length;t++){e.animatables[t].target.draw()}}function animateParticules(e,t){for(var a=createCircle(e,t),n=[],i=0;i<numberOfParticules;i++){n.push(createParticule(e,t))}anime.timeline().add({targets:n,x:function(e){return e.endPos.x},y:function(e){return e.endPos.y},radius:0.1,duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule}).add({targets:a,radius:anime.random(80,160),lineWidth:0,alpha:{value:0,easing:"linear",duration:anime.random(600,800)},duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule,offset:0})}function debounce(e,t){var a;return function(){var n=this,i=arguments;clearTimeout(a),a=setTimeout(function(){e.apply(n,i)},t)}}var canvasEl=document.querySelector(".fireworks");if(canvasEl){var ctx=canvasEl.getContext("2d"),numberOfParticules=30,pointerX=0,pointerY=0,tap="mousedown",colors=["#FF1461","#18FF92","#5A87FF","#FBF38C"],setCanvasSize=debounce(function(){canvasEl.width=2*window.innerWidth,canvasEl.height=2*window.innerHeight,canvasEl.style.width=window.innerWidth+"px",canvasEl.style.height=window.innerHeight+"px",canvasEl.getContext("2d").scale(2,2)},500),render=anime({duration:1/0,update:function(){ctx.clearRect(0,0,canvasEl.width,canvasEl.height)}});document.addEventListener(tap,function(e){"sidebar"!==e.target.id&&"toggle-sidebar"!==e.target.id&&"A"!==e.target.nodeName&&"IMG"!==e.target.nodeName&&(render.play(),updateCoords(e),animateParticules(pointerX,pointerY))},!1),setCanvasSize(),window.addEventListener("resize",setCanvasSize,!1)}"use strict";function updateCoords(e){pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){var a={};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){var a={};return a.x=e,a.y=t,a.color="#F00",a.radius=0.1,a.alpha=0.5,a.lineWidth=6,a.draw=function(){ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){for(var t=0;t<e.animatables.length;t++){e.animatables[t].target.draw()}}function animateParticules(e,t){for(var a=createCircle(e,t),n=[],i=0;i<numberOfParticules;i++){n.push(createParticule(e,t))}anime.timeline().add({targets:n,x:function(e){return e.endPos.x},y:function(e){return e.endPos.y},radius:0.1,duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule}).add({targets:a,radius:anime.random(80,160),lineWidth:0,alpha:{value:0,easing:"linear",duration:anime.random(600,800)},duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule,offset:0})}function debounce(e,t){var a;return function(){var n=this,i=arguments;clearTimeout(a),a=setTimeout(function(){e.apply(n,i)},t)}}var canvasEl=document.querySelector(".fireworks");if(canvasEl){var ctx=canvasEl.getContext("2d"),numberOfParticules=30,pointerX=0,pointerY=0,tap="mousedown",colors=["#FF1461","#18FF92","#5A87FF","#FBF38C"],setCanvasSize=debounce(function(){canvasEl.width=2*window.innerWidth,canvasEl.height=2*window.innerHeight,canvasEl.style.width=window.innerWidth+"px",canvasEl.style.height=window.innerHeight+"px",canvasEl.getContext("2d").scale(2,2)},500),render=anime({duration:1/0,update:function(){ctx.clearRect(0,0,canvasEl.width,canvasEl.height)}});document.addEventListener(tap,function(e){"sidebar"!==e.target.id&&"toggle-sidebar"!==e.target.id&&"A"!==e.target.nodeName&&"IMG"!==e.target.nodeName&&(render.play(),updateCoords(e),animateParticules(pointerX,pointerY))},!1),setCanvasSize(),window.addEventListener("resize",setCanvasSize,!1)}; ;
打开
themes/next/layout/_layout.swig
,在</body>
上面写下如下代码:1
2
3
4
5{% if theme.fireworks %}
<canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas>
<script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
<script type="text/javascript" src="/js/src/fireworks.js"></script>
{% endif %}打开主题配置文件,在里面最后写下:
1
2# Fireworks
fireworks: true
12.8 添加动态背景
转载:http://yearito.cn/posts/hexo-theme-beautify.html
12.8.1 粒子漂浮聚合
上面这种只是其中一种动态背景,新版的Next主题集成了该功能,
在根目录下克隆依赖
1 | git clone https://github.com/theme-next/theme-next-canvas-nest themes/next/source/lib/canvas-nest |
只需要在主题配置中设置如下即可
1 | # Canvas-nest |
12.8.2 Three三维效果
在安装依赖根目录下
1 | git clone https://github.com/theme-next/theme-next-three themes/next/source/lib/three |
然后在主题配置文件中设置开启对应的动效选项即可。
1 | # JavaScript 3D library. |
12.8.3 随机三角丝带
点击下方按钮下载相应的脚本,并置于 themes\next\source\js\ 目录下:
1 | if (document.getElementById('evanyou')) { |
在主题自定义布局文件中添加以下代码:
themes\next\layout\_custom\custom.swig
1 | {# 随机三角丝带背景 #} |
如果 custom.swig 文件不存在,需要手动新建并在布局页面中 body 末尾引入:
themes\next\layout\_layout.swig
1 | ... |
在主题配置文件中添加以下代码:
1 | # colorful trilateral riband background |
12.9 回到顶部
原理很简单,将 back-to-top 按钮添加图片背景,并添加 CSS3 动效即可。
首先,找到自己喜欢的图片素材放到 source\images\ 目录下。
你可以点击下方按钮下载本站所使用的小猫上吊素材( 小猫咪这么可爱,当然要多放点孜然啦…)
然后在自定义样式文件中添加如下代码:
themes\next\source\css\_custom\custom.styl
1 | //自定义回到顶部样式 |
刷新浏览器即可预览效果。
12.10 加入已运行时间
1 | npm install hexo-symbols-count-time |
/blog/themes/next/layout/_custom/sidebar.swig
1 | <div id="days"></div> |
上面 Date
的值记得改为你自己的,且按上面格式,然后修改:/blog/themes/next/layout/_macro/sidebar.swig
1 | {% include '../_custom/sidebar.swig' %} |
百度收录
https://ziyuan.baidu.com/college/articleinfo?id=1003
域名映射
个人博客支持https https://www.codepeople.cn/2019/01/11/GitHub-Https-config/