Next.js搭建全球领先的公司都在使用并喜爱的项目

前面,刚使用vite搭建完项目,今天就看到一篇介绍next.js,魔力十足哇!!

那我们也来尝试搭建一下项目,过过瘾吧

官网在这

安装Next.js

系统要求:

  • 节点.js 16.8或以后。
  • 支持 macOS、Windows(包括 WSL)和 Linux。

自动安装

建议使用create-next-app,它会自动为您设置所有内容。

包括路由器,tailwindCss,typeScript,路径别名…

要创建项目,请运行:

npx create-next-app@latest

安装时,你将看到以下提示:

image.png

太爽了!! Next.js现在默认附带 TypeScript、ESLint 和 Tailwind CSS 配置。您也可以选择使用src应用程序代码的目录。

提示后,create-next-app将使用项目名称创建一个文件夹并安装所需的依赖项。

手动安装

若要手动创建新的 Next.js 应用,请安装所需的程序包:

终端

npm install next@latest react@latest react-dom@latest

打开package.json并添加以下内容scripts:

包.json

{  
    "scripts": {    
        "dev": "next dev",    
        "build": "next build",   
        "start": "next start",  
        "lint": "next lint" 
        }
}

这些脚本是指开发应用程序的不同阶段:

  • dev:运行next dev以在开发模式下启动下一步.js。
  • build:运行next build以构建用于生产用途的应用程序。
  • start:运行next start以启动 Next.js 生产服务器。
  • lint:运行next lint以设置 Next.js 的内置 ESLint 配置。

创建目录

next.js使用文件系统路由,这意味着文件的结构决定了应用程序中的路由。

项目结构

image.png

image.png

image.png

image.png

app目录

对于新应用程序,我们建议使用应用路由器。该路由器允许您使用 React 的最新功能,并且是基于社区反馈的页面路由器的演变。

要使用app路由器,创建一个app/文件夹,然后添加一个layout.tsxpage.tsx文件。当用户访问应用程序的根目录 (/).

App Folder Structure

在内部创建根布局app/layout.tsx与所需的<html><body>标签:

app/layout.tsx

打字稿

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

最后,创建一个主页app/page.tsx有一些初始内容:

export default function Page() { return <h1>Hello, Next.js!</h1>}

温馨提示:如果您忘记创建layout.tsx,下一步.js 将在运行开发服务器时使用next dev.

了解有关使用应用路由器的更多信息.

pages目录(可选)

如果您希望使用页面路由器而不是应用程序路由器,则可以创建一个pages/项目根目录下的目录。

然后,添加一个index.tsx文件在您的pages文件夹。这将是您的主页(/):

export default function Page() {  return <h1>Hello, Next.js!</h1>}

接下来,添加一个_app.tsx文件里面pages/以定义全局布局。详细了解自定义应用文件).

import type { AppProps } from 'next/app'
 

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

最后,添加一个_document.tsx文件里面pages/以控制来自服务器的初始响应。了解有关自定义文档文件的详细信息.

import { Html, Head, Main, NextScript } from 'next/document'
 

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

了解有关使用页面路由器的详细信息.

温馨提示:虽然您可以在同一项目中同时使用两个路由器,但路由app将优先于pages.我们建议在新项目中仅使用一个路由器,以避免混淆。

public文件夹(可选)

您可以选择创建一个public文件夹,用于存储静态资产,例如图像、字体等。里面的文件public然后,代码可以从基本 URL 开始引用目录 (/).

那么,创建完的项目package.json如下:

image.png

运行

使用你喜欢的方式运行项目:

我比较喜欢

pnpm dev

当然,你也可以使用如下命令:

1.  运行 `npm run dev`以启动开发服务器。
2.  访问 `http://localhost:3000` 以查看您的应用程序。
3.  编辑 `app/layout.tsx`(或 `pages/index.tsx`)文件并保存它,以便在浏览器中查看更新的结果。

访问打开页面就会看到如下界面,真的是超级炫酷啊!

