iT邦幫忙

2021 iThome 鐵人賽

DAY 2
1
Modern Web

從零開始學習 Next.js系列 第 2

Day02 - 為什麼你需要 Next.js ?

next.js

為什麼你需要 Next.js ?

對於工程師來說選擇用什麼樣的技術,背後都是取決於商業策略需要什麼,以常見的 SSR (Server Side Rendering)、pre-rendering 來說,為什麼要做 SSR 跟 pre-rendering,不外乎是希望網站整體的 SEO 能夠變好,或是提升使用者體驗。

而現在 SPA (Single Page Application) 盛行的時代,許多網站在沒有框架或後端支援的情況下,僅僅使用像是 React 或 Vue 等前端框架,要做到 SSR 或 pre-rendering 還需要做許多設定,做這些技術研究都得花費時間成本與心思,最後才能導入到專案中。

所以 Next.js 的出現能夠解決工程師心中的痛,不必再花費很多時間處理 pre-rendering 或 SSR 的問題,而是利用框架的優勢,讓工程師更專注在開發核心功能上面。

Server Side Rendering 與 Static Side Generation

Next.js 是一個基於 React 的框架,它同時支援 SSR (Server Side Rendering) 與 SSG (Static Side Generation) 兩種方法,不需要很多的設定就可以讓網站同時有這兩種功能。

Next.js 在設計上可以混用兩種方法,像是 /page-a 希望能夠 SSR,因為網站內容很常改變,需要 API 支援變動頻繁的資料;而 /page-b 則是使用 SSG 則是可以用在內容較不常改變的頁面,例如 Landing Page 或部落格等。

圖片的檔案優化

SEO 除了需要網站內容之外,還必須提到 core web vitals 的評分,評分的標準包括網站的速度、是否使用較新的圖片格式等等,因此網站可能會選用 WebP 的檔案格式。WebP 這種格式根據 google 的無失真壓縮測試,甚至可以比 PNG 檔少了 45% 的檔案大小。想要使用這種檔案格式,想要自動化處理,就必須使用 webpack 或 gulp 等加入一些 plugin 進行處理,不僅設定麻煩,事後還要維護不少的設定檔,可以看作是一項不小的成本。

而 Next.js 也提供了相對應的解決方案,可以使用內建的圖片優化方案,讓 Next.js 幫我們自動化處理圖片的格式,不用再額外安裝插件生成不同的格式的圖片檔,而且可以根據不同的瀏覽器,提供支援的圖片檔案,能夠減少許多繁冗的程式碼。

API routes

Next.js 實際上是一個全端框架,它除了 React 的部分外,甚至還提供了建立 API 的功能。如果一個新的專案,在還沒有建構 API 的服務之前,考慮使用 Next.js 的 API routes 是一個選項。

Getting Started

看了基本的 Next.js 介紹,你也許在思考導入新技術的風險,大家導入一項新技術的擔憂,其中一項便是資料來源不夠多,在查詢問題解決方法時,因為沒有足夠大的社群資源,導致得自己想破頭可能也找不到解答。但從使用 Next.js 使用人數上每個月都有線性成長,至今為止,每週已經有 100 多萬人下載,GitHub 的星星數也到了 70K。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/0bb37ca1-327e-4353-91ea-0e41bb5d91b8/_2021-07-18_11.19.38.png
*https://www.npmtrends.com/next*

此外,有需多著名的公司都已經採用了 Next.js 的解決方案,像是 TikTok、Netflix、GitHub、Uber、Twitch 等等。

Companies / Sites using Next.js · Discussion #10640 · vercel/next.js

綜合上述,Next.js 這個框架已經漸漸成熟,社群、資源都以很快的速度增加,所以導入後不用擔心框架的討論度不夠,導致資訊尋找困難。

說了這麼多,第二天不寫點程式好像說不過去,那我們就來簡單玩一下 Next.js 吧!

create next app

如同我們在使用 react 時經常會用到的 create-react-app , Next.js 也有方便的 CLI 工具 create-next-app 可以使用,它能夠快速建立一個基本的應用,並且包含了許多你可能會用到的工具、設定,像是 eslint.gitignore 等。如果你需要不同的 template,在 Next.js 官方的 repo 中也有各式各樣的範例可以在使用 create-next-app 時引用。

建立專案

接下來,你可以使用以下的指令建立 next app:

npx create-next-app
# or
yarn create next-app

而如果你需要 typescript 支援的話,則可以在指令後加上 --ts--typescript 的設定:

npx create-next-app --ts
# or
yarn create next-app --typescript

啟動專案

在建立完 Next.js 的專案後,我們來啟動 Next.js 的應用吧!使用以下指令開啟 dev server:

