前言:当自己拥有一台电脑时,可以搭建hexo博客,写写自己喜欢的东西,或者用来存档。
Hexo的好处
- 纯静态博客,部署简单、成本低廉、运行优化非常高效。
- Hexo 静态博客框架可以在云端,也可以在本地电脑上甚至手机上。
- Hexo 框架的博客网站没有网站后台,不存在后台安全漏洞的问题。
- 因为是纯静态的,几乎所有的 CDN 服务都可以完美的加速提升浏览速度。
- 搜索引擎对纯静态网站有天然的青睐度,收录、权重优先权明显。
- 纯静态网站会让网络攻击成本大大的增加也就是说纯静态网站被攻击的可能性更低了。
软件安装(Git+Node.Js)
Node.Js下载 官网
Git下载 官网
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 1、在D盘创建一个Hexo文件,Hexo文件下再创建一个Git和Nodejs的文件用于软件存储 2、软件安装成功之后,电脑桌面鼠标右键找到Open Git Bash here并打开 3、分别输入 git -v node -v npm -v 查看是否会出现版本号。 4、Hexo文件目录里创建一个全局文件,命名随便,我用的是QJ 5、Git Bash: npm config set prefix "D:\Hexo\QJ" npm config set cache "D:\Hexo\QJ" 全局变量 6、复制设置全局变量的目录D:\Hexo\QJ 7、打开控制面板-系统安全-系统-高级系统设置-高级-环境变量-用户变量中新建 变量名为Hexo 变量值为D:\Hexo\QJ
|
安装Hexo框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 1、Hexo文件目录下创建一个Blog文件夹 2、打开Blog文件,文件中鼠标右键打开Open Git Bash here 3、Git Bash: npm install -g hexo 安装Hexo框架 4、Git Bash: hexo -v 查看会不会出现版本号,如果没有报错没有一点问题 5、Git Bash: hexo init 初始化博客 6、Git Bash: hexo s 开启本地服务 7、执行成功后会出现一个本地链接,鼠标选中右键Open打开会出现Hexo自带的主题博客
|
代码部署至托管平台
国外Github
[Github官网](GitHub: Let’s build from here · GitHub)
1 2 3 4 5 6 7 8 9 10 11 12 13
| 1、Git Bash:ssh-keygen -t rsa -C "3118708520@qq.com" //生成与gitub连接的密钥 2、打开文件找到后缀为.pub的文件(一般在你C盘的用户文件中「SSH」)打开复制密钥 3、打开Github在个人设置中的SSH把生成下来的密钥和ssh对接 3、修改Hexo根目录下的_config.yml deploy: type: git repo: https://bitbucket.org/JohnSmith/johnsmith.bitbucket.io branch: main 修改配置文件 4、hexo g 生成静态文件 5、Git Bash: npm install hexo-deployer-git --save 安装插件 6、git config --global user.email "3118708520@qq.com" 配置git信息 git config --global user.name "xiaowentx" 7、hexo d 远程部署博客
|
重新部署至Github
只要输入以下命令,进行文章全部更新。输完命令后等待几分钟即可。
1、hexo g
2、hexo clean
3、hexo d
Butterfly主题安装
1 2 3 4 5 6 7 8 9 10
| 1、首先关闭本地服务Ctrl+C,如果运行两个Open Git Bash here会报错 2、在Blog文件夹中运行Open Git Bash here 3、Git Bash: git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly 进行主题安装(如果安装不了重开Open Git Bash here再试一下,或者试一下npm安装) npm install hexo-theme-butterfly 4、修改Hexo根目录下的_config.yml把主題改为 butterfly 5.Hexo根目录运行Git并输入 hexo s 查看主题是否已经有了
|
Butterfly主题配置
1 2
| 1、主题配置文件在themes下的_config.yml(站点配置文件) 2、Butterfly博客主页 https://butterfly.js.org/(可参考Butterfly博客)
|
Butterfly主题魔改:友情页面
打开[Blogroot]\source\link\index.md,添加一行type: ‘link’:
1 2 3 4 5
| --- title: 友情链接 date: 2025-05-21 17:32:19 type: "link" ---
|
创建数据文件
新建文件[Blogroot]\source/_data\link.yml,没有_data文件夹的话也请自己新建。以下是默认友链格式示例。打开[Blogroot]\source_data\link.yml,输入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| - class_name: butterfly排版 class_desc: 这里的每个站点,都耐人寻味…… flink_style: butterfly link_list: - name: 标题 link: https://www.test.com/ avatar: https://www.test.com/cs.png siteshot: https://www.test.com/cs.png descr: 技术分享,编程学习 type: 技术 - class_name: flexcard排版 class_desc: 这里的每个站点,都耐人寻味…… flink_style: flexcard link_list: - name: 码农观测站 link: https://www.test.com/ avatar: https://www.test.com/cs.png siteshot: https://www.test.com/cs.png descr: 技术分享,编程学习 type: 技术
|
注意flink_style为排版参数
1
| flink_style: flexcard || butterfly
|
打开link菜单
取消[Blogroot]_config.butterfly.yml中menu配置项内link页面的注释(这里我已改成中文【友链】)。
1 2 3 4 5 6 7 8 9 10 11
| menu: 首页: / || fas fa-home 文章: /archives/ || fas fa-archive 标签: /tags/ || fas fa-tags 分类: /categories/ || fas fa-folder-open 友链: /link/ || fas fa-link 关于: /about/ || fas fa-heart
|
替换模板文件
替换[Blogroot]\themes\butterfly\layout\includes\page\flink.pug
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
| .container if top_img === false h1.page-title= page.title .flink if site.data.link each i in site.data.link if i.class_name h2!= i.class_name if i.class_desc .flink-desc!=i.class_desc if i.flink_style === 'flexcard' .flexcard-flink-list each item in i.link_list a.flink-list-card(href=url_for(item.link) target='_blank' data-title=item.descr) .wrapper.cover if item.type .is-type.is-type-0!=item.type - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link if theme.lazyload.enable img.cover.fadeIn(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' ) else img.cover.fadeIn(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' ) .info if theme.lazyload.enable img.flink-avatar(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' ) else img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' ) span.flink-sitename= item.name span.flink-sitedesc(title=item.descr)= item.descr else if i.flink_style === 'butterfly' .butterfly-flink-list each item in i.link_list .flink-list-item a(href=url_for(item.link) title=item.name target="_blank") .flink-item-icon if theme.lazyload.enable img(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name ) else img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name ) .flink-item-info .flink-item-name= item.name .flink-item-desc(title=item.descr)= item.descr != page.content
|
替换样式文件
替换[Blogroot]\themes\butterfly\source\css_page\flink.styl
注意代码中#article-container,检查一下你的Butterfly主题link页面div是不是用的这个id,如果不是的部署将没有样式
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
| #article-container .flink margin-bottom: 20px .flink-desc margin: 0 0 .6rem !important .butterfly-flink-list overflow: auto text-align: center
& > .flink-list-item position: relative float: left overflow: hidden margin: 15px 7px width: calc(100% / 3 - 15px) height: 90px line-height: 17px -webkit-transform: translateZ(0) addBorderRadius(8) background: #49b1f514
+maxWidth1024() width: calc(50% - 15px) !important
+maxWidth600() width: calc(100% - 15px) !important
&:hover .flink-item-icon margin-left: -10px width: 0
&:before position: absolute top: 0 right: 0 bottom: 0 left: 0 z-index: -1 background: var(--text-bg-hover) content: '' transition: transform .3s ease-out transform: scale(0)
&:hover:before, &:focus:before, &:active:before transform: scale(1)
a color: var(--font-color) text-decoration: none
.flink-item-icon float: left overflow: hidden margin: 15px 10px width: 60px height: 60px border-radius: 30% transition: width .3s ease-out
img width: 100% height: 100% transition: filter 375ms ease-in .2s, transform .3s object-fit: cover
.img-alt display: none :hover color: #fff
.flexcard-flink-list display: flex flex-wrap: wrap justify-content: flex-start margin: -8px align-items: stretch > .flink-list-card margin: 8px width: calc(100% / 4 - 16px) display: block line-height: 1.4 height: 100% text-decoration:none .cover width: 100% height: 120px overflow: hidden border-radius: 6px box-shadow: 0 1px 2px 0px rgba(0, 0, 0, 0.2) background: #f6f6f6 position: relative .is-type position: absolute top: 0 left: 0 color: #fff z-index: 10 border-radius: 6px 0 6px 0 padding: 4px 8px font-size: .6rem background-color: var(--btn-bg) img width: 100% height: 100% pointer-events: none transition: transform 2s ease object-fit: cover .info margin-top: 8px img width: 32px height: 32px pointer-events: none border-radius: 16px float: left margin: 0 auto .1rem !important margin-right: 8px !important .flink-sitename font-weight: 600 font-size: var(--global-font-size) color: var(--font-color) display: -webkit-box -webkit-box-orient: vertical overflow: hidden -webkit-line-clamp: 1 transition: all 0.28s ease -moz-transition: all 0.28s ease -webkit-transition: all 0.28s ease -o-transition: all 0.28s ease .flink-sitedesc margin-top: 4px !important font-size: var(--global-font-size); word-wrap: break-word line-height: 1.2 color: #888 display: -webkit-box -webkit-box-orient: vertical overflow: hidden -webkit-line-clamp: 2 :hover .cover box-shadow: 0 4px 8px 0px rgba(0, 0, 0, 0.1), 0 2px 4px 0px rgba(0, 0, 0, 0.1), 0 4px 8px 0px rgba(0, 0, 0, 0.1), 0 8px 16px 0px rgba(0, 0, 0, 0.1) .flink-sitename color: var(--tzy-theme) !important
.flink-item-name @extend .limit-one-line padding: 16px 10px 0 0 height: 40px font-weight: bold font-size: 1.43em
.flink-item-desc @extend .limit-one-line padding: 16px 10px 16px 0 height: 50px font-size: .93em
.flink-name margin-bottom: 5px font-weight: bold font-size: 1.5em
|
全部保存好之后,一键三连部署本地预览
1
| hexo clean; hexo g;hexo s
|
效果图

