Next 服务端渲染项目搭建

2,726 阅读5分钟

在开始搭建项目之前,我们先来了解下什么是Next ?

Next 简介

Next.js 为您提供生产环境所需的所有功能以及最佳的开发体验:包括静态及服务器端融合渲染、 支持TypeScript、智能化打包、 路由预取等功能 无需任何配置。

英文文档: nextjs.org/
中文文档: www.nextjs.cn/

在官方文档上面,详细的介绍了Next的所有优点,感兴趣的同学可以点击进入自行阅读,这里不再赘述。

相信通过阅读官方文档,你会困惑一下几个名词:

  1. CSR:Client Side Rendering,客户端(通常是浏览器)渲染
  2. SSR:Server Side Rendering,服务端渲染
  3. SSG:Static Site Generation,静态网站生成
  4. ISR:Incremental Site Rendering,增量式的网站渲染
  5. DPR:Distributed Persistent Rendering,分布式的持续渲染

CSR 客户端渲染

客户端渲染.png
它的优点:

  1. 前后端分离,开发效率高。
  2. 用户体验更好,我们将网站做成SPA(单页面应用)或者部分内容做成SPA,当用户点击时,不会形成频繁的跳转。

它的缺点:

  1. 前端响应速度慢,特别是首屏,这样用户是受不了的。
  2. 不利于SEO优化,因为爬虫不认识SPA,所以它只是记录了一个页面。

为了解决 CSR 的缺点, SSR 出现了。

SSR 服务端渲染

服务端渲染.png
但是很遗憾,服务端渲染确实可以 解决 CSR 单页面应用 (SPA) 产生的 SEO、首屏渲染时间等问题而诞生的,在服务端直接实时同构渲染用户看到的页面,能最大程度上提高用户的体验。

它的优点:

  1. 尽量不占用前端的资源,前端这块耗时少,速度快。
  2. 有利于SEO优化,因为在后端有完整的html页面,所以爬虫更容易爬取信息。

它的缺点:

  1. 不利于前后端分离,开发的效率降低了。
  2. 对html的解析,对前端来说加快了速度,但是加大了服务器的压力。

参考资料:
www.mybj123.com/13984.html
zhuanlan.zhihu.com/p/365113639
zhuanlan.zhihu.com/p/47044039

开始搭建

本文基于 Next 官方脚手架搭建:

npx create-next-app@latest --typescript

注意:

目录结构:
image.png

添加 Prettier

npm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier

添加 eslint-typescript

npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-import-resolver-typescript

修改 .eslintrc 文件:

{
  "env": {
    "browser": true,
    "es2021": true
  },
  "plugins": ["@typescript-eslint"],
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "next",
    "next/core-web-vitals",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "rules": {
    "@typescript-eslint/no-unused-vars": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/consistent-type-imports": "warn",
    "@typescript-eslint/no-var-requires": "off",
    "import/no-anonymous-default-export": [
      "error",
      {
        "allowArray": false,
        "allowArrowFunction": true,
        "allowAnonymousClass": false,
        "allowAnonymousFunction": false,
        "allowCallExpression": true,
        "allowLiteral": false,
        "allowObject": false
      }
    ]
  }
}

添加 prettier 规则

{
  "semi": false,
  "trailingComma": "es5",
  "useTabs": false,
  "rintWidth": 80,
  "singleQuote": true,
  "tabWidth": 2
}

添加 TailwindCSS

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

初始化生成配置文件:

npx tailwindcss init -p # 此操作会生成 tailwind.config.js 和 postcss.config.js 配置文件

修改 tailwind.config.js 配置文件【官网示例】:

