Next.js的标语是The React Framework for Production。
https://nextjs.org/learn/
- How Next.js Works
-
Development and Production Environments
-
The Next.js Compiler
- Next.js采用一个rust写就的编译器,来处理JS代码。其SWC平台可以用于编译、化简、打包等等用途。
-
-
Rendering
- 介绍了三种呈现方式
- Static Site Generation
- Server-Side Rendering
- Client-Side Rendering
- (蛮好奇React的SSG和SSR是怎么达成的)
- 介绍了三种呈现方式
-
CDN and the Edge
- 区别,CDN只用来分发内容,the Edge可以用来处理少量计算
-
- Create a Next.js App
- 构建Web应用需要考虑的方面
- 打包链条、分发粒度、是否需要预呈现、是否需要在服务端呈现,是否同服务端交互
- 是否有良好的开发体验
-
Next.js: The React Framework
- 提供pit of success般体验
- 内置的特性包括
- 简明基于页面的路由系统(支持动态路由)
- 预呈现,包括静态生成(SSG)或服务端呈现(SSR),支持在页面级别选择呈现方式
- 自动分割代码,以实现更快速页面加载
- 客户端路由,带有优化了的预获取(prefetching)
- 内置CSS以及Sass支持,可以支持任何CSS-in-JS料库
- 开发环境支持Fast Rfresh
- API路由可以用于开发带有Serverless Function的API端点
- 完全可扩展
-
About This Tutorial
- 创建一个简单的 blog app,例子在https://next-learn-starter.vercel.app/
-
Setup
- 基本环境搭建(过)
-
Create a Next.js app
- 执行
npx create-next-app@latest nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
- 调用
create-next-app
--example
部分指明的是模板
- 调用
- 执行
-
Run the development server
cd nextjs-blog
npm run dev
或npx next dev -H localhost
-
Editing the Page
- 可尝试修改
pages/index.js
查看变动是否生效
- 可尝试修改
- 构建Web应用需要考虑的方面
- Navigate Between Pages
-
Pages in Next.js
- 一个页面是pages目录下的一个文件中到处的一个React组件
- 页面的路由映射有一定之规则
- 一个页面是pages目录下的一个文件中到处的一个React组件
-
Create a New Page
- 创建一个
pages/posts/first-post.js
,然后到处一个简单的React组件- 可以在
http://localhost:3000/posts/first-post
访问到其内容
- 可以在
- 创建一个
-
Link Component
- Next.js中可以使用
next/link
中的<Link>
组件到链接 -
Using
- 形式如
<Link href="/posts/first-post">this page!</Link>
- Next.js 12.2之前,Link组件需要包裹在
- 形式如
- Next.js中可以使用
-
Client-Side Navigation
- Link组件支持的是客户端的导览
- 此方式并不会刷新整个页面
-
Code splitting and prefetching
- 只会为当前页面获取数据
- 这也意味着不同页面的数据是隔离的
- 如果某个页面抛出异常,整个app仍能够工作
- 此外,production模式下,Next会根据Link来预加载数据
- Link组件支持的是客户端的导览
-
- Assets, Metadata, and CSS
- static asset放置在顶层的public目录
-
Unoptimized Image
- 传统的
<img src="/images/profile.jpg" alt="Your Name" />
所没有处理的功能- 确保图像响应不同的屏幕尺寸
- 通过第三方的工具或者料库来优化图片
- 只在图像进入视界的时候才显示
- 传统的
-
Image Component and Image Optimization
next/image
是一个用来替代<img>
元素的组件- 默认情况下,next.js也支持图像的优化
- 可以优化图片的大小,以及格式
- 就算图片外部外部源,也能工作。
-
Using the Image Component
- 图片优化是按需的,有用户请求时才操作
- 默认情况下,图片为惰性加载
- 图片呈现的时候会避免Cumulative Layout Shift,参考https://web.dev/vitals/#core-web-vitals以及https://webmasters.googleblog.com/2020/05/evaluating-page-experience.html。
-
Metadata
- 注意到
page/index.js
中使用的时<Head>
而不是<head>
<Head>
是一个React组件
- 注意到
-
Third-Party JavaScript
- 可以使用
import Script from 'next/script';
- 例子:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" onLoad={() => console.log(`script loaded correctly, window.FB has been populated`) } />
- 上面的strategy设为lazyOnload的话告诉Next在浏览器空闲的时候加载目标脚本
- onLoad在加载后执行动作
- 可以使用
-
CSS Styling
- 从模板创建的工程,styles目录已然有两个css文件
globals.css
以及Home.module.css
- CSS modules可以根据组件来区分CSS标类名字
- 除了CSS modules之外,Next应用可以支持其他js方式
- Sass允许导入
.css
以及.scss
文件 - PostCSS料库,比如Tailwind
- CSS-in-JS料库,比如styled-jsx, styled-components以及emotion
- Sass允许导入
- 从模板创建的工程,styles目录已然有两个css文件
-
Layout Component
- Layout组件可以在全部页面共享
- 位置可以是
components\layout.js
-
Adding CSS
- 创建与上述组件对应的CSS module:
components/layout.module.cs
- layout组件中可以导入那个module.css文件,然后使用之:
return <div className={styles.container}>{children}</div>;
- Next也支持对CSS模块进行代码切分,每个页面只加载自己的那部分
- 创建与上述组件对应的CSS module:
-
Global Styles
- 全局CSS需要创建
pages/_app.js
,然后导出一个App
组件- 这需要重启开发服务器
- 全局CSS可以随意放置,不过要将其导入到
pages/_app.js
,代码如import '../styles/global.css';
- 全局CSS需要创建
-
Polishing Layout
- 将默认模板替换成博客模板
-
Styling Tips
-
Using clsx library to toggle classes
- clsx是一个简单的料库,可以帮助翻转标类名字
-
Customizing PostCSS Config
-
Using Sass
- 默认就支持,但是需要安装sass:
npm install -D sass
- 可以把CSS文件命名为
.scss
或者.sass
- CSS Module可以命名为
.module.scss
或.module.sass
- 默认就支持,但是需要安装sass:
-
- Pre-rendering and Data Fetching
-
Pre-rendering
- 默认情况下,Next会预呈现每个页面,也就是说给每个页面提前生成HTML
- 每个预呈现的页面会包含所需的最小JS代码
- 等页面加载时,会执行JS代码,让页面变得具有交互性(此举叫做hydration)
-
Check That Pre-rendering Is Happening
- 观察预呈现是否发生
- 关闭JS,这样非预呈现的页面就显示不了内容
- 观察预呈现是否发生
- 默认情况下,Next会预呈现每个页面,也就是说给每个页面提前生成HTML
-
Two Forms of Pre-rendering
- Static Site Generation和Server-side Rendering
-
Per-page Basis
- 可以在页面级别决定采用何种静态渲染
-
When to Use Static Generation v.s. Server-side Rendering
- 问个问题:“是否能在用户请求前就呈现?”
-
Static Generation with and without Data
- 静态渲染可以带数据
-
Static Generation with Data using getStaticProps
- 如果在导出组件的同时,也导出一个异步的getStaticProps算函
- 那么此getStaticProps就会在建构时执行
- 如果在导出组件的同时,也导出一个异步的getStaticProps算函
-
Creating a simple blog architecture
- 数据存储在本地的markdown文件
-
Creating the markdown files
- 在pages目录下,创建
posts/pre-rendering.md
和posts/ssg-ssr.md
- markdown的元数据可以用gray-matter来解析
- 在pages目录下,创建
-
Creating the utility function to read the file system
- 目标
- 从markdown文件中的元数据获取title, date等信息
- 在索引页面以列表方式显示这些数据
- 创建一个lib目录
- 里面创建一个post.js文件
- 目标
-
Implement getStaticProps
-
Using Static Generation (getStaticProps())
- (过)
-
-
getStaticProps Details
-
Next.js在服务端和客户端补填了fetch()
- getStaticProps只在服务端运行,而不是在客户端运行
-
Development vs. Production
- development条件下getStaticProps每个请求都运行
- production条件下getStaticProps运行在建构时
- 可以通过fallback key来返回getStaticPaths
-
Only Allowed in a Page
- 只能在页面文件中导出
-
What If I Need to Fetch Data at Request Time?
- 可以使用服务端呈现
-
-
Fetching Data at Request Time
- SSR的话需要导出getServerSideProps,而不是getStaticProps
-
Client-side Rendering
- 如果不需要预呈现数据,可以选择客户端呈现的策略
- 静态生成部分页面,那些不需要外部数据的部分
- 页面加载之后,使用JS来加载数据,充实剩余部分
- 如果不需要预呈现数据,可以选择客户端呈现的策略
-
SWR
- 用于数据获取的React hook,文档在https://swr.vercel.app/
-
- Dynamic Routes
- 让路由依赖于动态获取的博客文章信息
-
Page Path Depends on External Data
- 也就是dynamic URL
-
How to Statically Generate Pages with Dynamic Routes
- 目的,为博客站点创建动态路由
- 每篇博文的路径是
/posts/<id>
,<id>
为博文markdown文件的名字
- 每篇博文的路径是
- 目的,为博客站点创建动态路由
-
Overview of the Steps
- 在
pages/posts
下创建[id].js
- 须导出一个getStaticPaths算函,用于返回id列表
- 须导出另一个
getStaticProps({ params })
算函,接收一个参数,用于返回针对某个具体id的信息
- 在
-
Implement getStaticPaths
- 删掉原先的first-post.js。
- getStaticPaths要求输入的是一个对象阵列,每个对象有params子对象,子对象中有id辖属。
- getStaticPaths返回的是一个对象,含有paths辖属和fallback辖属
-
Implement getStaticProps
- (过)
-
Render Markdown
- 使用remark以及remark-html来呈现HTML
- HTML的插入是采用React的dangerouslySetInnerHTML
-
Polishing the Post Page
-
Adding title to the Post Page
- 使用next/head中的Head来增加title
-
Formatting the Date
- 使用date-fns料库来格式化日期
- 需要创建一个文件叫做
components/date.js
,用于盛放Date组件
-
Adding CSS
- 从
styles/utils.module.css
添加CSS标类到[id].js
- 从
-
-
Polishing the Index Page
- 从首页添加到链接到各个页面
-
Dynamic Routes Details
- 重复一些关键的信息
-
Fetch External API or Query Database
- 和getStaticProps一样,getStaticPaths可以从任意数据源获取数据
-
Development vs. Production
- development情形,getStaticPaths每个请求都运行
- production情形,getStaticPaths在建构时运行
-
Fallback
- 如果为彳值,那么getStaticPaths没有返回的路径,都是显示一个404页面
- 如果为亍值,那么(略)
- 如果为blocking,那么在服务端又是一番处理
-
Catch-all Routes
pages/posts/[...id].js
可以匹配/posts/a
/posts/a/b
/posts/a/b/c
- 等等
getStaticPaths
必须返回params的id辖属是一个阵列id: ['a', 'b', 'c'],
-
Router
- 通过
next/router
中的useRouter钩子,可以访问Next.js的路由器
- 通过
-
404 Pages
- 创建
pages/404.js
来自定义404页面 - 此页面是建构时自动生成的
- 创建
-
More Examples
- 一些starters
- API Routes
- API端点主要用于Node.js的无服务端算函
- (略)
- Deploying Your Next.js App
- (略)
- TypeScript
- 默认与typescript良好集成
-
Create tsconfig.json
- 创建一个空的tsconfig.json
- 运行开发服务器的时候,会自动补齐所需依赖料包,并往tsconfig.json里面填内容
- 同时也会创建并填充next-env.d.ts
-
Next.js Specific Types
- (过)
https://nextjs.org/docs/
- Basic Features
- Built-in CSS Support
- 可以直接import css文件
-
Adding a Global Stylesheet
- 在
page/_app.js
导入css文件,适用于全局所有组件 - 这种做法允许在开发的时候热重载css文件
-
Import styles from node_modules
- 从next 9.5.4之后,可以从任意处导入node_modules中的css
- 在
-
Adding Component-Level CSS
- 支持CSS module文件,名字如
[name].module.css
- css module文件可以在应用的任意位置导入
- 例子
components/Button.js
可以导入components/Button.module.css
- 所有的CSS module文件会被迷你化,然后码粒化,用以保证每个页面只加载最小的css
- 支持CSS module文件,名字如
-
Sass Support
- 支持扩展名
.scss
(推荐),.sass
- 需要安装sass:
npm install --save-dev sass
-
Customizing Sass Options
next.config.js
中的sassOptions
可以定义sass的选项
-
Sass Variables
- (过)
- 支持扩展名
-
CSS-in-JS
- 给出了许多实例
- 对于tailwindcss,路径在
https://github.com/vercel/next.js/blob/canary/examples/with-tailwindcss/README.md
- 安装方式:
npx create-next-app --example with-tailwindcss with-tailwindcss-app
- 或者:
npx create-next-app --example with-tailwindcss-emotion with-tailwindcss-emotion-app
- 参考:https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss-emotion
- 安装方式:
-
FAQ
-
Does it work with JavaScript disabled?
- development需要开启js支持Fast Refresh,production情形下不开js也能加载css
-
-
Related
- (过)
- Built-in CSS Support
- Advanced Features
- Customizing PostCSS Config
- 默认支持postCSS
- 开箱支持
- autoprefixer
- Cross-browser Flexbox bugs
- 修补IE11,但是对IE11默认不开启CSS Grid Layout
- 开箱支持
-
Customizing Target Browsers
- 可以在package.json自定义browserslist
- 可以使用browsersl.ist 工具
-
CSS Modules
- 只要将css取名
.module.css
- 只要将css取名
-
Customizing Plugins
- 如果自定义了PostCSS配置,Next就会禁用默认的行为
- 在工程根目录创建一个
postcss.config.json
文件- 也可以命名为
.postcssrc.json
,从package.json
的postcss
键项中读取
- 也可以命名为
- 不要使用
require()
,插件必须通过字符串提供
- 默认支持postCSS
- Using MDX
-
Why use MDX?
-
MDX Plugins
- MDX内部使用的是remark以及rehype
- remark支持remark-gfm
- MDX内部使用的是remark以及rehype
-
@next/mdx
- 允许从本地
/pages
目录的.mdx
文件导入数据 -
Setup @next/mdx in Next.js
- 允许从本地
-
Using Components, Layouts and Custom Elements
-
Frontmatter
@next/mdx
默认不支持frontmatter,可以使用gray-matter
-
Layouts
- 需要这样:
export default ({ children }) => <MyLayoutComponent meta={meta}>{children}</MyLayoutComponent>
- 需要这样:
-
Custom Elements
- 需要在配置中开启
providerImportSource: "@mdx-js/react"
- 需要在配置中开启
-
-
Using rust based MDX compiler (experimental)
- (略)
-
- Customizing PostCSS Config
Telemetry
- How Do I Opt-Out?
next telemetry
可以有disable/status/enable等子操作npx next telemetry disable # Or yarn next telemetry disable
其他
适合Next.js的React组件框架
网络文摘
(底线)