Butterfly主题魔改:分类页面
安装插件
1
| npm install hexo-butterfly-categories-card --save
|
新建样式文件
在博客根目录themes\butterfly\source\css\下新建categorybar.css文件,添加 https://npm.elemecdn.com/hexo-butterfly-categories-card@1.0.0/lib/categorybar.css 的代码。
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
| #categoryBar { width: 100% !important; } ul.categoryBar-list { margin: 5px 5px 0 5px !important; padding: 0 !important; } li.categoryBar-list-item { font-weight: bold; display: inline-block; height: 180px !important; margin: 5px 0.5% 0 0.5% !important; background-image: linear-gradient(rgba(0,0,0,0.4) 25%, rgba(16,16,16,0) 100%); border-radius: 10px; padding: 25px 0 25px 25px !important; box-shadow: rgba(50,50,50,0.3) 50px 50px 50px 50px inset; overflow: hidden; background-size: 100% !important; background-position: center !important; } li.categoryBar-list-item:hover { background-size: 110% !important; box-shadow: inset 500px 50px 50px 50px rgba(50,50,50,0.6); } li.categoryBar-list-item:hover span.categoryBar-list-descr { transition: all 0.5s; transform: translate(-100%, 0); } a.categoryBar-list-link { color: #fff !important; font-size: 20px !important; } a.categoryBar-list-link::before { content: '|' !important; color: #fff !important; font-size: 20px !important; } a.categoryBar-list-link:after { content: ''; position: relative; width: 0; bottom: 0; display: block; height: 3px; border-radius: 3px; background-color: #fff; } a.categoryBar-list-link:hover:after { width: 90%; left: 1%; transition: all 0.5s; } span.categoryBar-list-count { display: block !important; color: #fff !important; font-size: 20px !important; } span.categoryBar-list-count::before { content: '\f02d' !important; padding-right: 15px !important; display: inline-block; font-weight: 600; font-style: normal; font-variant: normal; font-family: 'Font Awesome 6 Free'; text-rendering: auto; -webkit-font-smoothing: antialiased; } span.categoryBar-list-descr { padding: 5px; display: block !important; color: #fff !important; font-size: 20px !important; position: relative; right: -100%; } @media screen and (max-width: 650px) { li.categoryBar-list-item { width: 48% !important; height: 150px !important; margin: 5px 1% 0 1% !important; } }
|
修改插件js样式文件
打开博客根目录下node_modules\hexo-butterfly-categories-card\index.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
| 'use strict'
const pluginname = 'butterfly_categories_card'
const pug = require('pug') const path = require('path') const urlFor = require('hexo-util').url_for.bind(hexo) const util = require('hexo-util')
hexo.extend.filter.register('after_generate', function () {
const config = hexo.config.categoryBar || hexo.theme.config.categoryBar if (!(config && config.enable)) return var categories_list= hexo.locals.get('categories').data; var categories_message= config.message; var new_categories_list = []; for (var i = 0; i < categories_list.length; i++) { var a = categories_list[i]; var b = categories_message[i]; new_categories_list[i] = Object.assign({}, a, { path: a.path }, b); } const data = { pjaxenable: hexo.theme.config.pjax.enable, enable_page: config.enable_page ? config.enable_page : "/", layout_type: config.layout.type, layout_name: config.layout.name, layout_index: config.layout.index ? config.layout.index : 0, categories_list: new_categories_list, column: config.column ? config.column : odd, row: config.row ? config.row : 2, custom_css: config.custom_css ? urlFor(config.custom_css) : "https://cdn.jsdelivr.net/npm/hexo-butterfly-categories-card/lib/categorybar.css" } const temple_html_text = config.temple_html ? config.temple_html : pug.renderFile(path.join(__dirname, './lib/html.pug'),data);
const css_text = `<link rel="stylesheet" href="${data.custom_css}">` var get_layout if (data.layout_type === 'class') { get_layout = `document.getElementsByClassName('${data.layout_name}')[${data.layout_index}]` } else if (data.layout_type === 'id') { get_layout = `document.getElementById('${data.layout_name}')` } else { get_layout = `document.getElementById('${data.layout_name}')` }
var user_info_js = `<script data-pjax> function ${pluginname}_injector_config(){ // 检查容器是否存在 var parent_div_git = ${get_layout}; // 如果容器不存在,则动态创建 if (!parent_div_git) { console.warn('${pluginname}: 挂载容器不存在,正在动态创建...'); // 创建新容器(默认插入到页面主体顶部) parent_div_git = document.createElement('div'); parent_div_git.id = '${data.layout_name}'; // 赋予配置的ID document.querySelector('#page').prepend(parent_div_git); // 插入到 #content-inner 内 } var item_html = '${temple_html_text}'; console.log('已挂载 ${pluginname}'); parent_div_git.insertAdjacentHTML("afterbegin",item_html) } // 路径匹配逻辑(使用 startsWith) if (location.pathname.startsWith('${data.enable_page}') || '${data.enable_page}' === 'all') { ${pluginname}_injector_config(); } </script>` hexo.extend.injector.register('body_end', user_info_js, "default"); hexo.extend.injector.register('head_end', css_text, "default"); }, hexo.extend.helper.register('priority', function(){ const pre_priority = hexo.config.categoryBar.priority || hexo.theme.config.categoryBar.priority const priority = pre_priority ? pre_priority : 10 return priority }) )
|
修改插件html.pug文件
打开博客根目录下node_modules\hexo-butterfly-categories-card\lib\html.pug文件,全部替换成以下代码:
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
| - var prow = 190 * row + 'px' - var mrow = 160 * row + 'px'
if (column === 'odd') style. li.categoryBar-list-item{width:32.3%;}.categoryBar-list{max-height: #{prow};overflow:auto;}.categoryBar-list::-webkit-scrollbar{width:0!important}@media screen and (max-width: 650px){.categoryBar-list{max-height: #{mrow};}} else if (column === 'even') style. li.categoryBar-list-item{width:24%;}.categoryBar-list{max-height: #{prow};overflow:auto;}.categoryBar-list::-webkit-scrollbar{width:0!important}@media screen and (max-width: 650px){.categoryBar-list{max-height: #{mrow};}} .recent-post-item(style='height:auto;width:100%;padding:0px;') #categoryBar ul.categoryBar-list if pjaxenable each cl in categories_list li.categoryBar-list-item(style=`background:url(` + cl.cover + `);`) //- 强制修正路径:移除重复的 categories 前缀 - var cleanPath = cl.path.replace(/^\/?categories\//, '') a.categoryBar-list-link( onclick=`pjax.loadUrl("/categories/${cleanPath}");` href='javascript:void(0);' )= cl.name span.categoryBar-list-count= cl.length span.categoryBar-list-descr= cl.descr else each cl in categories_list li.categoryBar-list-item(style=`background:url(` + cl.cover + `);`) //- 直接输出修正后的路径 - var cleanPath = cl.path.replace(/^\/?categories\//, '') a.categoryBar-list-link(href=`/categories/${cleanPath}`)= cl.name span.categoryBar-list-count= cl.length span.categoryBar-list-descr= cl.descr
|
修改配置文件
在博客根目录下_config.butterfly.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
|
categoryBar: enable: true priority: 5 enable_page: /categories/ layout: type: id name: recent-posts index: 0 column: odd row: 5 message: - descr: 1 cover: /img/11.png - descr: 2 cover: /img/12.png - descr: 3 cover: /img/13.png - descr: 4 cover: /img/14.png - descr: 5 cover: /img/15.png - descr: 6 cover: /img/16.png - descr: 7 cover: /img/17.png - descr: 8 cover: /img/18.png custom_css: /css/categorybar.css
|
效果图

更换自己的域名
1、在博客的blog下的.deploy_git目录下创建名为CNAME的文本文档
2、去自己购买域名的地方把域名解析
3、添加两个记录第一个主机名为@类型选择CNAME对应值的话就是github的地址比如xxxxx.github.io,第二个主机名为www类型为A记录对应值则是你ping到github上创建博客的ip地址
4、进入github的Your repositories->你所建立的储存库->Settings->Pages->在Custom domain中填写你购买的域名就OK了。
Hexo的基本命令
hexo博客文章采用Markdown语法
1 2 3 4
| hexo init 初始化博客 hexo n title 创建一篇新的文章,文章标题是title hexo new page tags 新建标签页 hexo new "hexo" 新建标题名为hexo的文章
|
Hexo搬移
1.拷贝相关文件
建立hexo博客都会有一个独立的文件夹。电脑转移时安全的做法是将整个文件夹拷贝,这其中包括三个必备的文件:config.yml(站点配置_)、theme(主题文件夹)、source(博客内容文件)、_config.butterfly.yml(主题配置文件)。
次要文件:scaffolds(文章的模板)、package.json(使用包的说明文件)和.gitignore(限定在提交的时候哪些文件可以忽略)三个次要文件为自动生成的,因此丢失也不影响博客内容,后续在hexo init时会生成这三个文件。
需要删除的文件:.git文件、node_modules(进行npm install会重新生成)、public(执行hexo g时会重新生成)、.deploy_git文件夹(执行hexo d时会重新生成)、db.json文件。其实上面这些可删除的文件即为.gitignore文件里面记载的可以忽略的内容。
2.在新电脑上重新安装git
3.替换掉git之前的SSH