module.exports = {
  mode: 'jit',
  content: [
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
    './layout/**/*.{js,ts,jsx,tsx}',
    './lib/**/*.{js,ts,jsx,tsx}',
    './utils/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

在 styles/global.css 中添加:

@tailwind base;
@tailwind components;
@tailwind utilities;

_app.ts 中引入 global.css 即可生效。

添加 路径别名

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    // 基础路径
    "baseUrl": ".",
    
    // 添加别名 , 在项目中即可使用 @components 
    "paths": {
      "@components/*": ["components/*"],
      "@utils/*": ["utils/*"],
      "@lib/*": ["lib/*"],
      "@styles/*": ["styles/*"]
    }
  },
  "include": [
    "types/process.d.ts",
    "next-env.d.ts",
    "types/next-auth.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": ["node_modules"]
}

添加 stylelint

npm install --save-dev stylelint stylelint-config-standard 

根目录创建 stylelint.config.js 配置文件:

module.exports = {
	extends: 'stylelint-config-standard',
	rules: {
		
	},
}

添加 less

npm i next-with-less less less-loader

在 next.config.js 中修改配置:

const withLess = require('next-with-less')

module.exports = withLess({
  reactStrictMode: true,
  lessLoaderOptions: {},
})

添加 antd 组件库

npm install antd

创建 antd.less 文件:

@import "~antd/dist/antd.less";

@primary-color: #f74a49;

@link-color: #1890ff;

@success-color: #52c41a;

@warning-color: #faad14;

@error-color: #f5222d;

@font-size-base: 14px;

@heading-color: rgba(0, 0, 0, 0.85);

@text-color: rgba(0, 0, 0, 0.65);

@text-color-secondary: rgba(0, 0, 0, 0.45);

@disabled-color: rgba(0, 0, 0, 0.25);

@border-radius-base: 2px;

@border-color-base: #d9d9d9;

@box-shadow-base: 0 3px 6px -4px rgba(0, 0, 0, 0.12),
  0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05);

接着 在 pages/_app.tsx 中引入

import '@styles/globals.css' // 注意 这里引入了 tailwind base 初始化文件,所以它不能在antd之后引入,否则antd组件库的样式会被清除
import '@styles/antd.less'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default MyApp;

less 引入后需要添加 类型文件告诉 typescript:

// type/global.d.ts

declare module '*.module.css' {
  const classes: { readonly [key: string]: string }
  export default classes
}

declare module '*.module.less' {
  const classes: { readonly [key: string]: string }
  export default classes
}

添加 husky 等代码规范

npm i lint-staged husky -save-dev

安装成功后执行以下命令启动 husky :

npm set-script prepare "husky install"
npm run prepare

接着安装钩子:

npx husky add .husky/pre-commit "npx lint-staged"

在根目录添加 lint-staged 的配置文件:

module.exports = {
  '**/*.(ts|tsx)': () => 'npx tsc --noEmit',

  '**/*.(ts|tsx|js)': (filenames) => [
    `npx eslint --fix ${filenames.join(' ')}`,
    `npx prettier --write ${filenames.join(' ')}`,
  ],

  '**/*.(md|json)': (filenames) =>
    `npx prettier --write ${filenames.join(' ')}`,

  '**/*.(less)': (filenames) =>
    `npx stylelint ${filenames.join(' ')} --custom-syntax postcss-less`,
}

安装 commitlint

# 安装 commitlint cli 和常规配置
npm install --save-dev @commitlint/{config-conventional,cli}
# For Windows:
npm install --save-dev @commitlint/config-conventional @commitlint/cli

# 该命令会在根目录创建 commitlint 配置文件
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js

接着安装 husky 钩子:

npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"

使用:

git add .
git commit -m "feat: 项目基础建设"

lint.png
可以看到钩子被触发。

最终完整项目结构如下:
image.png

由于文章是在项目搭建后才写的,所以目录结构中有些文件是在下一篇文章中需要介绍的。
下一篇文章将带领大家使用 next-auth 这个库 ,讲解如何优雅的在 Next 项目中实现权限控制问题。

如果喜欢这篇文章请给我点赞 👍
谢谢 🙏