Blog Cover Image

Inspire you to have New thinking, Walk out your unique Road.

有的時候,你無意間遇到的一些故事,會激發你的靈感,改變你的想法,接下來你會用與之前全然不同的觀念去創造屬於你獨特的故事。

Sign @MinaYu.

[前端又變成小菜鳥] 前端框架的奇幻旅程 | SEO 那回事 | 從 Nuxt.js, Gridsome, Vue 一直到之後想學React.js 跟 Next.js

Posted on

還記得1個多月前(10/10)我剛結束長達6個月運用休閒時間開發自己的個人網站,想起那個時候最尾兩三週真的是心情歷經三溫暖。

前言

沒想到才一個多月前的事,但我已經覺得是很久以前的事情了。

想到當時的情況,真的讓我壓力百分百,焦慮等級點滿,我記得約莫8月左右,我給自己訂了一個希望9月半能將網站順利上線的目標,於是在中秋連假(四天),我整整四天都在coding,就是希望能趕在中秋節上線。

上線是上線了,不過當時我真的沒想到會遇到SEO的問題。

應該是說,我有想到,但是我還是決定嘗試看看,畢竟我當時其實並不了解這個技術的深層,只是想說也許可行?


你目前看到的這個網站,當初是我今年(2022年)4月時終於有時間有能力回來學前端,於是在先前表姐的提及下,我選了Nuxt.js做我的第一個前端框架學習,所以這個網站一開始是用Nuxt.js寫成的,但後來為什麼變回Hugo了?請聽我娓娓道來。

我在學 Nuxt.js 時雖然遇上蠻多困難,但很多都是我能夠自己Google/自己嘗試學習,Nuxt.js是基於Vue.js的延伸版,邏輯跟設定蠻多延伸Vue.js,而且又有一些額外的功能Nuxt.js已經幫我們開發者處理好。

於是就在這個Nuxt.js的前端坑中玩耍開心了一陣子,心想我終於可以自己設計跟開發自己的個人網站了!

然而在9/11左右(中秋節連假順利把網站推上去後),觀察幾天Google Analysis,發現後面幾天我的網頁瀏覽一天一天還低,然後原本排名前面的文章,瞬間掉下來,這是我心想:

糟糕,我擔心的SEO問題,居然最後還是發生了。

然後我告訴自己下一次要開發新專案時,不要一昧追求新技術,而是好好的跟根據需求去研究這些技術能不能達成目標

這篇文章其實蠻想紀錄自己在個人網站開發最尾那幾週的前端旅程故事(因為當時的我真的超焦慮+壓力爆棚),然後想寫一下自己從中學到什麼了。


Nuxt.js 的SEO設定問題

起初就有在思考會不會SEO有問題,目前使用Hugo時,當generate成完全靜態網頁後,會生產好一堆.html檔,我的每篇部落格文章的SEO資訊都已經按照文章的內容跟設定寫好在.html檔內,所以直接放在Github上+上寫好sitemap,就可以讓google bot抓到我的網站跟文章內容,進而讓讀者搜尋到我的文章。

Hugo 本身就是Github上高星星數的Static Site Generator (SSG) (靜態網頁生產器),還有其他SSG選項,像是: Jekyll, Vuepress …等。我一開始是想說,我其實還沒學過任何前端框架(我以前學前端時,三大框架剛出現),所以想說挑個前端框架(Nuxt.js) 搭配一個 CSS Package (Tailwind.css),能夠算是嘗試自學跟自己做出一個自己的個人網站,無論是功能面或美術面都是。所以後來選了Nuxt.js。至於,為什麼不是Vue.js,…,我當初只是覺得Nuxt.js這個名稱酷斃了,就定下想用這個框架寫網站的目標XDDD

使用過後的想法:

Nuxt.js 其實還沒辦法做到完全靜態,指令 generate 能夠產出.html檔,可是你仔細去看 .html檔內容應該會出現:

  • 每個.html檔的 head都一樣
  • 沒有body,只有javascript檔

(應該就是CSR (Client-Side Rendering)的技術概念了)

generate 雖然有產出 .html 檔,但是內容其實是使用者點進網站後, 內嵌的javascript才會根據目前的頁面render資料,並非剛開始就產好,所以Google Bot去爬蟲時,會爬到一樣的SEO內容,判定這個網站SEO都相同,不利於部落格文章特定的SEO內容。

