一、前言
本文基于开源项目:
广东靓仔之前也写过Next.js的相关文章,这篇文章来一个全面的介绍,希望对没使用过Next.js又感兴趣的小伙伴有一点点帮助。
温馨提示:看Nextjs的文档我们最好选择英文版本,中文文档好像很久不更新了
二、基础知识
系统环境需求
Node.js 12.22.0 或更高版本
MacOS、Windows (包括 WSL) 和 Linux 都被支持
安装
yarn global add create-next-app # or npm i -g create-next-app
or 官方推荐
npx create-next-app@latest # or yarn create next-app
TypeScript 项目
npx create-next-app@latest --typescript # or yarn create next-app --typescript
三、目录梳理
运行Demo
我们安装好项目,运行:http://localhost:3000/
效果如下:
目录结构说明
next.config.js // 是我们的配置文件,用来修改next以及webpack的配置
pages // Next.js路由文件夹
|--index.js // 入口文件
|--_app.js // 用来定义一些页面共用的
Home.module.css // 带有.module后缀的样式文件一般是用来做样式隔离的
【温馨提示】
一般抽取组件的时候,我们可以在根目录创建components文件夹
(不能存储在pages目录,会导致路由错乱)
四、配置修改
便捷开发
一般在Next项目中,我们会结合antd搭配开发,常见的两种使用方式如下:
一、Next.js + Antd (with Less)
安装
yarn add next-plugin-antd-less yarn add --dev babel-plugin-import
使用
// next.config.js const withAntdLess = require('next-plugin-antd-less'); module.exports = withAntdLess({ // 可选 modifyVars: { '@primary-color': '#04f' }, // 可选 lessVarsFilePath: './src/styles/variables.less', // 可选 lessVarsFilePathAppendToEndOfContent: false, // 可选 https://github.com/webpack-contrib/css-loader#object cssLoaderOptions: {}, // 其他配置在这里... webpack(config) { return config; }, // 仅适用于 Next.js 10,如果您使用 Next.js 11,请删除此块 future: { webpack5: true, }, });
添加一个 .babelrc.js
// .babelrc.js module.exports = { presets: [['next/babel']], plugins: [['import', { libraryName: 'antd', style: true }]], };
详细前往:https://www.npmjs.com/package/next-plugin-antd-less
二、安装antd同时也开启css modules
安装支持next-css、babel-plugin-import
yarn add @zeit/next-css babel-plugin-import # or npm install @zeit/next-css babel-plugin-import --save-dev
修改babelrc
{ "presets": [ "next/babel" ], "plugins": [ [ "import", { "libraryName": "antd", "libraryDirectory":"lib", "style": true } ] ] }
增加next-less.config.js
const cssLoaderConfig = require('@zeit/next-css/css-loader-config') module.exports = (nextConfig = {}) => { return Object.assign({}, nextConfig, { webpack(config, options) { if (!options.defaultLoaders) { throw new Error( 'This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade' ) } const { dev, isServer } = options const { cssModules, cssLoaderOptions, postcssLoaderOptions, lessLoaderOptions = {} } = nextConfig options.defaultLoaders.less = cssLoaderConfig(config, { extensions: ['less'], cssModules, cssLoaderOptions, postcssLoaderOptions, dev, isServer, loaders: [ { loader: 'less-loader', options: lessLoaderOptions } ] }) config.module.rules.push({ test: /\.less$/, exclude: /node_modules/, use: options.defaultLoaders.less }) // 我们禁用了antd的cssModules config.module.rules.push({ test: /\.less$/, include: /node_modules/, use: cssLoaderConfig(config, { extensions: ['less'], cssModules:false, cssLoaderOptions:{}, dev, isServer, loaders: [ { loader: 'less-loader', options: lessLoaderOptions } ] }) }) if (typeof nextConfig.webpack === 'function') { return nextConfig.webpack(config, options) } return config } }) }
修改next.config.js
const withLessExcludeAntd = require("./next-less.config.js") // choose your own modifyVars const modifyVars = require("./utils/modifyVars") if (typeof require !== 'undefined') { require.extensions['.less'] = (file) => {} } module.exports = withLessExcludeAntd({ cssModules: true, cssLoaderOptions: { importLoaders: 1, localIdentName: "[local]___[hash:base64:5]", }, lessLoaderOptions: { javascriptEnabled: true, modifyVars: modifyVars }
详细前往:https://www.yuque.com/steven-kkr5g/aza/ig3x9w
三、组件级css
Next.js 通过 [name].module.css 文件命名约定来支持 CSS 模块 。
五、SSG和SSR
SSG-静态生成
最简单、性能也最优的预渲染方式就是静态生成(SSG),把组件渲染工作完全前移到编译时:
- (编译时)获取数据
- (编译时)渲染组件,生成 HTML
Demo:
// pages/demo.js export default function Home(props) { ... } // 获取静态数据 export async function getStaticProps() { const data = ... // The value of the `props` key will be // passed to the `Home` component return { props: ... } }
getStaticProps只在服务端执行(根本不会进入客户端 bundle),返回的静态数据会传递给页面组件(上例中的Home)。也就是说,要求通过getStaticProps提前备好页面所依赖的全部数据,数据 ready 之后组件才开始渲染,并生成 HTML。
Tips: 只有页面能通过getStaticProps
声明其数据依赖,普通组件不允许,所以要求将整页依赖的所有数据都组织到一处。
SSR-服务端渲染
Next.js 提供了 SSR 专用的getServerSideProps(context):
// pages/demo.js export async function getServerSideProps(context) { const res = await fetch(`https://...`) const data = await res.json() if (!data) { return { notFound: true, } } return { props: {}, // will be passed to the page component as props } }
每个请求过来时都执行,所以能够拿到请求上下文参数(context)
除了这个外,编码过程跟写React项目差不多。