image.png

配置 SourceMap

development 环境是开启sourceMap的,production 环境默认不开启。如果需要在prod 环境中开启,可以在next.config.js 中进行配置,为了不暴露项目源码,不建议进行配置

javascript




复制代码





module.exports = {
  productionBrowserSourceMaps: !!isDev,
}

设置页面Title

设置页面的title很简单,修改 src/layout.tsx

import "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "林寒的歌",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  );
}

可以看到

image.png

设置错误页面

Next.js 自带了 404、500页面,但是比较简陋,我们可以自定义页面覆盖掉自带错误页面

image.png

可以自定义 404.tsx、500.tsx或者 _error.tsx。

环境变量

环境变量还是老配方

  • .env.development
  • .env.production
  • .env.test

CSS预处理及使用

集成Sass

Next.js 允许你导入(import)具有 .scss 和 .sass 扩展名的 Sass 文件。 你可以通过 CSS 模块以及 .module.scss 或 .module.sass 扩展名来使用组件及的 Sass。

复制代码
npm install sass

页面路由

基于文件系统的路由

Next.js 的优势是 基于文件系统的路由,对应的只需要在 src/pages 下创建的对应页面即可。

在pages/ 下创建 /about.tsx 文件,重新启动项目,即可访问 http://localhost:3000/about

next/link

Next.js 项目内的页面跳转使用<Link>, 该组件会预先加载引用的页面。如果是项目外部链接,则使用<a>

next/router

Next.js 自带的router,通过 useRouter 来获取当前页面的pathname等信息

图片引用

使用原生转存失败,建议直接上传图片文件标签引入图片

