大亨升級為大大亨 Gatsby 3
Gatsby 3 有一個很重大的改變,有關圖片的語法都改變了。原有的 project 如果升級到 gatsby 3 圖片語法沒有跟著改的話,有可能沒問題、也可能會不能跑了,或出現一些錯誤。因為我的 project 有些奇怪的錯誤,所以我乾脆就把我的 blog 圖片語法做個升級,這就是所謂的有拜有保佑吧,咦?
plugin 升級
gatsby 2 相片的 plugin 用的是gatsby-image
,升級的時候可以先移除,然後改用gatsby-plugin-image
,並一併升級相片有關的plugins:
npm uninstall gatsby-image
npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-transformer-sharp
原本 gatsby 2 不管靜態或是動態圖檔,都是在檔案開頭匯入import Img from 'gatsby-image'
的 Img 這個 component 來設定相片。
gatsby 3 則是改成靜態圖檔匯入import { StaticImage } from "gatsby-plugin-image"
,動態圖檔匯入import { GatsbyImage } from "gatsby-plugin-image"
優點
為什麼要升級 gatsby 3? gatsby 3為什麼相片要用新語法?我個人覺得新語法有兩個優點:
- 原本 gatsby 2 的靜態圖檔都需要透過 garaphQL 提供來源,gatsby 3 新語法用 StaticImage 這個 component 就可以把 url 或是 ralative path 放入 property 中直接使用,確實方便多了。
- 原本 gatsby 2 中,動態圖檔不管 graphQL 或是 component 的 property 中都需要設定一些 option,現在只需要在 graphQL 中設定就好了,語法是有簡潔一點啦。
靜態圖檔
升級靜態圖檔,需要注意到以下幾個重點:
- 靜態圖檔
<StaticImage />
不再需要跟graphQL要資料了。 - 用
<StaticImage src="trex.png" width={width} heignt={width/2} />
這樣的 component,和 html 的<img />
用法機乎一樣。 <StaticImage />
依然可以享受 gatsby 的 lazy load,自動產生適合大小的圖檔等功能。- 如果遠端檔案變了,不會自動立即更新,rebuild 後才會更新。
- gatsby 的 document 裡面,關於 option 的部份,是選 string 的部份,不要選 enum 。
<StaticImage />
的 props 不能從別的檔案、function、component 傳來。
我的圖是從 CMS 傳來的,常從 property 傳來傳去,所以所以我其實不太常使用<StaticImage />
,比較常使用<GatsbyImage />
。
動態圖檔
動態圖檔語法改變蠻大的,一個最大的重點是 graphQL 裡面的語法:
fixed {
...GatsbyImageSharpFixed
}
改成:
gatsbyImageData(layout: FIXED)
或是:
gatsbyImageData(
width: 200
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
)
使用 component 的語法變成這樣<GatsbyImage image={data.file.childImageSharp.gatsbyImageData} />
我們可以觀察到,原本 gatsby 2 裡面 component 的 options,都改到 graphQL裡面了,在 gatsby 3 裡面,component 裡不需要設定什麼 property 了。
這裡可以注意一下,gatsby 官方 document 列出來的 option 裡面的值,要用大寫的 enum value,這是給 graphQL 用的,小寫是給 component 的 property 用的。
其它method
getImage()
要用這個 method 的話,可以在檔案開頭匯入import { getImage } from 'gatsby-plugin-image'
,這個 method 的功能主要是 <GatsbyImage image={data.file.childImageSharp.gatsbyImageData} />
裡面的data.file.childImageSharp.gatsbyImageData
可以替換成getImage(data.file.childImageSharp)
。
換成這種語法,其實只是如果 gatsbyImageData 的值是 null 的情況下,getImage()
會送出 undefined,而不會讓整個 app 掛掉,其實和childImageSharp?.gatsbyImageData
語法意義一樣,不用getImage()
語法也沒差。
getSrc()
和getImage()
很像,主要是不需要用到 gatsby 一些處理相片的功能,只需要直接取得圖片網址,讓類似 SEO 這種 component 可以用,目的也是預防噴 null 出來出錯。
import { getSrc } from "gatsby-plugin-image"
const HomePage = ({ data }) => {
const imagePath = getSrc(data.file)
return (
<>
<SEO imageSrc={imagePath} />
</>
)
}
實例
可以點「原本」和「改成」看原始檔:
images {
fluid {
...GatsbyContentfulFluid
}
images {
gatsbyImageData(
width: 800
placeholder: BLURRED
aspectRatio:1.5
)
}
<TagCard
slug={slug.toLowerCase()}
key={`tag-${slug.toLowerCase()}`}
iceFireNumber={iceFireNumber}
postTitle={title}
publishedDate={publishedDate}
excerpt={excerpt}
timeToRead={(timeToRead * 1.5)}
imageSrc={element.images[0].fluid}
/>
const image = getImage(element.images[0]);
return (
<TagCard
slug={slug.toLowerCase()}
key={`tag-${slug.toLowerCase()}`}
iceFireNumber={iceFireNumber}
postTitle={title}
publishedDate={publishedDate}
excerpt={excerpt}
timeToRead={(timeToRead * 1.5)}
image={image}
/>
import Img from 'gatsby-image'
import { GatsbyImage } from 'gatsby-plugin-image'
<Link to={`/blog/${slug}/`}>
<Img className="db" fluid={{ ...imageSrc, aspectRatio: 1.5 }} />
</Link>
<Link to={`/blog/${slug}/`}>
<GatsbyImage className="db" image={image} alt={postTitle} />
</Link>
怎麼讀 document
詳細升級步驟可以參考官網高品質 document,以上只是我摘錄和補充一些我覺得比較重要的訊息,接下來分享一點這次升級的心得。
做一個 Gatsby 的開發者,不免要常常讀 Gatsby 的 document,事實上 Gatsby 的 document 品質非常好,不說附上實用的範例程式碼,甚至有的地方還附上影片教學。儘管如此,總還是會是覺得讀 gatsby 的 document 很花時間。
我之前讀 document 的方式,就是邊讀邊做,首先把 document 看懂,然後跟著一步一步做,中間會需要跳去別的 document 或是去 google 資料,然後寫程式碼實作,然後再回去看 document 繼續實作,成功做出來了之後,再做筆記。
這樣的流程有一個小小的缺點是,做到一半再回去查 document 的時候我覺得很花時間,原因如下:
- document 是英文的,總是比看中文慢。
- document 太詳細記載各種情況了,實際上我可能只需要用到 2、3 種情況。
- document 的記載邏輯和自己的尋找邏輯不見得一致。
所以這次升級 gatsby 3 我做了一個小小的改變,我先看 document 先不寫 code,直接把我覺得會用到的部份先摘錄做出一份筆記,等於我先做出一份我自己版本的 document,然後等一下開始寫 code 的時候,再照我自己版本的 document 進行。
我發現這樣小小的改變,竟然大大簡省了我看 document 的時間,因為我看得是我自己中文版本的 document,而且裡面只記載了我會用到的 2、3 種狀況,更重要的是這份特製的 document 記載的邏輯就會是我記東西和我搜尋的邏輯,所以我肉搜(肉眼搜尋)起來超快。
這中間會遇到一個小問題,因為讀 document 的時候沒有實做,偶爾會對原本 document 的理解會有錯誤,那並沒有關係,發現這種情況,就修改一下自己版本的 document 就好了,而且最後升級完畢的時候,整理筆記也會快速很多。
這次升級成 gatsby 3,反而這個讀 document 的方法是我最大的收獲。