next.js v14 升级全步骤|迁移 pages Router 到 App Router

2024-06-15 21:20

本文主要是介绍next.js v14 升级全步骤|迁移 pages Router 到 App Router,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【概括】本文升级整体按照官网文档指引进行,在迁移 pages Router 前先看了官网的实操视频。

【注意】文章内对 .babel.ts、next.config.js 进行了多次更改,最终配置可见 报错3: Server Error ReferenceError: React is not defined

一、升级 Next.js 版本

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

升级后报错:

报错1:Build Error :You may need an appropriate loader to handle this file type, currently no loaders areconfigured to process this file

file type, currently no loaders areconfigured to process this file.
Failed to compile ●Next.js (14.2.3)
/components/GlobalLoading/index.module.less Module parse failed:
Unexpected token(1:0)You may need an appropriate loader to handle this
file type, currently no loaders areconfigured to process this file.
See https://webpack.js.org/concepts#loaders.container f
pointer-events: none; transition-property: opacity;

原因:next 内部支持 css 而不支持 less,我的项目在 next v12.1.6 时使用 next-plugin-antd-less 来支持 less,但根据官方文档来看,它只实现了对 next v11、v12 的支持,不支持 v14,因此我们选择安装其他包来支持。
在这里插入图片描述
解决方法:

npm install less less-loader next-with-less

配置:

// next.config.js
const withLess = require("next-with-less");module.exports = withLess({lessLoaderOptions: {/* 里面的配置根据自己的来,下面是我之前next-plugin-antd-less里的配置 */javascriptEnabled: true,modifyVars: {'@primary-color': '#4169E1','@primary-deep': '#3656F8','@background-color': '#F4F4F4',},additionalData: `@import "${__dirname}/src/styles/variables.less";`,},
});

参考文章:
如何在 next.js 13.4.13 中使用 less?
Next.js 和 Antd 以及 CSS Less 设置
next-with-less
Next13支持less&自定义less-module

报错2:Build Error:Syntax error: Selector “:global .ant-menu-sub” is not pure (pure selectors must contain at least one local class or id)

在这里插入图片描述
原因:scss 不期望在模块样式文件中使用全局选择器,我们最好使用类选择器,然后在类选择器内使用其他选择器。
解决方法:不要在 .module.scss 的第一层选择器使用 :global 或 标签选择器;如果需要全局拦截,考虑添加一个全局 css 文件(global.css)然后在 layout.tsx 里引入

// .module.scss,下面的写法是可以的
.root {a {color: red;}
}

参考文档:Selector “:global .class” is not pure

报错3:Build Error:Global CSS cannot be imported from within node_modules.

在这里插入图片描述
解决办法:我参考了很多文档,但还是没明白根本原因。我这里觉得是 less 文件的问题,因此修改了 webpack 配置,修改后在我本地可以正常运行。(后面觉得 next 对 less 的支持很不友好,于是放弃了 less,采用了 scss, 因此下面这段 webpack 配置最终也被替换)

// next.config.jswebpack(config, { isServer }) {config.module.rules.push({test: /\.less$/,use: [{loader: 'style-loader',},{loader: 'css-loader',},{loader: 'less-loader',options: {lessOptions: {javascriptEnabled: true,},},},],});return config;},
// .babelrc.js
module.exports = {presets: ['next/babel'],// 下面这行注释了,我这次更新就不用 antd 了,所以直接注释,升级完会把和 antd 相关的都删了// plugins: [['import', { libraryName: 'antd', style: true }]],
};

二、升级新功能

升级 Image

npx @next/codemod@latest next-image-to-legacy-image .

升级 Link

npx @next/codemod@latest new-link .

升级 Script

我没用到 Script ,升级可看官网

三、迁移 pages 到 app

报错1:TypeError: Property left of AssignmentExpression expected node to be of a type [“LVal”] but instead got “BooleanLiteral”

解决方法:参考下面文章,评论回复 .babelrc.js 文件在不必要时可删除,因此我删除后可以正常运行了。但在我继续升级中,.babelrc.js 还是增加了如下配置:

