Next.js 教學
https://nextjs.org/
1.建立專案
1.開一個新資料夾,然後cd進去後輸入以下指令。
Copy npm init -y
npm install --save react react-dom next
2.在package.json的script內加入以下
Copy {
"scripts": {
"dev": "next"
}
}
3.
4.之後應該會顯示一個404畫面,這時我們新增一下pages 資料夾,裡面放入一個index.js,內容放入以下。
Copy const Index = () => (
< div >
< p >Hello Next.js</ p >
</ div >
)
export default Index
5.新增其他route時只要在pages內加入檔案即可。
/pages/about.js
Copy export default () => (
< div >
< p >This is the about page</ p >
</ div >
)
2.新增client Route
我們把index.js改為如下
Copy import Link from 'next/link'
const Index = () => (
< div >
< Link href = "/about" >
< a >About Page</ a >
</ Link >
< p >Hello Next.js</ p >
</ div >
)
export default Index
route的文件:https://github.com/zeit/next.js#routing
3.新增共用layout component
https://nextjs.org/learn/basics/using-shared-components/the-layout-component
4.引入<script>或是其他html tag
Copy import Layout from '../components/MyLayout.js'
import Head from 'next/head'
export default () => (
< Layout >
< Head >
< script src = "https://checkout.stripe.com/v2/checkout.js" ></ script >
</ Head >
< p >This is the about page</ p >
</ Layout >
)
5.讀取url
加入withRouter
之後即可讀取到router的props
Copy import {withRouter} from 'next/router'
import Layout from '../components/MyLayout.js'
const Content = withRouter ((props) => (
< div >
< h1 >{ props . router . query .title}</ h1 >
< p >This is the blog post content.</ p >
</ div >
))
const Page = (props) => (
< Layout >
< Content />
</ Layout >
)
export default Page
6.Router Masking
也就是更改實際的client URL
Copy < Link as = { `/p/ ${ props .id } /scasc` } href = { `/post?title= ${ props .title } ` }>
< a >{ props .title}</ a >
</ Link >
as 為顯示出來的,href為實際的router
但重新整理後會無法讀取該顯示出來的router
7.自訂Server
原先為使用Next.js內建的dev server,現在要來自己建一個Server
如果有不在page內路徑url,也必須要自訂server,否則重新整理會產生404頁面。
Copy const express = require ( 'express' )
const next = require ( 'next' )
const dev = process . env . NODE_ENV !== 'production'
const app = next ({ dev })
const handle = app .getRequestHandler ()
app .prepare ()
.then (() => {
const server = express ()
server .get ( '/p/:id' , (req , res) => {
const actualPage = '/post'
const queryParams = { title : req . params .id }
app .render (req , res , actualPage , queryParams)
})
server .get ( '*' , (req , res) => {
return handle (req , res)
})
server .listen ( 3000 , (err) => {
if (err) throw err
console .log ( '> Ready on http://localhost:3000' )
})
})
.catch ((ex) => {
console .error ( ex .stack)
process .exit ( 1 )
})
https://github.com/zeit/next.js#custom-server-and-routing
8.使用Fetch獲取Data
把index.js改為如下
當client 跳轉到此頁面時會從client發出請求,但如果是重新整理頁面的話則是Server Side會發出請求並直接把資料渲染到頁面上。
Copy import Layout from '../components/MyLayout.js'
import Link from 'next/link'
import fetch from 'isomorphic-unfetch'
const Index = (props) => (
< Layout >
< h1 >Batman TV Shows</ h1 >
< ul >
{ props . shows .map (({show}) => (
< li key = { show .id}>
< Link as = { `/p/ ${ show .id } ` } href = { `/post?id= ${ show .id } ` }>
< a >{ show .name}</ a >
</ Link >
</ li >
))}
</ ul >
</ Layout >
)
Index . getInitialProps = async function () {
const res = await fetch ( 'https://api.tvmaze.com/search/shows?q=batman' )
const data = await res .json ()
console .log ( `Show data fetched. Count: ${ data . length } ` )
return {
shows : data
}
}
export default Index
更新版:
Next.js 9.3
https://nextjs.org/docs/api-reference/data-fetching/get-initial-props
Copy export async function getStaticProps () {
// Call an external API endpoint to get posts
const res = await fetch ( ` ${ process . env . NEXT_PUBLIC_API_ENDPOINT } /}` )
const data = await res .json ()
return {
props : {
data ,
} ,
}
}
export default function Home ({ data }) {
...
}
9. Style JSX
可以如下寫css
Copy export default () => (
< Layout >
< h1 >My Blog</ h1 >
< ul >
{ getPosts () .map ((post) => (
< li key = { post .id}>
< Link as = { `/p/ ${ post .id } ` } href = { `/post?title= ${ post .title } ` }>
< a >{ post .title}</ a >
</ Link >
</ li >
))}
</ ul >
< style jsx >{ `
h1, a {
font-family: "Arial";
}
ul {
padding: 0;
}
li {
list-style: none;
margin: 5px 0;
}
a {
text-decoration: none;
color: blue;
}
a:hover {
opacity: 0.6;
}
` }</ style >
</ Layout >
)
如果要加上外部css檔案
next.config.js
Copy const withCSS = require ( '@zeit/next-css' )
module . exports = withCSS ()
然後記得import './....css' 的檔案必須寫在pages/index.js中。
10. 部署
新增以下這兩行在 package.json 的 script 中。
Copy "build": "next build",
"start": "next start -p 8000",
但如果想用自訂的Server可以在build完後使用
加上NODE_ENV=production即可,自訂的Server為上面第七點的Server
Copy "serve": "NODE_ENV=production node server.js"
使用Nginx
他跟create-react-app 不同之處在於他是server side render,所以沒有直接build然後用serve static的方式,而是需要啟動next的server然後用nginx做reverse proxy的方式。
Copy location / {
# default port , could be changed if you use next with custom server
proxy_pass http : //localhost:3000;
proxy_http_version 1.1 ;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade' ;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
# if you have try_files like this , remove it from our block
# otherwise next app will not work properly
# try_files $uri $uri / = 404 ;
}
使用pm2
到next專案下輸入如下:
Copy next build
pm2 start npm --name "next" -- start
11. 部署到 Now
Now 為一個 https://zeit.co/ 所出的雲端快速建置服務,使用Heroku
安裝:
Copy npm i -g --unsafe-perm now
之後再項目的根目錄輸入now
記得先到網站註冊帳號
部署後會看到如下(會給你分配一個 now.sh 的子網域):
之後回到Zeit.co網站也可查看部署過的項目。
Next UI
https://nextui.org/docs/frameworks/nextjs
額外功能
1. 輸出靜態頁面
更新:可參考以下連結快速配置
https://nextjs.org/docs/app/building-your-application/deploying/static-exports
新增 next.config.js
Copy module . exports = {
exportPathMap : function () {
return {
'/' : { page : '/' } ,
'/about' : { page : '/about' } ,
'/p/hello-nextjs' : { page : '/post' , query : { title : "Hello Next.js" } } ,
'/p/learn-nextjs' : { page : '/post' , query : { title : "Learn Next.js is awesome" } } ,
'/p/deploy-nextjs' : { page : '/post' , query : { title : "Deploy apps with Zeit" } } ,
'/p/exporting-pages' : { page : '/post' , query : { title : "Learn to Export HTML Pages" } }
}
}
}
上面的config檔案描述 route 該導向哪個檔案,以及要Render的資料。
之後輸入以下即可
會產生一個out資料夾,裡面包含一個html檔案。
可以使用Serve模組測試
Copy npm install serve -g
cd out
serve -p 8080
如果想要部署到 Now上,進入 out 資料夾後輸入 now
即可。
Next.js 使用 antd (ant design)
新增 pages/_app.js
引入 antd style
Copy import "antd/dist/antd.css" ;
function App ({ Component , pageProps }) {
return < Component { ... pageProps} />;
}
export default App;
PM2 執行 Next.js
Copy pm2 start npm --name <取名字> -- start
Last updated 9 months ago