雖然表姐有跟我說,請想想某些購物網站並不是靜態網站,他們都是有架伺服器的,那為什麼這些購物網站的SEO就這麼好?所以,並不是說要良好的SEO,就一定要完全靜態網站。不過這個部分我還沒有去探討。

Nuxt.js的SEO設定方式?

目前看到兩種,可以參考Nuxt.js 網站

  • Global Settings: 就是統一將Meta Tags 寫在root的設定檔 nuxt.config.js
  • Local Settings: 就是如果需要客製化個別頁面的SEO,就將Meta Tags 寫在個別的.vue檔script中。

優先度: Local Settings > Global Settings ,偵測到那一頁有設定 Local Settings 則會取代原本 Global Settings 設定的內容。


在這邊要道歉,我並不是排斥Nuxt.js,其實這個框架很好很容易上手,而且我本人也沒有到研究的很透徹,因為他有幾種模式: Server side rendering, Static Site Generation,也許還有其他模式。

我照文件在 nuxt.config.js 設定檔中將網頁改為靜態生成,確實在執行指令後也都有生成.html檔,只是真的內容還是有 client side rendering,就是使用者點入網頁才跳轉內容,並非一開始.html內的內容就是固定的。

Render文件的解釋,我也還是不理解,依據這個後端的腦袋,所以排列組合會有幾種嗎 QQ? (可惡的後端思維)

// Server Side Rendered Sites and Static Sites
export default {
  ssr: true 
  target: static 
}

// Client Side Rendering Only
export default {
  ssr: false 
  target: static 
}

// ??
export default {
  ssr: true 
}

// ??
export default {
  ssr: false 
}

我有嘗試把我當時的網站從靜態生產(Static Site Generation) 改為 Server side rendering (SSR),結果沒學過SSR的我,剛run起SSR,就看到一堆錯XD,在我努力嘗試幾下後,我被自己訂下很急的deadline打敗,開始尋找其他資源。

不過確實我覺得SSR也是我必經要學之路。


嘗試 Vuepress & Gridsome

我不想要這半年的努力白白浪費…

於是,我在某週的星期六,我帶上星巴克咖啡,坐在一座高牆上,一邊查找哪些框架是可以符合我的目標,然後一邊擔心自己這半年的努力會完全白費,我真的喜歡我自己設計的這個網站style。

既Nuxt.js過後,我發現SEO沒辦法滿足我的需求,在評估我很希望自己能夠短時間內把開發好的內容搬到另外一個技術,然後那個技術具備優良的SEO體驗。

起初我還是不考慮Hugo,因為考慮到我短期還沒有想要深入Golang,於是為了符合SEO,然後又希望能用到JavaScript框架,我找了幾個SSG靜態網站生產器的選項:

然後這是兩個備案,當時異想天開的覺得三大框架的核心都是JS,應該長得很相似吧(?XD),所以看起來Next.js是基於React.js看起來星星數最多又很流行的框架,Hugo是最後真的沒辦法順利用其他框架完成,最後的備案。

  • Next.js
  • Hugo 這兩個都是基於Vue.js框架延伸出來的靜態網站生產器技術,事不宜遲當週日我馬上就開始嘗試Vuepress

Vuepress 開始嘗試沒多久,就暫時打住了,Vuepress是以md檔為主要的靜態網頁生產器,而我的網站大量使用到Tailwind.css + .vue 檔,好像一個頁面要對應一個 .md檔的樣子,我的Hugo雖然是使用.md檔來寫一個一個部落格文章,但是每個.md檔對應Vuepress有自己規定的.md檔規則,所以我有400多個.md檔文章,我要對400多個.md檔做內容的更換,起笑。

簡單來說,這是Hugo .md檔 的格式

---
author: minayu416
title: ""
draft: true
date: 2022-12-11T23:39:20+08:00
status: published
categories:
- ''
- ''
type: "post"
description: ""
slug: ''
keywords:
- test
image: ''
---

如果是用Vuepress的話, date 可能要改成其他字代替日期 (有點忘記了)。

