Hexo 上 JS 無情消失的解決方式

我遇到的問題

套上模板之後,我發現我不能像一般寫靜態網站一樣把 JS 打在 index.html 上,每次一寫好在terminal輸入 hexo deploy 或是 hexo g -d 都會被原本被蓋掉,不能新增。

上圖為試圖新增 <div id="Hello"></div>index.html
然後正常來說,按儲存推上去就沒問題了吧?我們試試

$ hexo g -d


他就…

無情的消失了QAQ

推理時間

  • 是推上 git 的問題嗎?
    • 否。

hexo s 在畚箕檢查
檢測後發現他是在本機就消失
所以推測是在下載下來的 theme 中有檔案複製他自己架好的文件

  • 是全部都不見嗎?
    • 只有 html 檔被重整

試著在裡面 style.css 和 index.html 裡新增自己的東西
只有 html 被刪除

  • 依照上述問答推理,我們可以知道是有一個檔案來自動生成或修改 HTML 檔

但是這麼多檔案要怎麼找???

解決

  • 所以我對照 theme 裡的文件,尋找熟悉的身影…
  • 找到了兩個我沒見過的副檔名 .ejs.ts
    • .ts
      • TypeScript
      • 官方介紹:TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.
      • Ummmm… 說是基於 JS 的強型別語言,感覺不是。
      • TypeScript 新手指南
    • .ejs
      • EJS
      • 官方介紹:What is the “E” for? “Embedded?” Could be. How about “Effective,” “Elegant,” or just “Easy”? EJS is a simple templating language that lets you generate HTML markup with plain JavaScript. No religiousness about how to organize things. No reinvention of iteration and control-flow. It’s just plain JavaScript.
      • 說是基於 JS 的簡單模板語言讓我生成 HTML 檔
      • 找到了~
  • 稍微學會看懂他的使用方式,可以照著原本寫HTML的方式寫,差別只是在於是寫在 .ejs 檔裡面而已。
  • 我的作法是把我會寫的 JS 直接寫在 EJS 裏面,像這樣:

原本的程式碼

<script>
setTimeout(() => {localSearch("<%= theme.search.path || 'search.json' %>")}, 0)
</script>

我新增的

<script>
setTimeout(() => {localSearch("<%= theme.search.path || 'search.json' %>")}, 0)


const wrapper = document.getElementById("bubble-wrapper");

const animateBubble = x => {
const bubble = document.createElement("div");

bubble.className = "bubble";
bubble.style.left = `${x}px`;

wrapper.appendChild(bubble);

setTimeout(() => wrapper.removeChild(bubble), 2000);
}

window.onmousemove = e => animateBubble(e.clientX);
</script>

要注意的是原作者 EJS 檔名不見得很直覺,要一個一個檢查看看你要換的是在什麼地方

剩下的 CSS 就塞在原本會放的位置 ex: style.css。
然後就解決了~~

(那個藍藍的是海浪(?)會隨著滑鼠移動)

%%%%%

EJS 介紹

  • 簡單介紹一下 EJS 怎麼寫
  • 就是用 <%= %> or <%- %> 把 JS 包起來,被包起來的就會進行編譯。舉個例子:
    <body>
    <ul>
    <% for(var i = 0; i < users.length; i++) { %>
    <% var user = users[i]; %>
    <li><%= user %></li>
    <% } %>
    </ul>
    </body>
    如果 users = [‘one’, ‘two’, ‘three’] 那渲染出來的就是:
  • one
  • two
  • three

那這可以幹嘛呢?
如果每個網頁都有重複的東西 ex: home, tags, about...的header就可以靠 EJS 解決。舉個栗子:
原本是每個介面都要寫一次這個:

<header>
<a href="/">my Blog</a>
<nav>
<li><a href="about">about</a></li>
<li><a href="tags">tags</a></li>
<li><a href="Categories">Categories</a></li>
</nav>
</header>

用 EJS 的方式處理:
我們可以當作一個模板片段單獨獨立出來(這裡叫做common-header.ejs)處理這個重複的部分,然後在各個頁面引入。

<body>
<%- include('./templates/common-header.ejs'); %>
<h1>my Blog</h1>
</body>

參考檔案: