序曲:
在 Emlog 經歷數次伺服器死亡之後,我開始尋找穩定性高的方案。
我將目光看向了純靜態頁面的 Hexo,可以免卻 SQL資料庫 管理的繁瑣。
不過,Git 是什麽?我該如何部署?這些特殊名詞如何去理解?這些,都是一道道難題。
現在距離 Hexo 建站之初已有半年之久,我將盡力去回憶每一處過程並記錄。當然,這不是教學。
準備:
若不隨意更改核心軟體的安裝路徑,便可避免許多未知的錯誤。
Node.js 和 Git 均為如此。VSCode?本質上是 Hexo 的管理器罷了。
01.Node.js的安裝
02.選擇Windows Installer X64.msi下載並安裝;
03.按照默認路徑&選項安裝,以規避無法部署的風險;
04.CDM鍵入 “node -v” 進行驗證,若出現版本訊息即為安裝成功。
02.Git的安裝
03.按照默認路徑&選項安裝,以規避無法部署的風險;
04.CDM鍵入 “git –version” “node -v” “npm -v” 進行驗證,若出現版本訊息即為安裝成功。
03.VSCode的安裝
02.選擇 Windows X64 下載並安裝,路徑可隨意選擇盤符;
P.S.: VSCode 本質上作為 Hexo 的管理器存在,頁面編輯和終端部署均可在其中完成。
部署:
部署包括Hexo的本地部署和 Github 的通信部署。
本地部署仍需遵循不隨意變動默認安裝目錄的準則。
若 SSH 無法使用,那麽切換為 HTTPS 也是一個不錯的方法。
01.Hexo的安裝
01.打開 VSCode,啟動 Gitbash 終端;
02.在終端中鍵入以下指令,若提示鍵入新指令則安裝完成;
03.在 C:\Users<用戶名> 路徑創建資料夾,用以存放Hexo本地檔案;
04.在終端中鍵入 “cd <01步驟創建的文件夾名>”,意為進入 03 步驟創建的目錄;
05.在終端中鍵入以下指令,若提示鍵入新指令則安裝完成;
06.在終端中鍵入以下指令進行驗證,若出現版本訊息即為安裝結束。
06.在終端中鍵入 “hexo clean && hexo g && hexo s”,訪問終端出現的連結,若正確訪問即成功。
P.S.: 若安裝路徑不為默認,Bash 終端將在下一次重載系統後無法調用 Hexo 指令。
02.Github的部署
01.鍵入以下指令,安裝推送部署擴展;
1
| npm install hexo-deployer-git --save
|
02.打開 _config.yml 文件,修改 deploy 為如下配置;
1 2 3 4
| deploy: type: git repository: [email protected]:Magstic/magstic.github.io.git branch: main
|
04.若出現文件路徑,則 Enter 兩次,鍵入如下命令,複製密鑰至剪貼板;
1
| clip < ~/.ssh/id_rsa.pub
|
05.訪問 Github - Settings - SSH and GPG Keys,將剪貼板上的密鑰添加至 SSH key;
06.創建名為 magstic.github.io 的 Repositories,勾選 Public 和 Add a README file;
07.進入 06 創建的 Repositories,Settings-Page-Branch,選擇 main 分支。
進入 06 創建的 Repositories,Settings-Page-Custom domain,連結域名並使用 HTTPS;
09.鍵入以下指令,使用個人信息鏈接 Github;
1 2
| git config --global user.name "Magstic" git config --global user.email "[email protected]"
|
10.鍵入以下指令,鍵入 yes,若出現 Hi Magstic… 則通信成功。
寫作:
個人在寫作中的常用指令。建立新的貼文無需指令,複製即可。
寫作時會遇見子頁面的需求。新建貼文不是好的方法,因此需要自由頁面。
自由頁面並非真正意義上的子頁面——不過,它仍可以被本地搜索引擎檢索。
01.常規指令
清理緩存檔案
生成靜態頁面
部署至本地訪問
部署至Git訪問
一系列常用的組合指令
1
| hexo clean && hexo g && hexo s
|
1
| hexo clean && hexo g && hexo d
|
02.自由頁面
什麽是“自由頁面”?
Hexo 默認渲染通用路徑下的頁面,有時候會為自定義 Html 帶來困擾。
因此,我們需要使頁面規避抑或進行 Hexo 的渲染,以使最終頁面的結構合理。
打開 _config.yml 文件,修改 Directory 的 skip_render 項。
Skip_Render 意為“略過渲染”,在這裡可以使用 Glob表達式 配對路徑。
“source”為資源路徑,在渲染後 source 中的内容會出現在靜態頁的根目錄。
故修改路徑時略過 source,直接填寫其下的子資料夾或者文件名即可。
這是一些例子:
我不想令指定路徑下的一個html被渲染!
1 2
| skip_render: - "html/aojiru/coll.html"
|
我不想令指定路徑下的全部html被渲染!
1 2
| skip_render: - "html/aojiru/*"
|
03.其他事項
合理安排資源路徑比其他任何事情都重要。
不論自己能否記清每一檔案的明細,都應做好分類。
此外,Hexo 是輕量化的靜態頁,應避免在 source 中直接上載媒體資源。
當然,這涉及優化,將在最後一個環節中去總結。
美化:
我喜歡極簡,但是極簡亦會使 Hexo 失去美感。
Butterfly 無繁雜動態效果的同時,也提供了諸多的美化策略。
功能上,檢索與評論功能并不被原生的 Hexo 支持,我們需要擴展。
01.Butterfly
Butterfly 是 Hexo 的一個主題,由 Jerry 開發。
Butterfly Doc已囊括 90% 的美化策略,我將在下面記錄該 site 上所應用的策略。
1
| npm install hexo-theme-butterfly
|
主題被安裝到該路徑:node_modules/hexo-theme-butterfly
打開 _config.yml 文件,修改 theme 以應用主題。
1
| npm install hexo-renderer-pug hexo-renderer-stylus --save
|
透過 npm 安裝的内容均在 node_modules 目錄下,這不便於管理配置檔。
首先,打開該路徑,複製 config 文件的全部内容:node_modules/hexo-theme-butterfly/_config.yml;
然後,回到根路徑下建立 _config.butterfly.yml 檔案,將複製的内容貼在該檔案上並保存;
最後,可直接使用根路徑下的 _config.butterfly.yml 檔案配置主題,優先級>主題路徑下的 _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 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
| nav: logo: display_title: true fixed: false
menu: 歸類: /categories/ || fas fa-folder-open 關於: /about/ || fas fa-paper-plane 足跡: /message/ || fas fa-shoe-prints
favicon: https://magstic.art/images/avatar.jpg
avatar: img: https://magstic.art/images/avatar.jpg effect: false
disable_top_img: true
error_404: enable: true subtitle: '站點重建中,請訪問主頁。' background: https://s2.loli.net/2023/05/12/V8LgEuI6CnvYe7F.png
post_meta: page: date_type: created date_format: date categories: true tags: false label: true post: date_type: both date_format: date categories: true tags: true label: true
photofigcaption: false
copy: enable: true copyright: enable: false
toc: post: true page: false number: true expand: false style_simple: false scroll_percent: true
post_copyright: enable: false decode: false
footer: owner: enable: true since: 2020 custom_text: copyright: true
aside: enable: true hide: false button: true mobile: true position: right display: archive: true tag: true category: true card_author: enable: true description: button: enable: true icon: fab fa-google text: Gmail link: mailto:[email protected] card_recent_post: enable: true limit: 2 card_archives: enable: false card_webinfo: enable: false post_count: true last_push_date: true
darkmode: enable: true
|
- 調整主題檔
控制avatar不被滑鼠動作響應。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| //node_modules\hexo-theme-butterfly\source\css\_layout\aside.styl .avatar-img overflow: hidden margin: 0 auto width: 110px height: 110px border-radius: 70px
img width: 100% height: 100% transition: filter 0ms ease-in .0s, transform .0s object-fit: cover
&:hover transform: rotate(0deg)
|
02.星空背景
網路流行的星空背景,我進行了螢火蟲化。
1 2 3 4 5 6 7
| //_config.butterfly.yml inject: head: - <link rel="stylesheet" href="/css/universe.css"> bottom: - <canvas id="universe"></canvas> - <script defer src="/js/universe.js"></script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| //node_modules\hexo-theme-butterfly\source\css\universe.css #universe{ display: block; position: fixed; margin: 0; padding: 0; border: 0; outline: 0; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; z-index: -1; }
|
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
| function fireflies() { window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
var canvas = document.getElementById("universe"), ctx = canvas.getContext("2d"), fireflies = [], numFireflies = 50, fireflySpeed = 0.2, fireflySize = 1, fireflyOpacityMin = 0.2, fireflyOpacityMax = 0.5;
canvas.width = window.innerWidth; canvas.height = window.innerHeight;
window.addEventListener("resize", function() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; });
function Firefly() { this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.dx = (Math.random() < 0.5 ? -1 : 1) * fireflySpeed; this.dy = (Math.random() < 0.5 ? -1 : 1) * fireflySpeed; this.color = "rgba(255, 215, 0, " + (Math.random() * (fireflyOpacityMax - fireflyOpacityMin) + fireflyOpacityMin) + ")"; this.flashing = false; this.flashSpeed = Math.random() * 0.2 + 0.5; }
Firefly.prototype.update = function() { this.x += this.dx; this.y += this.dy;
if (this.x < 0 || this.x > canvas.width) this.dx *= -1; if (this.y < 0 || this.y > canvas.height) this.dy *= -1; };
Firefly.prototype.draw = function() { ctx.beginPath(); ctx.arc(this.x, this.y, fireflySize, 0, 2 * Math.PI); ctx.fillStyle = this.color; ctx.fill(); };
function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < fireflies.length; i++) { var firefly = fireflies[i]; firefly.update(); firefly.draw(); }
requestAnimationFrame(animate); }
for (var i = 0; i < numFireflies; i++) { fireflies.push(new Firefly()); }
animate(); }
fireflies();
|
03.本地檢索
本地檢索是靜態 BLOG 的必備之物。
1
| npm install hexo-generator-search --save
|
1 2 3 4 5 6 7
| local_search: enable: true preload: false top_n_per_article: 0 unescape: false CDN:
|
04.摺叠擴展
Hexo 的摺叠擴展不被 Lazyload 規則響應,這不利於優化。
hexo-sliding-spoiler雖不完美,但在優化面前,必須取捨。
1
| install hexo-sliding-spoiler --save
|
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
| //node_modules\hexo-sliding-spoiler\assets\spoiler.css .spoiler { margin: 5px 0; padding: 0 15px; border: 0.5px solid #4e4e4e80; position: relative; clear: both; border-radius: 3px; }
.spoiler .spoiler-title { background: #4e4e4e60; margin: 0 -15px; padding: 5px 15px; color: #ffffff; font-weight: bold; font-size: 13px; display: block; cursor: pointer; }
.spoiler .spoiler-title:before { font-weight: bold; }
.spoiler.collapsed .spoiler-title:before { content: "▶ "; }
.spoiler.expanded .spoiler-title:before { content: "▼ "; }
.spoiler .spoiler-content { padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0; -moz-transition-duration: 0.1s; -webkit-transition-duration: 0.1s; -o-transition-duration: 0.1s; transition-duration: 0.8s; -moz-transition-timing-function: ease-in-out; -webkit-transition-timing-function: ease-in-out; -o-transition-timing-function: ease-in-out; transition-timing-function: ease-in-out; }
.spoiler.collapsed .spoiler-content { overflow: hidden; max-height: 0; }
.spoiler.expanded .spoiler-content { max-height: 8000px; overflow: hidden; }
.spoiler .spoiler-content p:first-child { margin-top: 0 !important; }
|
05.留言系統
該 BLOG 使用Twikoo進行 Netlify + MongoDB 部署。
MongoDB 的 Free Instance 對於一個BLOG的評論區域足矣。
我不推薦使用圖像系統,因為依賴於第三方圖床的服務並不穩定。
優化:
我不想使用 Loading 動畫,因此我需要使用 Lazyload。
01.Lazyload
使用 Butterfly 原生的 Lazyload 即可,因為擴展並不穩定。
為了評論區能夠在大陸地區正常訪問,我關閉了評論的 Lazyload。
1 2 3 4 5 6 7 8 9 10 11
| //_config.butterfly.yml
comments: lazyload: false
lazyload: enable: true field: post placeholder: blur: true
|
02.Google Search Console
我不希望 Baidu 收錄我,因此我使用Google Search Console進行管理。
Baidu 是最大的中文檢索引擎,但其 Console 無比糟糕;因此,我注銷了賬戶。
我也不希望一些内容被百度索引。因此,我使用 Cloudflare 的 Rules 拒絕了一切百度的 Spider。
03.Cloudflare
Cloudflare 的面板無比簡潔友好。
我主要使用 域管理、WAF 以及 R2存儲桶。
我使用 Art 域進行 Blog 管理,Top 域進行資源管理。
Git 無比方便,我無法捨棄 Git Pages 去使用 CF Pages。
如果我使用 Actions,這會使部分 CSS 無法被渲染,同時 BLOG 的時間綫會紊亂。
……總之,我需要使 DNS 解析至 Github。
1 2 3 4 5
| 【A】185.199.111.153 【A】185.199.110.153 【A】185.199.109.153 【A】185.199.108.153 【CNAME】magstic.github.io
|
Cloudflare 的 Proxy 在大陸地區亦可獲得不錯的訪問速度。
我使用 Cloudflare 的 WAF 設置防火牆規則。
為了 Site 的安全,我不會釋放全部的 WAF 規則。
網路安全
- WAF
- 建立規則
1 2 3 4 5
| 【使用者代理程式】 【包含】python-requests 【Or】Go-http-client 【Or】baidu ……
|
我使用 R2 存放 Blog 的檔案。
我過去使用七牛雲,但服務極度不穩定。
R2提供的 Free Plan 無比優惠,這使我無比心動。
我使用 top 域綁定了存儲桶,起源是我沒有想到 CF 提供免費的 SSL 服務。