module.exports = {"presets": [ 'next/babel',],"plugins": []
}

参考文章:Upgrading nextjs from 12 to 14 and receiving Boolean Literal type error on node_modules/process/browser.js when trying to access env variables

报错2:Support for the experimental syntax ‘jsx’ isn’t currently enabled

解决方法: 安装两个包并配置如下内容

npm install --save-dev @babel/preset-env @babel/preset-react
// .babelrc.js
module.exports = {"presets": ["@babel/preset-env", "@babel/preset-react"]
}

参考文章:Support for the experimental syntax ‘jsx’ isn’t currently enabled

报错3: Server Error ReferenceError: React is not defined

在这里插入图片描述

总结:
把 less 换成 scss 了

// next.config.js
const path = require('path')const SassLoader = {sassOptions: {includePaths: [path.join(__dirname, 'styles')],prependData: `$primary-color: #4169E1;$primary-deep: #3656F8;$background-color: #F4F4F4;`,},
}
// babelrc.ts
module.exports = {"presets": [ 'next/babel',],
}

报错4: app-index.js:33 Warning: A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.

解决方法:当前文件顶部添加 'use client'
在这里插入图片描述

报错5: Server Error Error: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function

解决方法:当前文件顶部添加 'use client'
在这里插入图片描述

报错6: Server Error Error: Super expression must either be null or a function

解决方法:当前文件顶部添加 'use client'
在这里插入图片描述

App Router SEO 处理

在未升级前,我通过 url.pathname 为不同页面设置不同的 title、 content:

 <Head><title>{title}</title><meta name="description" content={description} /><meta name="keywords" content={keywords} /></Head>

但在升级之后,这些内容由 layout.tsx 的 generateMetadata 暴露出去,在 server component 中我无法直接获取 url 的 pathname
解决方法:通过中间件的形式注入 pathname,保证在 server component 里也可以获取到页面路径。采用设置 x-url 而不是直接读取请求头的 referer ,是因为直接输入 url 访问时 headers 没有 referer。

// middleware.ts
// eslint-disable-next-line @next/next/no-server-import-in-page
import { NextRequest, NextResponse } from "next/server";export function middleware(request: NextRequest) {const requestHeaders = new Headers(request.headers)requestHeaders.set('x-url', request.url);const response = NextResponse.next({request: {headers: requestHeaders,},})response.headers.set('x-url', request.url)return response
}
// layout.tsx
export async function generateMetadata(): Promise<Metadata | null> {const url = new URL(headers().get("x-url")!);let seoData = nulltry {seoData = seo(url.pathname)} catch (error) {}return seoData
}

middleware.ts 配置参考:
官方文档
github: How to access pathname in generateMetadata?

这篇关于next.js v14 升级全步骤|迁移 pages Router 到 App Router的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1064613

相关文章

idea报错java: 非法字符: ‘\ufeff‘的解决步骤以及说明

《idea报错java:非法字符:‘ufeff‘的解决步骤以及说明》:本文主要介绍idea报错java:非法字符:ufeff的解决步骤以及说明,文章详细解释了为什么在Java中会出现uf... 目录BOM是什么?1. BOM的作用2. 为什么会出现 \ufeff 错误?3. 如何解决 \ufeff 问题?最

使用Python和PaddleOCR实现图文识别的代码和步骤

《使用Python和PaddleOCR实现图文识别的代码和步骤》在当今数字化时代,图文识别技术的应用越来越广泛,如文档数字化、信息提取等,PaddleOCR是百度开源的一款强大的OCR工具包,它集成了... 目录一、引言二、环境准备2.1 安装 python2.2 安装 PaddlePaddle2.3 安装

Flutter实现文字镂空效果的详细步骤

《Flutter实现文字镂空效果的详细步骤》:本文主要介绍如何使用Flutter实现文字镂空效果,包括创建基础应用结构、实现自定义绘制器、构建UI界面以及实现颜色选择按钮等步骤,并详细解析了混合模... 目录引言实现原理开始实现步骤1:创建基础应用结构步骤2:创建主屏幕步骤3:实现自定义绘制器步骤4:构建U

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/