本地图片资源,存放在 public/img/*** 下,图片会跟随项目进行打包,图片根路径地址与项目跟路径地址一致

引用方式一

javascript




复制代码





<img
  src={`${publicRuntimeConfig.basePath}/img/modelTitle/moreIcon.png`}
  width="5"
  height="9"
  
/>

publicRuntimeConfig.basePath 是根据当前环境,获取的 basePath 路径

使用 next/image 引用图片

Next.js 自带的<Image> 可以认为是<img> 的升级版,提供了非常方便的尺寸适配,加载等属性,会根据客户端的情况,进行图片的动态优化处理,但也会自动增加很多样式,会影响原生的<img> 样式,所以要根据情况使用。

如果要使用,需要在<Image>包裹一个父容器,并为父容器定义样式。<Image>会自动适配父容器的大小,因为可以不用为<Image>特意设置宽高。需要注意的是,如果使用<Image>加载图片,因为 Next.js 的安全机制,还需要在 next.config.js文件中设置图片域属性,例如设置图片域名属性 qq.com

javascript




复制代码





module.exports = {
  images: {
    domains: ['qq.com'],
    path: `${basePath}/_next/image`,
  },
}

项目中开始部分网络图片采用<Image>加载,Next 的确会做懒加载等处理,但是在安卓低端机下存在兼容问题,无法展示,所以后来统一使用原生<img> 标签进行加载。

接口请求

CSR/SSR/SSG三种API请求方式

在Next.js 项目中,API请求有三种方式。但是根据项目的部署方式,最多可以同时有两种,即:

  1. CSR+SSR
  2. CSR+SSG

CSR 的API请求,就是常规的前端项目中的请求方式,即:由客户端浏览器发起请求,拿到数据后渲染到页面

SSR的API请求,是由服务端(Next.js的Node.js)发起请求,拿到数据后,组装到HTML里,然后将组装好的HTML返回给客户端浏览器

SSG的API请求,于SSR的API请求类似,也是由服务发起请求并把数据组装到HTML里,然后进行静态化输出。 但由于是完全静态化的,所以当API数据发生变化时,必须重新静态化才能更新页面。

getInitialProps (SSR)

getInitialProps是在渲染页面之前就会运行的API。 如果该路径下包含该请求,则执行该请求,并将所需的数据作为props传递给页面。

  • 只能在pages文件夹内的文件中使用。getInitialProps是SSR专用的API,这是误解。
  • 直接访问后,getInitialProps将在服务器端运行。
  • 使用next/link进行客户端路由时,在客户端执行。

getServerSideProps (SSR)

getServerSideProps 每次访问时请求数据

  • 方法只会在服务端运行,每次请求都运行一遍 getServerSideProps 方法
  • 如果页面通过浏览器端Link组件导航而来,Next会向服务端发一个请求,然后在服务端运行getServerSideProps方法,然后返回JSON到浏览器
  • getServerSideProps 方法主要是升级了9.3之前的 getInitialProps 方法。9.3之前的 getInitialProps 方法有一个很大的缺陷是在浏览器中req和 res 对象会是 undefined 。也就是使用它的页面,如果是浏览器渲染你需要在组件内再显示地请求一次,开发体验不太好

getStaticProps(SSG)

所谓的SSG也就是静态站点生成,在build阶段将页面构建成静态的html文件,这样线上直接访问HTML文件,性能极高。

  • 不会在客户端上运行,始终在服务器端运行
  • getStaticProps 是用于在构建时预先执行 getInitialProps 进行的处理并预先生成静态文件的API
  • 如果是动态路由的页面,使用 getStaticPaths 方法来返回所有的路由参数,以及是否需要回落机制

getStaticPaths (SSG)

用于在使用动态路由时生成静态文件。

  • getStaticPaths 方法返回的fallback很有用:如果fallback是false,访问该方法没有返回的路由会404
  • 但是如果不想或者不方便在build阶段拿到路由参数,可以设置fallback为true,Next在访问build中没有的动态路由时候,先浏览器loading,然后服务端开始build该页面的信息,然后再返回浏览器渲染,再次访问该路由该缓存就会生效,很强大!!!
  • 静态缓存目前没办法很灵活的更新!例如内容在build或者fallback生效之后发生更改,目前没办法很方便的替换缓存。

如何选择SSR还是SSG?

  • 如果页面内容真动态(例如,来源数据库,且经常变化), 使用getServerSideProps方法的SSR。
  • 如果是静态页面或者伪动态(例如,来源数据库,但是不变化),可以酌情使用SSG。

axios

使用 axios,并进行的简单的封装,进行了请求拦截及响应拦截。

开发过程中的优化方案

上面提到的本地图片引用,因为项目采用Docker构建,图片如果跟随项目一起打包,每次更新上线后,图片的缓存会失效,页面会重新加载图片,体验上很不好,后来修改为将本地图片上传至CDN。需修改配置文件中的 assetPrefix 配置为CDN文件路径,需结合next-compose-pluginsnext-optimized-images 使用

修改页面图片引用方式

shell
复制代码





npm install --save next-compose-plugins next-optimized-images
javascript




复制代码





// next.config.js
const withPlugins = require('next-compose-plugins');


const optimizedImages = require('next-optimized-images');

const nextConfig = {
  assetPrefix: isDev ? '' : 'https://图片cdn地址',
  distDir: 'build', // 项目文件打包路径
  basePath: '',
  sassOptions: {
    includePaths: [path.join(__dirname, 'src/styles')],
  },
  ...
}

module.exports = withPlugins([optimizedImages], nextConfig);

module.exports = nextConfig;

修改图片的目录,原目录在public/img/*** 下,修改为src/assets/images/***

页面/组件引用方式修改

javascript




复制代码





// 导入本地图片
import demoImg from '@/assets/image/demoImg.png';


// 使用
<img src={demoImg.src}  />

项目构建,执行 npm run build 后,会在项目目录下生成 build 文件夹,该文件夹下就是项目的构建结果。其中 build/static/media 文件夹存放的是项目引用的图片,并且文件名已经经过hash 处理,可通过工具上传至CDN目录。

部署

next.js官方推荐使用vercel部署

官网在这里

参考资料

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYQ6BHcW' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片