Spring Boot+NextJS打包Jar部署Azure Spring Apps后静态资源404
Spring Boot + NextJS 部署Azure Spring Apps后静态资源404问题排查与解决
将Spring Boot后端与NextJS前端打包为Jar包并部署至Azure Spring Apps后,出现静态资源404错误,但本地环境运行完全正常。
相关配置信息
nextjs.config.mjs
/** @type {import('next').NextConfig} */ const nextConfig = { output: 'standalone', reactStrictMode: true, images: { unoptimized: true }, experimental: { proxyTimeout: 1000 * 120, // 120 seconds }, async rewrites() { return [ { source: '/api/:path*', destination: 'http://localhost:8080/api/:path*', }, ] }, } export default nextConfig
package.json(scripts片段)
"scripts": { "dev": "next dev", "build": "next build", "start": "next scdtart", "lint": "next lint" },
NextJS对应的pom.xml(插件片段)
<plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.11.3</version> <executions> <execution> <id>install node and npm</id> <goals> <goal>install-node-and-npm</goal> </goals> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> <phase>generate-resources</phase> </execution> <execution> <id>npm run build</id> <goals> <goal>npm</goal> </goals> <phase>generate-resources</phase> <configuration> <arguments>run build</arguments> </configuration> </execution> </executions> <configuration> <nodeVersion>v20.0.0</nodeVersion> </configuration> </plugin> </plugins>
依赖项(package.json片段)
"dependencies": { "@heroicons/react": "^2.1.1", "@tremor/react": "^3.14.0", "@vercel/analytics": "^1.1.3", "http-proxy-middleware": "^2.0.6", "next": "14.1.0", "next-auth": "^4.24.5", "nextjs-cors": "^2.2.0", "react": "^18", "react-dom": "^18" },
目标目录结构

问题排查与解决步骤
1. 修复package.json脚本拼写错误
package.json的start脚本存在拼写错误:next scdtart 需修正为 next start,错误会导致NextJS无法正常启动静态资源服务:
"scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" },
2. 确保NextJS构建产物被正确打包进Jar
通过maven-resources-plugin将NextJS构建产物(.next/standalone、.next/static、public目录)复制到Spring Boot的静态资源目录,修改pom.xml添加以下插件:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.1</version> <executions> <execution> <id>copy-nextjs-assets</id> <phase>process-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/classes/static</outputDirectory> <resources> <resource> <directory>${project.basedir}/.next/standalone</directory> <includes> <include>**/*</include> </includes> </resource> <resource> <directory>${project.basedir}/.next/static</directory> <includes> <include>**/*</include> </includes> </resource> <resource> <directory>${project.basedir}/public</directory> <includes> <include>**/*</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin>
3. 配置Spring Boot静态资源映射
添加Spring Boot配置类,确保静态资源路径被正确识别:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("classpath:/static/") .setCachePeriod(0); // 生产环境可调整为合适缓存时长 } }
4. 适配Azure环境调整NextJS路由重写
Azure Spring Apps环境中,后端服务地址并非localhost:8080,修改nextjs.config.mjs使用相对路径或环境变量:
async rewrites() { return [ { source: '/api/:path*', destination: '/api/:path*', // 改为相对路径,由Spring Boot直接处理 }, ] },
或通过环境变量动态配置:
async rewrites() { return [ { source: '/api/:path*', destination: `${process.env.BACKEND_URL || 'http://localhost:8080'}/api/:path*`, }, ] },
在Azure Spring Apps的应用配置中设置BACKEND_URL为实际后端服务地址。
5. 验证Jar包内容
重新打包后,解压Jar检查BOOT-INF/classes/static目录,确认包含.next/standalone、.next/static的所有文件,确保构建产物复制正确。
内容的提问来源于stack exchange,提问作者Asraful
相关产品推荐
相关产品推荐

