Next.js实战(上)| 青训营笔记

221 阅读5分钟

Next.js实战(上)

这是我参与第五届青训营 伴学笔记创作活动的第7天。

课程重点

  1. CSR,SSR,SSG
  2. 什么是Next.js
  3. Next.js客户端开发

详细知识点

CSR,SSR,SSG

先科普一下B端、C端的概念:

什么是B端,C端? B的全称是Business即商家,多为企业的产品。通常是企业或商家,为工作或商业目的而使用的系统型软件、工具或平台。例如:腾讯云,阿里云,企业内部的ERP系统等等。 C的全称是Customer即消费者,多为用户的产品,个人用户或终端用户,使用的是客户端。例如:微信,抖音,拼多多等等。 image.png

  • CSR:客户端渲染(Client-Side Rendering)。是常见的B端Web应用开发模式,前后端分离,服务器压力相对更轻,渲染工作在客户端进行,服务器直接返回不加工的HTML,用户在后续进行访问操作。首屏时间更长。
  • SSR:服务端渲染(Server-Side Rendering)。是面对C端用户,需要支持SEO,就需使用SSR,因为可以有HTML的结构节点,对于浏览器爬虫友好。传统的服务端渲染如JSP、PHP,是由java,php负责渲染逻辑,前端只负责UI和交互。缺点是代码耦合度高,模板语言中混杂编程语言,维护困难。
  • 同构SSR:BFF(Backend For Frontend)即服务于前端应用的后端。如:Nuxt.js(Vue)、Next.js(React).前后端一体化,一套Vue/React代码在服务器上运行一遍,到达浏览器又运行一遍。前端后端都要参与渲染,而且首次渲染出的HTML要一样。image.png
  • SSG:静态站点生成(Static Site Generation),在构建的时候直接把结果页面输出html到磁盘,每次访问直接把html返回给客户端,相当于一个静态资源。相比于SSR,由于不需要每次请求都由服务器端处理,所以可以大幅度减轻服务端的压力。缺陷在于只能用于偏静态的页面,无法生成与用户相关的内容,也就是所有用户访问的页面都是相同的。

SSR,SSG的优势:利于SEO,浏览器的推广程度,取决于搜索引擎对站点检索的排名,搜索引擎可以理解是一种爬虫,它会爬取指定页面的html,并根据用户输入的关键词对页面内容精选排序检索,最后形成我们看到的结果;更短的首屏时间,只需要请求到一个html文件就能展示出页面,虽然在服务器上会调取接口,但服务器之间的通信要远比客户端快,甚至是同一台服务器上的本地接口调取。因为不再需要请求大量js文件,这就使SSR/SSG可以拥有更短的首屏时间。

image.png

什么是Next.js

基于React提供的相关服务器端渲染API实现,整个过程实现比较繁琐重复,从零实现对新手不友好。迫切需要一个封装好的集合来快速上手服务器端渲染。

image.png Next.js是一个构建于Node.js之上的开源Web开发框架,支持基于React的Web应用程序功能,例如服务端渲染和生成静态网站。

Next.js客户端开发

初始化项目

npx create-next-app@latest --typescript
# or
yarn create next-app --typescript

项目结构

image.png Layout:在入口文件_app.tsx中导入layout布局组件,可以实现每个页面公共的页头和页尾。

import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import Layout from '@/components/layout'

export default function App({ Component, pageProps }: AppProps) {
  return <Layout>
     <Component {...pageProps}/>
  </Layout>
}

image.png 文件式路由 Next.js有一个基于页面概念的基于文件系统的路由器。当一个文件被添加到pages目录中时,它会自动作为一个路径可用。 image.png 预定义路由优先级更高,预定义路由能直接匹配的路由就不会分发给下面的动态路由。

BFF层的文件式路由: BFF,作为服务器构建包,不影响客户端构建bundle的体积。相同的router生成方式,不过是作为API层访问,而不是page. image.png

image.png 路由跳转:采用next/link跳转或者useRouter跳转

import type { NextPage } from "next";
import Link from "next/link";
import style from './index.module.scss'
const Navbar:NextPage = () => {
    return <div className={style.navbar}>
        <ul>
            <li><Link href="/">首页</Link></li>
            <li><Link href="/tag">标签</Link></li>
            <li><Link href="/my">我的</Link></li>
        </ul>
    </div>
}
export default Navbar

image.png 数据注入getServerSidePropsgetStaticPropsgetInitialProps、客户端注入。

getInitialProps:在服务端执行,只能在页面层面进行绑定,采用同构,首次渲染服务器端渲染,路由跳转使用客户端路由。

import type { NextPage } from "next";
import style from './index.module.scss'
type Data = {
  address: string
}
const Home: NextPage = ({props}) => {
  const list:Data[] = props.list
  return <div className={style.home}>
    我是首页
    <ul>
      {
        list.map((item,index) => {
          return <li key={index}>{item.address}</li>
        })
      }
    </ul>
  </div>;
}
Home.getInitialProps =async (context) => {
  console.log("query",context.query)
  const res = await fetch('http:127.0.0.1:3000/api/hello')
  const data: {list:Data[]} = await res.json()
  console.log(data);//服务端执行
  return {props:data};
}
export default Home;

意味着如果使用router跳转当前页,会在客户端执行Home.getInitialProps这部分逻辑 image.png getServeSideProps: SSR,与getInitialProps不同的是即使使用router跳转当前页,也只会在服务端执行这部分逻辑。

export const getServerSideProps: GetServerSideProps = async context => {
  const { articleId } = context.query;
  const { data } = await axios.get(`${LOCALDOMAIN}/api/articleInfo`, {
    params: {
      articleId,
    },
  });
  return {
    props: data, // 需要拿props包裹
  };
};

getStaticProps: SSG,在服务端构建时执行,如果涉及动态路由(带参数),需要使用getStaticPaths配置的所有可能的参数情况。

export const getStaticPaths: GetStaticPaths = async () => ({
   paths: [{ params: { articleId: '1' } }],
   fallback: false,
 });

 export const getStaticProps: GetStaticProps = async context => {
   const { articleId } = context.params as any;
   const { data } = await axios.get(`${LOCALDOMAIN}/api/articleInfo`, {
     params: {
       articleId,
     },
   });
   return {
     props: data,
   };
 };

总结:

以上内容主要科普了B端,C端,以及CSR,SSR,SSG这些概念,然后介绍了next.js以及next.js客户端的文件式路由,路由跳转方式,数据注入等。next.js服务端开发将在下节介绍。