# started server on http://localhost:3000
yarn dev

然後,開啟瀏覽器輸入「http://localhost:3000」,你便可以看到這個專案的預設首頁。

welcome to Next.js

專案資料夾導覽

如果只是啟動專案好像少了點什麼,所以就讓我們來看一下 Next.js 的資料夾架構跟一些檔案設定吧!

專案資料夾導覽

pages

這個資料夾底下放的是 Next.js 應用中的頁面,因為 Next.js 是使用 file-based routing,所以我們會把所有的頁面都放在裡面,而詳細介紹會在後面的章節中提到。

next.config.js

如果你的 next app 有些客製化的需求,則可以在這個檔案中設定,以下以環境變數作為舉例。

我們經常會在程式碼中使用環境變數,而常見的做法是會建立一個 .env 檔案,然後再搭配 dotenv 之類的套件使用環境變,而 Next.js 的作法則是可以在 next.config.js 中定義我們需要的環境變數。

next.config.js 加入以下設定:

module.exports = {
  env: {
    apiKey: 'api-key',
  },
}

接下來,你就可以 react 中使用 process.env.apiKey

function Home() {
  return <h1>環境變數 apiKey: {process.env.apiKey}</h1>;
}

export default Home;

next.config.js 的客製化設定挺豐富的,包括像是可以設定檔案讀取的路徑 base path,客製化的 header ,或是 webpack 的設定 等,如果有需要這些設定的話,可以到官方網站中看看。

next-env.d.ts

next-env.d.ts 這個檔案則是用在 typescript 型別的引用,這個檔案預設產生的內容如下:

/// <reference types="next" />
/// <reference types="next/types/global" />

接下來我們來看這個檔案的用途,首先,這個檔案中使用 typescript 的 triple-slash directives,引用了 Next.js 所定義的型別。再看到 tsconfig.json 中的 include 包含了這個檔案,所以你現在知道,這個檔案會參與 typescript 的編譯過程。

然後你再看到 styles 這個資料夾底下包含兩個檔案:

  • globals.css
  • Home.module.css

這是 Next.js 的其中一個預設的功能,不用額外設定就支援 CSS 檔案跟 CSS Modules。而之所以 typescript 讀得懂 *.module.css 的檔案也是因為有 next-env.d.ts

我們來實驗一下,把 next-env-d.ts 的第二行刪掉後,到 pages/index.tsx 中看看,你會看到 typescript 無法解析像是 Home.module.css 這種檔案。

錯誤訊息

所以,我們來看看第二行的型別引用包含了什麼,到 node_modules/next/types/global.d.ts 中看看裡面的型別定義,你可以看到裡面宣告了三個 module:

  • declare module '*.module.css' { ... }
  • declare module '*.module.sass' { ... }
  • declare module '*.module.scss' { ... }

正是因為有了這三個 declare module ,才能在專案中讓 typescript 能夠辨別 CSS modules。

而第一行的型別引用跟第二行差不多,第一行則是讓我們可以使用 <html amp=""><link nonce=""><style jsx> 等的語法。

剩下一些常見的設定檔

像是 :

  • .eslintrc:為了讓程式碼品質更為穩定,大部分專案都會使用的 lint 套件
  • .gitignore:這個檔案會設定一些你不想加入版控的檔案,例如 /node_modules
  • tsconfig.json :這個檔案則是用在 typescript 編譯時需要的設定

剩下的檔案較為瑣碎就不再細說了。

總結

在這個章節我們了解到 Next.js 提供許多很棒的功能,包含了混用 SSR (Server Side Rendering) 跟 SSG (Static Side Generation) 的特性,而且還支援基於 TypeScript 開發,還有令人興奮的圖片優化,在支援 WebP 的瀏覽器中使用這種較新的檔案格式。

表面上是因為這些豐富的特性,有利於 SEO 與 UX,對於工程師來說,使用 Next.js 則是可以提升 DX (developer Experience),簡化 SSR 與 pre-rendering 的設定,寫法與原本的 React 寫法很接近,能夠以較低的成本學習並導入到專案中。而且資源未來還會陸續增多,暫且不必擔心框架的熱度影響導入後找不到解決問題的方法。

在瞭解了 Next.js 的一些功能後,透過建立一個應用並快速導覽,我們也知道 Next.js 的專案架構以及一些設定檔的用途。

這只是剛開始而已,接下來 28 天就讓我們一起來看看 Next.js 的魔力吧!

Reference


上一篇
Day01 - 系列文介紹、規劃
下一篇
Day03 - 深入淺出 CSR、SSR 與 SSG
系列文
從零開始學習 Next.js30

尚未有邦友留言

立即登入留言