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

相关文章

vite搭建vue3项目的搭建步骤

《vite搭建vue3项目的搭建步骤》本文主要介绍了vite搭建vue3项目的搭建步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1.确保Nodejs环境2.使用vite-cli工具3.进入项目安装依赖1.确保Nodejs环境

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多

Linux云服务器手动配置DNS的方法步骤

《Linux云服务器手动配置DNS的方法步骤》在Linux云服务器上手动配置DNS(域名系统)是确保服务器能够正常解析域名的重要步骤,以下是详细的配置方法,包括系统文件的修改和常见问题的解决方案,需要... 目录1. 为什么需要手动配置 DNS?2. 手动配置 DNS 的方法方法 1:修改 /etc/res

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

Ubuntu向多台主机批量传输文件的流程步骤

《Ubuntu向多台主机批量传输文件的流程步骤》:本文主要介绍在Ubuntu中批量传输文件到多台主机的方法,需确保主机互通、用户名密码统一及端口开放,通过安装sshpass工具,准备包含目标主机信... 目录Ubuntu 向多台主机批量传输文件1.安装 sshpass2.准备主机列表文件3.创建一个批处理脚

使用Node.js和PostgreSQL构建数据库应用

《使用Node.js和PostgreSQL构建数据库应用》PostgreSQL是一个功能强大的开源关系型数据库,而Node.js是构建高效网络应用的理想平台,结合这两个技术,我们可以创建出色的数据驱动... 目录初始化项目与安装依赖建立数据库连接执行CRUD操作查询数据插入数据更新数据删除数据完整示例与最佳

docker编写java的jar完整步骤记录

《docker编写java的jar完整步骤记录》在平常的开发工作中,我们经常需要部署项目,开发测试完成后,最关键的一步就是部署,:本文主要介绍docker编写java的jar的相关资料,文中通过代... 目录all-docker/生成Docker打包部署文件配置服务A的Dockerfile (a/Docke