再加上我發現Vuepress的結構跟Nuxt.js差蠻多的,我勢必又要一段時間學習,考慮到自己的目標是 快速上線+考慮到未來使用性,可能未來不會持續用Vuepress,最後還是會考慮換個框架,畢竟星星數少加上很多外掛功能不齊全。

所以呢…好像嘗試沒到一天,就暫時打住了。


再來是 Gridsome

Gridsome 是我當初在查文章跟Bug時看到的,當初我覺得他的網頁做得很酷炫,又是基於Vue.js的Jamstack framwork框架(又一個新名詞!)。所以,我毫不猶豫開始拿起這個新玩具走跳一波。

Gridsome星星數 8400左右,其實不高。而且如果決定要使用Gridsome來開發的話,我要在學習GraphQL去撈資料,基於本人從事後端工程第三年終於修成仙,理解所謂的底層概念跟基礎觀念都一樣,會Python就會Javascript,學Golang也很快上手,學習一個 GraphQL 應該不是太難的事。

確實雖然初期有點卡關,而且GraphQL的文件,我這個蠢呆萌看不太懂QQ,不過順利的從我這廣大的 .md檔文章撈出我想要的資料,然後render進網頁。

Gridsome 跟 Nuxt.js 真的有87%像,幾乎快要可以無痛轉換,除了撈 .md檔資料, Nuxt.js是使用 @nuxt/content,而 Gridsome 使用 GraphQL,其他Girdsome好像幾乎都有外掛是跟Nuxt.js相似,連i18n的功能都能處理的好好的。

要特別注意的是,如果是撈.md檔的像是部落格頁面跟分類這種動態route網頁,要寫在./src/templates裡,然後要去設定檔做設定(這邊不多說~)

但我前面已經說過,我最後回歸了Hugo的懷抱,所以Gridsome最後並沒有採用。

在我開始用Gridsome重構我的Nuxt.js個人網站後,一切都很順利,除了GraphQL偶爾卡的幾天,基本上都順暢流利,也預先run generate確實能產出完全靜態的網頁,我完成了85%的重構後,來到了最後一哩路。

我有一頁網站是部落格的分類,要根據 .md檔內不同的Category分類來篩選跟分類不同的文章類別,這個功能我只要在 route /category/:name帶入 name這個參數,然後在從.md檔取得資料時,篩選category = name,將屬於該分類的部落格文章撈出,然後render進該category網頁。

功能上沒什麼問題,但是失策的是,由於我的Category都是中文字,所以用GraphQL帶入中文字撈.md檔資料會報錯(忘記是會報錯還是都沒撈到任何資料)。

// category = "[資訊那些事]"

<page-query>
      query Posts ($category: [String]){
      posts: allBlogPost (
      filter: {
        status: {eq: "published"},
        categories: {contains: $category}
        }
      ) {
        edges {
          node{
            title
            description
            date
            categories
            featuredpath
            featured
            slug
        }
        }
    }
  
}   
    </page-query>

就是這樣,進入category.vue頁面後,$category會直接吃到route帶進來的參數,然後直接做query/filter。

結果就是一直報說在撈資料時有問題,在排除各種可能性後,我合理懷疑是因為我的category title都是中文字會有加解密跟編碼問題。

於是,encode+decode我也嘗試過了,然後stackoverflow翻過一遍了,最後在某個Github上看到 目前不支援非ancii文字

嗯…這麼說,就是卡了吧?我好像沒辦法做些什麼,除非要深入改GraphQL的框架,這並非我所樂見。

所以….,Gridsome這個選項宣告…只好先擺著了。


Next.js & Hugo

在歷經Vuepress + Gridsome的重構嘗試後,約莫花了我一週的休閒時間,結果還是沒有辦法完成目標,所以在六日深夜思考過後,我決定來看看Next.js,因為當初我在找Nuxt.js時,挖出一堆Next.js的資料,這兩個只有u/e不同啊,尤其網路上大部分資料都跟Next.js有關,當時也是過濾很久才找到我要找的答案。

於是在我天真的以為,三大前端框架就是都差不多的天真純真想法,我點入了Next.js的官方網站,心想的:

不過就是架構會不太同,底層邏輯應該差不多吧?

這種天真無邪的想法,直接把我推入地獄 (阿不是),在某個週六我又一邊點著木質調蠟燭+Lofi音樂配著清涼的無糖綠茶,打開Next.js頁面一邊看一邊覺得,怎麼這麼的不一樣…?

