NexT 主題升級折騰紀錄 (v8.18.0)
更新部落格的 NexT 主題到 v8.18 了,只能說是折騰。
升級緣由
發現自己的部落格,遇到大量圖片的時候,會有效能不佳的問題。
大量圖片最簡單的解法就是 Lazyload (當閱讀進度接近某個區塊時,才將對應圖片載入)
升級前使用的是 NexT v7.8.0,其實也不算太舊,但是 _config.yml 打開了此選項還是不成功。
我首先是思考,
是不是 "我的拿 Google Drive 當圖空" 這件事情導致如此 (怕 G 社有做預處理攔截)
於是我跑去看 NexT 所使用了第三方套件 lozad.js
clone repo 並且修改 demo file (替換圖片),其結果是運作正常。
那我也只能試著升級 NexT 看看了 🥲
踩坑 - 嘗試階段
我是這樣去嘗試的 (先看故事就好) :
- 更新 Hexo 到 6.3.0
- 把舊的 themes/NexT 資料夾重新命名成任意名字
直接下載最新版本的 NexT 並放到 themes 之中 (名字改成 NexT)。 hexo s
,啟動看看。
然後就炸掉了,文章跑不出來,sidebar 也跑不出來。
打開開發人員選項,是顯示 next-boot.js 中有 function 無法正確載入。
並且 terminal 也顯示有 highlight.js 有過時的跡象。
接下來是 debug,首先更新所有套件(除了 hexo)
然後建立一個新的 hexo project,並且檔案一個個放進去,去找出 "放了哪個檔案後 crash"。
經過了血與淚,我找到了問題原因
並且很多以前做的魔改也跟著失效了,所以後面也會闡述如何將他們救回來。
正確流程
- 更新 Hexo,我個人是只想先使用 hexo 6.3.0 就好了 (覺得最新版可能不穩,還在 rc)
- 指令 :
npm install hexo@6.3.0
- 指令 :
- 安裝一些新套件
1 | npm i js-yaml css |
- 使用
npm outdated
來更新所有 plugin
其中,我誠摯的推薦先更新下面三個。
1 | npm update highlight.js hexo-util hexo-cli |
更新好這三個之後,再使用
npm outdated
來顯示哪些過時的
並且red 一個個複製名稱 來更新 (npm update
)。
如果再次使用npm outdated
來看仍然沒更新,有可能被 package-lock 影響了
重複多次之後我自己是乾脆砍了然後重裝。NexT 的主題更新,我一律推薦從官方最新的 repo 去下載。
或是使用我們熟知的git clone <git address>
也行。
然後把你舊的 next 的資料夾改名成其他 (例如 next-old)。
上述的下載後,他的資料夾名稱可能是hexo-theme-next
之類的
改成你喜歡的例如next
(對應到你 hexo config 設定的那個)- 這邊科普一下,NexT 會根據專案技術債去決定是否開新的 repo 來維護
例如 8.0 版本就是直接開一個新的了,所以很多東西無法直接繼承。
這部分可以去看 NexT Upgrade
- 這邊科普一下,NexT 會根據專案技術債去決定是否開新的 repo 來維護
如果你在舊版有使用任何 data injection
也就是/hexo-root/source/_data
內有東西,推薦先將此資料夾搬走
或是改名稱為_x_data
之類的。因為測試 NexT 是否相容不要有太多危險因子。
另外還有一個巨大的危險因子,就是/hexo-root/source/js
。
在我們學會 data injection 之後,以前魔改時這也是重點開發區域之一
如果存在,建議先移動到安全位置。做完以上,可以先使用
hexo s
測試。
如果你裝了很多 hexo plugin,可能某些文章無法正常渲染,
也建議將它們都先搬到/hexo-root/source/_draft
。一般來說,
你應該會是 "沒有應用 next config 也沒有太關鍵的 data injection 狀態"
所以很安全、至少會開啟一個很陽春的 hexo blog,文章可以正常瀏覽。那你說,"啊我的 data injection 怎辦 ? 我套用的 custom css 呢 ! config 呢 !"
這個會在下文中一一說明。
客製化修改
關於 next 的 _config.yml
我們先複習一下以前是怎麼做的。
- 最以前的版本 : 直接在
/hexo-root/themes/next/_config.yml
修改 - 啟用 data injection 的版本 : 複製了一份 _config.yml,更名成 next.yml
並且放到/hexo-root/source/_data/next.yml
,然後內部會有選項override: true
然而,最新版本的作法是
- 從
/hexo-root/themes/next/_config.yml
複製到根目錄,並重新命名 :/hexo-root/_config.next.yml
(希望你們能直接看懂,我這種寫法出現好幾次了,看不懂再留言給我)
當然,這邊的 next 資料夾已經是最新版本了,也就是你複製的 _config.yml
是最新版。
那我該如何整合舊版本的到新版呢 ?
- 先知道自己是哪個時代的
是直接改在/hexo-root/themes/next/_config.yml
?
還是/hexo-root/source/_data/next.yml
此檔案存在 ? - 做一次
/hexo-root/themes/next/_config.yml
複製到根目錄,並重新命名 :/hexo-root/_config.next.yml
- 利用一些比對工具,例如 Diff checker 去比對舊版 config 和新版的差異。
然後編輯/hexo-root/_config.next.yml
,把一些舊設定也跟著填寫上去。
這樣做的用意是新版本的 _config.yml
是有可能有新東西的,不要忽略他們。
關於 data injection: _data 篇
_data 中,用來存放一些 injection files,例如 body-end.swig
, styles.styl
。
首先,在 NexT v8.x 版本中,已經不使用 .swig
了。全數使用 .njk
。
(.styl
仍然保留 !)
我看了一下我自己應用的,大多數是嵌入一些 js 或是知名的 sidebar 魔改
在簡單的應用上,語法基本沒差
所以我索性將 .swig
檔案都全複製一份,並且副檔名改掉。
但是,如果有 next.yml
存在,請另行備份,因為這個用法已經被捨棄了。
如果你想要確保這部分可以 work,首先你要確認你的 _config.next.yml
1 | custom_file_path: |
然後我前面給的建議是先將 _data
資料夾改名成 _x_data
,那現在就可以改回去了。
去測試看看吧 !
關於 data injection: js 篇
只要是放在 /hexo-root/source
中的檔案,基本上除了底線開頭有特殊用途
一般來說 ... 會全部複製一份到對應的 generated folder。(也就是 /hexo-root/public
)
所以如果我在 /hexo-root/source/js
內,放了一個跟原始碼一模一樣名字的 js file
那我這邊就會覆蓋掉原始檔,是有可能讓網頁 crash 的。
所以你必須知道你放的檔案是什麼、用途又是什麼、
以及到底是不是從對應版本的對應檔案去做修改的
(你總不能拿 v7.0 的 util.js
,放在 js 資料夾內,又期望它可以在 v8.10 中運作。)
所以這邊要做的事情是 :
- 先去看你以前
寫了什麼鬼東西,理解用途 (註解的重要性 🫠) - 複製你現在期望版本 (例如你現在 /themes/next 那個最新的版本) 裡面的檔案出來
記得是 "複製" 到/hexo-root/source/js
,檔名不變,然後將修改放進去
(修改要改到對的位置。建議可以從前後的 function 去推斷哪邊才是對應位置)
一般來說,只要你改的是你懂的東西,它應該會運作,除了一種可能性 :
- 如果舊的 function 被完全棄用了 (例如
wrapImageWithFancyBox
這個 function)
在這種狀況之下,你強行去添加 js code 到新版文件之中,有可能是一種厄介行為。
那就是會吃 crash。所以請理解你修改的東西,並且找到其突破點。
關於找突破點,下面會討論 fancybox 魔改,可以參考看看。
小總結一下,如果你改的正確,那 js 除了可以成功注入,網站也不會 crash。
以上,我們已經做了 : config 繼承、_data 檔名修正並添加回來、js 更新並添加回來。
其實應該完成了大部份的修改
--- 但是還是有一些問題,例如新舊技術不同、或是 class selector 失效。
關於 nofancybox 的設置
(Tutorial: Disable fancybox for specific images.)
想要閱讀完整教學、突破點,建議查看我發在 github discussion 的討論串 (中文)
https://github.com/next-theme/hexo-theme-next/discussions/687
以下會結錄部分內容。
- 為何需要 nofancybox
有了 fancybox,我們可以將圖片放大、在下面設置一些 caption、使用左右來瀏覽圖片。
但是,有一些圖片因為某些原因,我們就是不希望他套用。
例如這個這是一個應用方法 (把自己的圖片當成 emoji,緊跟在文字尾端。)
這類的圖片就不適合被套用 fancybox。所以,我們總要想個辦法來實現這件事情。
- 嘗試的辦法
- 以前怎麼做的我就怎麼做,首先使用 injection 方法,在
/hexo根目錄/source/js/
建立utils.js
並且先拷貝/next/source/js/utils.js
的全部內容,然後把wrapImageWithFancyBox: function() {}
都貼到合理位置。
但這並不會成功。- 我的想法是,可能這個 function 沒有被觸發 (搜了整個專案沒看到 wrapImageWithFancyBox 的觸發點)。
所以看了一下,得想辦法讓他在/next/source/js/next-boot.js
中去觸發。
所以我添加了CONFIG.fancybox && NexT.utils.wrapImageWithFancyBox();
在合理位置,畢竟以前版本也是類似這樣寫的。
但這並不會成功。- 用 console.log 稍微 debug 一下,發現
CONFIG.fancybox
是undefined
呀。
自己試了老半天,明明_config.next.yml
已經是fancybox: true
了,怎麼還這樣。
我自己的推斷是 CONFIG 在 assign 的過程中並沒有把 fancybox 當作 key 來讀入。
源碼看了老半天也沒看懂在哪邊 assign 的,歡迎開發組補充解惑。
不過讀不到,小事情,CONFIG.fancybox && NexT.utils.wrapImageWithFancyBox();
直接改成NexT.utils.wrapImageWithFancyBox();
,我牛逼。
但這並不會成功。 然後圖片全部都不顯示了 (等於 fancybox 套用過程中失敗)
- 正確的作法
- 首先一樣要善用 injection 方法,在
/hexo根目錄/source/js/third-party/
建立fancybox.js
。- 把
/next/source/js/third-party/fancybox.js
內的東西全部複製過去。- 安插一段 code 進去 (不含註解的話,三行)
1 | // 前面省略了一些 code |
這樣就完成了。
不過,雖然都已經用 injection 的方式了,還是推薦像我一樣寫自己的 ID 在註解之中
這樣以後忘記自己寫了、改了什麼東西之後,就會方便一點找 ...
以上就是突破點與解決辦法,希望能提供一些啟發。
如何讓文章背景畫布變成半透明顏色
如果沒意外,目前我的部落格應該仍然是半透明的背景。(相較於 default 的純白背景)
舊版的修改方式是在 source/_data/styles.styl
中加入
1 | .post-block { |
但是新版並不 work,而且打開 F12,會發現它被槓掉了 (被呈現刪除線)。
找了老半天,總之,它是被新版的 main.css 給統一控制了顏色
我們可以觀察到他使用了 var
去控制,這就讓我想到之前看過的一些線索
於是我們去 _config.next.yml
啟用(反註解) variable: source/_data/variables.styl
並且建立一份 /hexo-root/source/_data/variables.styl
,填入以下
1 | $content-bg-color = rgba(255, 255, 255, 0.9); |
完成 !
- 我提到的線索,是這兩篇 :
關於 Blog 首頁的 read more (閱讀更多) 顯示的摘要
- 舊版 : 我們只要不啟用 auto_excerpt 之類的
只要在文章內使用<!-- more -->
進行分隔 (Hexo 自帶的 feature)
就可以成功的將文章分隔的前半段顯示在首頁。 - 新版 : 如果我們在 config 內啟用
excerpt_description: true
那他就會使用 markdown 屬性的 description 欄位進行渲染。
這十分不人性 !
因為 markdown 的 description 欄位是為了拿來做 SEO
所以我個人極度推薦在文章內使用 <!-- more -->
進行分隔
並且把此選項變成 false
,這樣就能正確的顯示摘要了。
相關的解釋在官方文檔 : https://theme-next.js.org/docs/theme-settings/posts
關於魔改 Sidebar 的 "近期文章"
這邊給一些關鍵字,因為這方法其實和其他人做法一樣
怕有人不知道,所以簡單貼一下 Code for sidebar.njk
實際上,把裡面的程式碼拿去 Google,應該就能找到其他人的介紹了。
1 | {% if theme.recent_posts %} |
關於魔改 Sidebar 的滾動條(scrollbar) CSS
如果我還是使用 Hexo + NexT,
那你可以在我的左邊查看我的個人近期新文章等等資訊。
如果文章內看不到、點了 tab 也沒找到,可以到首頁,並且往下滑動一部分
可以看到我個人介紹的部分的滾動條是一個漸層顏色 (我自己看了很開心)
然而新版本並不 work,我渾身不對勁。(預設是 html 純純的灰色超寬的那種)
這邊也不拖沓了,簡單來說以前可以使用 site-overview-wrap
去定位 css
現在必須去找 sidebar-panel-container
去定位。
1 | /* Next 7.8.0: use site-overview-wrap to catch scrollbar */ |
關於 Sidebar 的友站連結
這個設定,在以前會像下方的左圖那樣顯示在 Sidebar 裡面。
(next.yml
中的 links 屬性)
現在呢,如右圖,官方把他額外做一個區域,我是覺得挺美的。
然而,他會在文章/首頁滾動到底部的時候才被加進去。
這點就有一點見仁見智了。
如果喜歡以前的做法,可以去參考 v7.8 的 sidebar.swig
並且想辦法對 sidebar.njk
進行魔改 (注入文件)
不過我覺得新版也沒特別不好,就沒去研究了。
順帶一提,即使我們在 config.links_settings.title 設定為 "友站連結",他仍然不 work。
我自己魔改了一下把這段修正
1 | <div class="links-of-blogroll-title"> |
這樣就能了。
不過我覺得這是官方疏失,找時間我再去反饋吧。
關於 hexo-tag-mmedia
作者棄坑了。然後推薦使用者們去用他另一個 plugin
我點了進去,他又說那個 plugin 他(也)棄坑了,
說可以去用這個 https://plugin-components.vuejs.press/
我還沒開始研究。
Hexo 不能使用 Aplayer 有點傷,我已經把我其中一兩篇文章的音樂連結砍了。
關於那些我還沒研究的功能
隨著 NexT 的更新,肯定有新的東西加入 (吧)
config 也多了很多我沒看懂的東西,這邊筆記一下,之後太閒可以研究一下是幹嘛用的。
1 | https://hexo.io/docs/helpers#open-graph |
結語
很累。
有很多零碎改過的東西,其實不知道有沒有全都繼承 (到這篇打完都還不知道)
但至少我直覺/外觀上有想到的都解決了
也總算解決了一個逃避一陣子的事情 :
一直覺得 lazyload 沒啟用的話,會不時的導致 image loading crash (太多 request,被圖空砍)
間接的讓使用者體驗不佳,那我就會十分的傷心
(因為我放圖片一定是篩選過的,而放很多的話,那必定是希望能分享美好事物)
很多魔改都是我私人的喜好
他沒辦法被繼承到新版本的話我真的會很痛苦。
很開心解決了他們,也希望能幫助到大家 !