部落格改版

好一陣子沒有更新部落格了,之前的工作都主要是內部分享,大部分的筆記也都寫在內部的 wiki 上。最近看了一下 Lighthouse 的分數,發現分數頗低,一開始想直接分析列出的問題逐一解決掉,但感覺沒有什麼效率,雖然可以練習,但懶惰的我還是直接換一個 Theme 吧。

這次選了一個 hexo-theme-Claudia 的佈景主題,如同目前正在看的畫面,風格還滿簡潔的,有興趣的話可以去看看。

關於圖片標記問題

Hexo 支援了 asset_img 語法來插入圖片,但我個人還是偏好使用 Markdown 的語法。因此,我考慮將 Hexo 內建的圖片插入語法轉換成 Markdown 語法。畢竟在未來若要更換主題時,大多數主題都使用 Markdown 語法來插入圖片。雖然繼續使用 Hexo 內建的語法也能正常運作,但隨著文章越來越多的,在管理上可能會變得越來越不方便。

Hexo 內部支援的標記功能是長這個樣子:

{% asset_img [title] [path] [width] [height] [link] %}

但大部分的 Theme 都以 Markdown 的方式呈現:

![title](path)

另外圖片存放的位置預設是在 _posts 底下,會產生跟文章檔案名稱相同的資料夾,我覺得隨著文章越來越多,會越來越難管理,所以我把圖片移動到 source/images 底下,並且把圖片的路徑改成 images/文章檔名/圖片檔名

手動逐一改的話就要花很多時間在這上面,所以直接寫個腳本來快速轉換吧。

轉換 script

轉換的邏輯主要是透過正規表達式來做,主要的步驟有:

  1. 指定要轉換的資料夾
  2. 找出所有的 Markdown 檔案
  3. 逐一讀取檔案內容
  4. 透過正規表達式來找出 Hexo 內建的標記語法
  5. 如果已經有存在的 Markdown 語法,就只改圖片的路徑
  6. 將找到的內容轉換成 Markdown 的語法
  7. 將轉換後的內容寫回檔案

基於上面的流程就寫了一個 script 做轉換:

const fs = require('fs-extra');
const path = require('path');
const fg = require('fast-glob');

const postsPath = 'source/_posts'; // 要轉換的 md 文件所在的目錄

(async () => {
  try {
    const files = await fg(`${postsPath}/**/*.md`);

    files.forEach(async (file) => {
      try {
        const fileContent = await fs.readFile(file, 'utf8');
        const dirname = path.dirname(file);
        const basename = path.basename(file, '.md');

        const assetImgRegex = /{%\s*asset_img\s+(.*?)\s+(.*?)\s*%}/g;
        const mdImgRegex = /!\[(.*?)\]\((.+?)\)/g;

        const convertAssetImg = (match, filename, description) => {
          return `![${description}](images/${basename}/${filename})`;
        };

        const convertMdImg = (match, description, filename) => {
          if (!filename.startsWith('images/')) {
            return `![${description}](images/${basename}/${filename})`;
          } else {
            return match;
          }
        };

        const newFileContent = fileContent
          .replace(assetImgRegex, convertAssetImg)
          .replace(mdImgRegex, convertMdImg);

        await fs.writeFile(file, newFileContent, 'utf8');
        console.log(`成功轉換:${file}`);
      } catch (error) {
        console.error(`處理文件 ${file} 時出錯:`, error);
      }
    });
  } catch (error) {
    console.error('讀取文件列表失敗:', error);
  }
})();

將轉換後的檔案確認及整理

轉換完成之後,我是直接用 Git 來確認被修改的部分,發現了幾個問題:

  1. 圖片如果是外部網址
    早期文章是直接找圖床然後帶入圖片網址,所以初步轉換之後會變成像這樣:
![title](images/文章檔名/https://example.com/image.png)

還好這些問題是早期用 logdown 寫的文章,所以沒有太多的圖片需要處理,隨手改一下即可。

  1. Hexo 的標記語法有多餘的參數
    內建的標記語法可以指定圖片的寬高,或是圖片的文字描述,但 MD 語法只有單純的 title,所以轉換之後就會變成像這樣:
![900 "'title'" "'description'"](images/文章檔名/image.png)

不過受影響的圖片也沒有太多,所以也是隨手改一下即可。真的很多的時候就要根據上面的 script 進一步修改了。

換主題後的效果

最後改完重新跑一次 LightHouse:
更新之後的分數
分數相當的不錯,不過要到滿分的話還有一些細節問題需要調整,這後面有時間再處理了。

另外太久沒看 CI,發現 TravisCI 沒有免費的服務了,所以又花了一點時間把 CI 轉移到 Github Action 上面,這部分之後再寫另外一篇轉換的過程

參考資料