Next.js 是基於 React.js延伸的框架,在我發現怎麼邏輯跟vue很不同後,我找了幾篇React.js vs Angular.js vs Vue.js相關的文章來壓壓驚一下,最後得出這個結論:

想簡單入門,請右轉Vue, 想變前端大神,請左轉點React.js

React.js 基本上都是用JavaScript來寫,當初好像就是創辦人覺得既然都是要用Javascript寫,為什麼不直接都寫Javascript?

好像不像vue可以允許 html + css,目前看起來React.js都是用JS回傳css+html。

嗯。。。。

學習曲線可能比當初的Nuxt.js,我的個人網站很希望可以在短期內重購然後上線,我暫時沒打算再花半年學React.js or Next.js 然後再重構我的網站。


所以最後呢?

在嘗試跟了解不同的框架後,Hugo最後還是成為我經過深思熟慮過後的選擇。除了我本身陸陸續續對我以前的Hugo主題做小更改了解到的一些概念之外,Hugo的設定跟架構我也很熟悉。而且大量的html + css也是我熟悉的語言。

我新網站除了前端頁面設計使用到Tailwind.css跟需要用原生JavaScript寫的像是 Navbar, Carousel之類的功能,後端撈資料的功能基本上都跟舊Hugo主題完全相似,也就是說Golang語法可以直接百分之百照搬過來。而且Hugo目前也還是星星數很高的技術。

我一開始其實是很擔心Hugo會不會不能用npm, tailwind.css 這類型前端技術套件,因為我的新網站是廣泛用tailwind.css,後來網路上其實有文章教導,所以這一步在一開始我確認可以在Hugo使用 Tailwind後,危機就排除了。

所以Hugo 是可以搭配Tailwind.css 的!!

在經過約莫一週的時間,我成功用Hugo重構我本來Nuxt.js的框架,部署到Github上後沒出什麼太大的問題。

唯一一個我目前還不是太滿意的就是。

那個…

不知道你有沒有發現你用手機展開Navbar後,點外面關不起來,要點那個三條線的Icon才會再合起來?

我還不知道怎麼修XDDD

萬惡的Carousel再換成Hugo用Hugo Carousel外掛開發後,整個順的不要不要的,比本來在Nuxt.js用的Carousel套件還順,左滑右滑怎麼滑都順。


最後

這次的前端框架旅程真的是很有趣,我在後端玩耍了3年左右,後端還是有很多東西可以玩,但是加了前端可以讓外行人看了更開心XD。

然後加上我又很愛嚐鮮,前端三大框架+上三大框架又延伸出一些其他的框架,有得玩了。然後玩出來的產物又可以架在Vercel上給人看,不像後端的程式都不知道怎麼讓人參考。

Angular.js目前沒有引起我的注意,所以近期可能還不會想要學Angular.js,下一個想接觸的框架應該是React.js跟Next.js,依照我過往的習慣,喜歡先接觸很多不同的技術,最後再選定喜歡的那個。(阿不過後端語言很幸運的,接觸Python就很愛,就這麼一路學下去)

而且Next.js提倡的Fully Static Site Generation 有吸引到我,究竟… Next.js可否做到SEO友善呢?我爬文是可以的。

在這個個人網站結束後,我有陸續做了兩個前端專案當作練習,分別是用Nuxt.js跟Vue.js寫的。

Own Influence,你可能會覺得怎麼跟我的網站設計很像,嘿沒錯,我不希望Nuxt.js的六個月旅程是0產出,所以我把網站有關的內容換掉,然後保留Nuxt.js開發,並架設上Vercel。

而明年我會開始開發Miri的下一個版本,會新開發網頁版本,目前還在考慮要不要就用Next.js或React.js去寫Miri的前端,這樣能夠學React.js又能幫Miri做出前端網頁,但是重點就是有沒有符合我要的需求,以及我未來是否還要用React.js當作Miri的前端框架。

還有諸多考量,但關於前端的旅程,React.js跟Vue.js我會繼續體驗。


點進來的前端大大們請別轟炸,請記住,我是一個三年後端工程師思維的前端小菜鳥 @v@,

好啦,這篇就這,後會有期。