Next.js 入門:建立專案與專案結構


Posted by SimonAllen on 2021-07-14

建立專案

系統要求

MacOS、Windows 和 Linux 都沒差
只要有 Node.js 12.0 或更高版本即可

安裝與建立 create-next-app 專案

打開 terminal 輸入

npx create-next-app ${專案名稱}

等 terminal 跑完即可。

npx 指令會先檢查本地端 Node.js 是否有安裝 create-next-app,有就執行 create-next-app

沒有就下載 create-next-app 裝入當前局部執行環境,不會裝進本機電腦 Node.js 全域環境,這麼做可以避免全域被汙染。若使用者想全域安裝也可以先下 npm install create-next-app -g,自行斟酌。

專案結構

打開建立好的專案可以看到如下檔案階層

|-- /node_modules
|-- /pages
    |-- /api
        |-- hello.js
    |-- _app.js
    |-- index.js
|-- /public
    |-- favicon.ico
    |-- vercel.svg
|-- /styles
    |-- globals.css
    |-- Home.module.css
|-- .eslintrc
|-- .gitignore
|-- next.config.js
|-- package-lock.json
|-- package.json
|-- README.md
  • pages 資料夾
    Next.js 幫開發者做掉了不少功能,其中之一就是各個頁面(page)與路由(router path)的設定,開發者不需要額外使用 3rd router library,只要在pages 資料夾內有對應的檔案,Next.js 就會自動替其處理對應 router。

    • api 資料夾
      Next.js 可以用來做 API mid server ,其 pages-router 的設定也支援 API 路徑,這裡是官方預設提供的範例,之後啟動專案時,只要進 http://localhost:3000/api/hello 即可以看到對應目前api 資料夾下 hello.js 的 json 檔。

    • _app.js
      pages 進入點。我們可以在這裡做一些全站各頁共用邏輯或初始化行為,例如:加入全域樣式、加入全站全頁<head> 內共用的元素、統一錯誤邊界的處理..等。

    • index.js
      預設頁面的 React 元件,在 Next.js 的 pages-router 路由設定下,pages 根目錄的 index 檔案會對應首頁,也就是使用者打開 http://localhost:3000 看見的頁面。

      關於 pages 資料夾與 router 的設定、注意事項,之後還會獨立記錄在另一篇文章。

  • public 資料夾
    即對外、靜態資源存放的位置,包含專案中會用到的圖片資源、favicon.ico 或是如 sitemap.xmlrobots.txt 皆置於此。

  • styles 資料夾
    預設的樣式檔案資料夾,目前包含了 globals.cssHome.module.css

  • .eslintrc 檔案
    由 Next.js 自動產生的 eslint 設定,後續有 eslint 設定可於此修改

  • .gitignore 檔案
    由 Next.js 自動產生的 git 追蹤(忽略)清單,後續有不想進 git 的檔案可於此修改

  • next.config.js 檔案
    next.config.js 主要處理 Next.js server 和我們 build code 建構檔案時有關的設定。畢竟 Next 已經幫開發者處理掉很多設定,若還有更改的需求,可以先在這對照官方文件,查看與調整專案設定,例如:檔案壓縮、自訂 Webpack 設定、檔案路徑調整、開發環境特定附檔名的支援...等等。

其他如:node_modulespackage-lock.jsonpackage.jsonREADME.md 這些 Node.js 專案常見檔案就不解釋了。看著目前的資料夾結構,不知道各位有沒有覺得哪邊怪怪的。

沒有 src 資料夾!

  • 自建 src 資料夾

    是的 Next.js 預設專案結構沒有 src 資料夾,若開發者不習慣,現行版本已可以建立 src 且不需做額外設定,除了檔案比較好整理外,整個配置也比較貼近過往使用 CRA 的開發者。

    src 內的東西,按照慣例不會有 root 根目錄的設定檔,我們可以在裏頭放常見的 componentsutilities 或其他自訂資料夾,只要 import 路徑正確即可。

|-- /node_modules
|-- /src
    |-- /pages
    |-- /styles
    |-- /components
    |-- /utilities 
    ...下略

|-- /public
|-- .eslintrc
|-- .gitignore
...下略

如果搜尋網路上關於 Next.js 早期的文章,為了使用 src 資料夾還需要額外設定 build 的位置,筆者使用的當下(Next.js 11版)已無此問題,開發者自然的建立 src 即可使用,慣例即設定的體驗蠻不錯的。

眼睛大概掃過目前檔案後,我們可以接著在 terminal cd 進剛剛建好的專案,輸入

npm run dev

透過瀏覽器打開 localhost:3000 可見以下畫面:

此時回到專案內,會發現 root 根目錄內多了一個 .next 資料夾

|-- /.next
|-- /node_modules
|-- /pages
|-- /public
...下略
  • .next 資料夾
    .next 資料夾,這裡會從放我們在 Next.js 建構、bundle、build 出來的東西,不論是 dev 或 prod 皆置放於此。要注意我們不會去修改裏頭的東西,因為 .next 裡面的東西會動態由 Next.js 指令產生與覆蓋。

指令

打開 package.json,可以看到預設可下的npm run ${script}指令,前面 terminal 下的 npm run dev 即是對應這裡的 "dev"

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  • dev
    執行 next dev 指令,在 dev 開發模式下啟動 Next.js 專案前後端程式碼,會一併建立(覆蓋)對應 dev 環境的.next 資料夾。

  • build
    執行 next build 指令,建構 prod 模式的 next application,會一併建立(覆蓋)對應 prod 環境 .next 資料夾。

  • lint
    執行 next lint 指令,用目前 ESLint 設定來檢查專案。

  • start
    執行 next start 指令,只啟動目前 Next.js 專案 prod 模式的 server。

    若初次 create-next-app 建好專案,直接執行此指令 npm run start 會報錯:

      Error: Could not find a production build in the '${path}\.next' directory. Try building your app with 'next build' before starting the production server.
    

    注:${path} 是當前專案的路徑,這裡我以 ${path} 替代。

    原因是找不到.next 資料夾(與 prod 環境的相關設定),按照 Next.js 說明執行 npm run start 前至少要先執行含 next build 指令,以預設專案來講就是要先執行 npm run build 產生對應 prod 環境的 .next 才行。

    如果需要啟動 dev 環境 Server,那執行 npm run dev 以運作 next dev 即可。

    另需注意:由於已有.next 存在,此時啟動 server 後仍可以透過 localhost:3000 打開當前專案頁面並看到先前 npm run build 的 Web 畫面。
    此時修改專案中前端程式碼存檔,reload 瀏覽器畫面並不會改變,因為 npm run start 只跑 dev Web server 這邊的程式碼而已。

總結

之前文章有提到 Next.js SSG 可以獨立只輸出純 static HTML 與靜態檔案,若想做到如 Gatsby.js 一樣,Next.js 還有一個指令 next export 可以做到。之後有空應該會有一篇筆記,講述如何使用 next export SSG 輸出建立 static HTML 與靜態檔案,以及過程中遇到與解決的問題。

參考

Nextjs 官方文件


#Next.js









Related Posts

用 ES6 語法串接 API - Fetch

用 ES6 語法串接 API - Fetch

筆記-JavaScript-event loop

筆記-JavaScript-event loop

CSS Box, Text Shadow

CSS Box, Text Shadow


Comments