Hexo + GitHub Pages 搭建個人博客及 NexT 主題配置
最近,自己根據網上的一些教程,基於 Hexo 搭建了自己的博客,並把搭建過程整理了出來,以供參考。
源碼倉庫:https://github.com/yifanzheng/yifanzheng.github.io/tree/hexo-blog-backup
框架驅動:Hexo
博客主題:NexT ^6.x
博客搭建與配置
環境準備
Hexo 搭建
安裝 Hexo,打開 Git Bash 命令窗口,輸入命令:
npm install -g hexo-cli
安裝好 Hexo 後,在任意目錄新建一個空文件夾,名字可以爲 blogs,然後進入這個文件夾,在命令行輸入命令:
hexo init
執行完成後(如果命令窗口出現橙色的 WARN 不用管),生成文件結構:
├── node_modules //依賴安裝目錄
├── scaffolds //模板文件夾,新建的文章將會從此目錄下的文件中繼承格式
| ├── draft.md //草稿模板
| ├── page.md //頁面模板
| └── post.md //文章模板
├── source //資源文件夾,用於放置圖片、數據、文章等資源
| └── _posts //文章目錄
├── themes //主題文件夾
| └── landscape //默認主題
├── .gitignore //指定不納入git版本控制的文件
├── _config.yml //站點配置文件
├── db.json
├── package.json
└── package-lock.json
下載依賴包,輸入命令:
npm install
依賴包下載完成後,輸入如下命令啓動 hexo 的內置 Web 服務器:
hexo g // 打包文件
hexo s // 啓動服務器
然後可以在在瀏覽器中通過地址 http://localhost:4000/ 訪問博客了。
更換 NexT 主題
Hexo 更換主題的方式很簡單,只需要將主題文件拷貝至根目錄下的 themes 目錄中, 然後修改根目錄下 _config.yml
文件中的 theme 字段,便可完成更換。
在博客項目的根目錄下,輸入命令:
git clone https://github.com/theme-next/hexo-theme-next.git themes/next
打開根目錄下 _config.yml
文件,將 theme 字段的值修改爲 next。
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: next
這個時候需要重啓服務器 hexo g && hexo s
並刷新才能使主題生效。
重要定義
在項目文件中存在兩個 _config.yml
文件,爲了方便區分。
-
項目根目錄下的
_config.yml
文件叫作站點配置文件
。 -
主題文件夾根目錄下的
themes/next/_config.yml
文件叫作主題配置文件
。
部署到 GitHub Pages
GitHub 配置
-
創建 GitHub 賬號
-
創建倉庫,倉庫名必須是:<GitHub 賬號名稱>.github.io,這是GitHub pages 的特殊命名規範
修改站點配置文件 _config.yml
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
type: 'git'
repo:
github: https://github.com/yifanzheng/yifanzheng.github.io.git
branch: master
注意:GitHub pages
僅在 master
分支下實現。
部署
- 在項目根目錄下,安裝 Git 部署插件:
npm install hexo-deployer-git --save
- 部署到 Github Pages
hexo g
hexo d
部署完成後,在瀏覽器訪問網址:https://<Github賬號名稱>.github.io 即可查看博客。
詳細過程可以參考:藉助 GitHub pages 搭建靜態個人網站並綁定域名
站點配置
站點配置可以查看 Hexo 官方文檔。
Hexo 官方文檔:https://hexo.io/zh-cn/docs/configuration.html 。
注意:所有的 :
都爲英文字符,後面必須有一個空格。
主題配置
NexT 的主題配置可以先查看官方文檔,寫得很不錯,很完善。
NexT 官方文檔:http://theme-next.iissnan.com/getting-started 。
NexT (最新)官方文檔:https://theme-next.org/docs/getting-started/ 。
第三方配置
鼠標點擊特效
從各個站點裏收集了以下四個比較常用的鼠標點擊特效:
- 禮花特效
下載:禮花特效
- 爆炸特效
下載:爆炸特效
- 浮出愛心
下載:浮出愛心
- 浮出文字
下載:浮出文字
將腳本文件放置於 themes/next/source/js/cursor
目錄下(如果沒有相應的目錄,需要自行創建,可以根據自己習慣命名)。
在主題自定義佈局文件 themes/next/layout/_custom/custom.swig
(如果沒有 custom.swig 文件,需自行創建)中添加如下代碼:
{# 鼠標點擊特效 #}
{% if theme.cursor_effect == "fireworks" %}
<script async src="/js/cursor/fireworks.js"></script>
{% elseif theme.cursor_effect == "explosion" %}
<canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas>
<script src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
<script async src="/js/cursor/explosion.min.js"></script>
{% elseif theme.cursor_effect == "love" %}
<script async src="/js/cursor/love.min.js"></script>
{% elseif theme.cursor_effect == "text" %}
<script async src="/js/cursor/text.js"></script>
{% endif %}
在 themes/next/layout/_layout.swig
文件 body 標籤中添加如下代碼:
...
{% include '_custom/custom.swig' %}
</body>
</html>
在主題配置文件 themes/next/_config.yml
中添加如下代碼:
# mouse click effect: fireworks | explosion | love | text
cursor_effect: love
打字特性
- 打字禮花
下載:打字禮花
將腳本文件放置到 themes/next/source/js
目錄下。
在主題自定義配置 themes/next/layout/_custom/custom.swig
文件中添加如下代碼:
{% if theme.typing_effect %}
<script async src="/js/activate-power-mode.min.js"></script>
<script>
POWERMODE.colorful = {{ theme.typing_effect.colorful }};
POWERMODE.shake = {{ theme.typing_effect.shake }};
document.body.addEventListener('input', POWERMODE);
</script>
{% endif %}
在主題配置文件 themes/next/_config.yml
中添加如下代碼:
# typing effect
typing_effect:
colorful: true # 禮花特效
shake: false # 震動特效
在 themes/next/layout/_layout.swig
文件 body 標籤中添加如下代碼:
...
{% include '_custom/custom.swig' %}
</body>
</html>
網站運行時間
在主題自定義配置 themes/next/layout/_custom/custom.swig
文件中添加如下代碼:
{# 頁腳站點運行時間統計 #}
{% if theme.footer.site_runtime.enable %}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/moment-precise-range.min.js"></script>
<script>
function timer() {
var ages = moment.preciseDiff(moment(),moment({{ theme.footer.site_runtime.since }},"YYYYMMDD"));
ages = ages.replace(/years?/, "年");
ages = ages.replace(/months?/, "月");
ages = ages.replace(/days?/, "天");
ages = ages.replace(/hours?/, "小時");
ages = ages.replace(/minutes?/, "分");
ages = ages.replace(/seconds?/, "秒");
ages = ages.replace(/\d+/g, '<span style="color:{{ theme.footer.site_runtime.color }}">$&</span>');
div.innerHTML = `{{ __('footer.site_runtime')}} ${ages}`;
}
var div = document.createElement("div");
//插入到copyright之後
var copyright = document.querySelector(".copyright");
document.querySelector(".footer-inner").insertBefore(div, copyright.nextSibling);
timer();
setInterval("timer()",1000)
</script>
{% endif %}
在 themes/next/layout/_layout.swig
文件 body 標籤中添加如下代碼:
...
{% include '_custom/custom.swig' %}
</body>
</html>
在主題主題配置文件 themes/next/_config.yml
中添加如下內容:
footer:
...
+ # Web Site runtime
+ site_runtime:
+ enable: true
+ # Specify the date when the site was setup
+ since: 20191124
+ # color of number
+ color: "#1890ff"
然後在文件 themes\next\languages\zh-CN.yml
中補全對應文案:
footer:
powered: "由 %s 強力驅動"
theme: 主題
# total_views: 總訪問量
# total_visitors: 總訪客量
total_views: "歷經 %s 次回眸才與你相遇"
total_visitors: "我的第 %s 位朋友"
+ site_runtime: "我已在此等候你"
文章閱讀量 - LeanCloud
LeanCloud 能夠給每篇博客統計訪問量的工具。首先註冊並登錄 LeanCloud。
LeanCloud 官網:https://www.leancloud.cn/ 。
- LeanCloud 應用配置
參考:https://github.com/theme-next/hexo-theme-next/blob/master/docs/zh-CN/LEANCLOUD-COUNTER-SECURITY.md
- hexo-leancloud-counter-security 插件安裝與配置
參考:https://github.com/theme-next/hexo-leancloud-counter-security
評論系統 - Valine
Valine 是一款基於 Leancloud 的快速,簡單和高效的無後端評論系統。
Valine 官網:https://valine.js.org/ 。
配置參考:https://theme-next.org/docs/third-party-services/comments#Valine
百度統計
登錄百度統計, 定位到站點的代碼獲取頁面。
複製 hm.js? 後面那串統計腳本 id,如圖:
編輯主題配置文件
,修改字段 baidu_analytics
, 字段值設置成你的百度統計腳本 id。
# Baidu Analytics
baidu_analytics: # <app_id>
收錄
百度收錄
- 添加站點
在 百度搜索資源平臺 中提交站點域名,勾選站點屬性,最後一步中同樣會要求驗證網站的所有權身份,選擇 CNAME 驗證,然後將給出的 ID 信息使用 CNAME 解析到 ziyuan.baidu.com
。
到 阿里雲 進行域名解析。
- 生成網站地圖
使用 npm 自動生成網站的 sitemap,然後將生成的 sitemap 提交到百度搜索引擎,輸入如下命令安裝 sitemap 插件。
npm install hexo-generator-sitemap --save
npm install hexo-generator-baidu-sitemap --save
在 站點配置文件
添加如下代碼:
# hexo sitemap
sitemap:
path: sitemap.xml
baidusitemap:
path: baidusitemap.xml
配置成功後,會生成 sitemap.xml
和 baidusitemap.xml
,sitemap.xml
一般提交給谷歌搜素引擎,baidusitemap.xml
一般適合提交百度搜索引擎。
提交百度 sitemap:
除了 sitemap 之外還提供了多種推送站點內容的方案:
- 主動推送:通過 API 接口推送站點內容,實時性較高。
- 自動推送:在網頁內添加 JS 腳本,每當頁面被訪問的時候會將頁面 url 推送給百度,比較被動。
- sitemap:填寫站點地圖文件地址,百度會週期性的抓取其中的內容進行分析收錄,收錄效率比較低。
- 手動提交:手動填寫鏈接地址進行收錄。
- 開啓主動推送
Hexo 中可以利用 hexo-baidu-url-submit 插件實現主動推送,在項目根目錄下輸入以下命令安裝依賴:
npm install hexo-baidu-url-submit --save
在 站點配置文件
中添加以下代碼:
# baidu SEO
baidu_url_submit:
count: 80 # 提交最新的一個鏈接
host: www.yifanstar.top # 在百度站長平臺中註冊的域名
token: <your token> # 請注意這是您的祕鑰, 所以請不要把博客源代碼發佈在公衆倉庫裏!
path: baidu_urls.txt # 文本文檔的地址, 新鏈接會保存在此文本文檔裏
在 站點配置文件
中修改部署策略:
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
-
type: 'git'
repo:
github: https://github.com/yifanzheng/yifanzheng.github.io.git
coding: https://git.dev.tencent.com/yifanzheng/blogs.git
branch: master
+ -
+ type: baidu_url_submitter
- 開啓自動推送
Next 主題中內置了開啓百度自動推送的選項,只需將其設置成 true 即可:
# Enable baidu push so that the blog will push the url to baidu automatically which is very helpful for SEO
baidu_push: true
谷歌收錄
在 Google Search Console 中提交站點域名,此時會提供幾種驗證網站所有權的方法,展開其他驗證方法中的 HTML 標記,然後將 meta 標籤的 content 屬性值複製到主題配置文件中:
# Google Webmaster tools verification setting
# See: https://www.google.com/webmasters/
google_site_verification: <content>
回到 Search Console 頁面點擊驗證按鈕,驗證成功後將進入控制檯,點擊左側 站點地圖 菜單,在域名後輸入 sitemap.xml
並提交,完成站點地圖的添加。
使用 Gulp 壓縮靜態資源
Gulp 是前端開發過程中對代碼進行構建的工具,是自動化項目的構建利器。不僅能對網站的資源進行優化,並且能在開發過程中能夠對很多重複的任務使其自動完成。
- 安裝 Gulp
npm install gulp -g
- 安裝 Gulp 的插件
# 安裝功能模塊
npm install gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-uglify gulp-imagemin --save
# 額外的功能模塊
npm install gulp-debug gulp-clean-css gulp-changed gulp-if gulp-plumber gulp-babel babel-preset-es2015 del --save
接下來在博客項目的根目錄下新建 gulpfile.js
文件,並複製下面的內容到文件中:
var gulp = require("gulp");
var debug = require("gulp-debug");
var cleancss = require("gulp-clean-css"); //css壓縮組件
var uglify = require("gulp-uglify"); //js壓縮組件
var htmlmin = require("gulp-htmlmin"); //html壓縮組件
var htmlclean = require("gulp-htmlclean"); //html清理組件
var imagemin = require("gulp-imagemin"); //圖片壓縮組件
var changed = require("gulp-changed"); //文件更改校驗組件
var gulpif = require("gulp-if"); //任務 幫助調用組件
var plumber = require("gulp-plumber"); //容錯組件(發生錯誤不跳出任務,並報出錯誤內容)
var isScriptAll = true; //是否處理所有文件,(true|處理所有文件)(false|只處理有更改的文件)
var isDebug = true; //是否調試顯示 編譯通過的文件
var gulpBabel = require("gulp-babel");
var es2015Preset = require("babel-preset-es2015");
var del = require("del");
var Hexo = require("hexo");
var hexo = new Hexo(process.cwd(), {}); // 初始化一個hexo對象
// 清除public文件夾
gulp.task("clean", function() {
return del(["public/**/*"]);
});
// 下面幾個跟hexo有關的操作,主要通過hexo.call()去執行,注意return
// 創建靜態頁面 (等同 hexo generate)
gulp.task("generate", function() {
return hexo.init().then(function() {
return hexo
.call("generate", {
watch: false
})
.then(function() {
return hexo.exit();
})
.catch(function(err) {
return hexo.exit(err);
});
});
});
// 啓動Hexo服務器
gulp.task("server", function() {
return hexo
.init()
.then(function() {
return hexo.call("server", {});
})
.catch(function(err) {
console.log(err);
});
});
// 部署到服務器
gulp.task("deploy", function() {
return hexo.init().then(function() {
return hexo
.call("deploy", {
watch: false
})
.then(function() {
return hexo.exit();
})
.catch(function(err) {
return hexo.exit(err);
});
});
});
// 壓縮public目錄下的js文件
gulp.task("compressJs", function() {
return gulp
.src(["./public/**/*.js", "!./public/libs/**"]) //排除的js
.pipe(gulpif(!isScriptAll, changed("./public")))
.pipe(gulpif(isDebug, debug({ title: "Compress JS:" })))
.pipe(plumber())
.pipe(
gulpBabel({
presets: [es2015Preset] // es5檢查機制
})
)
.pipe(uglify()) //調用壓縮組件方法uglify(),對合並的文件進行壓縮
.pipe(gulp.dest("./public")); //輸出到目標目錄
});
// 壓縮public目錄下的css文件
gulp.task("compressCss", function() {
var option = {
rebase: false,
//advanced: true, //類型:Boolean 默認:true [是否開啓高級優化(合併選擇器等)]
compatibility: "ie7" //保留ie7及以下兼容寫法 類型:String 默認:''or'*' [啓用兼容模式; 'ie7':IE7兼容模式,'ie8':IE8兼容模式,'*':IE9+兼容模式]
//keepBreaks: true, //類型:Boolean 默認:false [是否保留換行]
//keepSpecialComments: '*' //保留所有特殊前綴 當你用autoprefixer生成的瀏覽器前綴,如果不加這個參數,有可能將會刪除你的部分前綴
};
return gulp
.src(["./public/**/*.css", "!./public/**/*.min.css"]) //排除的css
.pipe(gulpif(!isScriptAll, changed("./public")))
.pipe(gulpif(isDebug, debug({ title: "Compress CSS:" })))
.pipe(plumber())
.pipe(cleancss(option))
.pipe(gulp.dest("./public"));
});
// 壓縮public目錄下的html文件
gulp.task("compressHtml", function() {
var cleanOptions = {
protect: /<\!--%fooTemplate\b.*?%-->/g, //忽略處理
unprotect: /<script [^>]*\btype="text\/x-handlebars-template"[\s\S]+?<\/script>/gi //特殊處理
};
var minOption = {
collapseWhitespace: true, //壓縮HTML
collapseBooleanAttributes: true, //省略布爾屬性的值 <input checked="true"/> ==> <input />
removeEmptyAttributes: true, //刪除所有空格作屬性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true, //刪除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true, //刪除<style>和<link>的type="text/css"
removeComments: true, //清除HTML註釋
minifyJS: true, //壓縮頁面JS
minifyCSS: true, //壓縮頁面CSS
minifyURLs: true //替換頁面URL
};
return gulp
.src("./public/**/*.html")
.pipe(gulpif(isDebug, debug({ title: "Compress HTML:" })))
.pipe(plumber())
.pipe(htmlclean(cleanOptions))
.pipe(htmlmin(minOption))
.pipe(gulp.dest("./public"));
});
// 壓縮 public/uploads 目錄內圖片
gulp.task("compressImage", function() {
var option = {
optimizationLevel: 5, //類型:Number 默認:3 取值範圍:0-7(優化等級)
progressive: true, //類型:Boolean 默認:false 無損壓縮jpg圖片
interlaced: false, //類型:Boolean 默認:false 隔行掃描gif進行渲染
multipass: false //類型:Boolean 默認:false 多次優化svg直到完全優化
};
return gulp
.src("./public/medias/**/*.*")
.pipe(gulpif(!isScriptAll, changed("./public/medias")))
.pipe(gulpif(isDebug, debug({ title: "Compress Images:" })))
.pipe(plumber())
.pipe(imagemin(option))
.pipe(gulp.dest("./public"));
});
// 執行順序: 清除public目錄 -> 產生原始博客內容 -> 執行壓縮混淆 -> 部署到服務器
gulp.task(
"build",
gulp.series(
"clean",
"generate",
"compressHtml",
"compressCss",
"compressJs",
"compressImage",
gulp.parallel("deploy")
)
);
// 默認任務
gulp.task(
"default",
gulp.series(
"clean",
"generate",
gulp.parallel("compressHtml", "compressCss", "compressImage", "compressJs")
)
);
//Gulp4最大的一個改變就是gulp.task函數現在只支持兩個參數,分別是任務名和運行任務的函數
以後在部署時,只需要每次在執行 generate 命令後執行 gulp 就可以實現對靜態資源的壓縮,壓縮完成後執行 deploy 命令同步到服務器:
hexo g
gulp
hexo d
參考
https://juejin.im/post/5dd2e898e51d45400206a466#heading-0
https://juejin.im/post/5bebfe51e51d45332a456de0#heading-0