用途:从零搭起可端到端跑通的后端(Spring Boot + MyBatis-Plus + MySQL)与前端(Vite + Vue 3),并在 VS Code 中按界面操作跑起来、打出包。 通用教程,不绑定具体业务工程;
文中
demo_db、com.example.demo、8080、5173均为示例值,落到具体工程时替换成实际库名、包名与端口即可。 版本基线:JDK 17、Maven 3.9+、Node 22/24、MySQL 8、Spring Boot 3.x、持久层 MyBatis-Plus 3.5.14。
前置条件自检
先确认四件工具在位,再开始建工程。缺任何一件都会在后面以难以定位的方式报错。
| 依赖 | 版本要求 | 自检命令 |
|---|---|---|
| JDK | 17(Boot 3.x/4.x 的 baseline 均为 17) | java -version |
| Maven | 3.9 以上 | mvn -v |
| Node | 满足前端工程的 engines,Vite 8 要求 ^22.18.0 \|\| >=24.12.0 | node -v && npm -v |
| MySQL | 8.x,且本机 3306 有服务在监听 | nc -z 127.0.0.1 3306 && echo ok |
mvn -v 的输出里会同时打印 Maven home 与 Java runtime,两行都要核对,避免命令行 Maven 与 IDE 用的是不同 JDK。
创建后端 Spring Boot 工程
安装扩展
| 扩展 | 作用 | 必需性 |
|---|---|---|
| Spring Boot Extension Pack | 属性文件智能提示、Spring Initializr 建工程、Boot Dashboard 启动 | 必需 |
| Extension Pack for Java | 编译、调试、运行、Maven 视图 | 必需 |
| Prettier / ESLint | 代码格式化与规范检查 | 非必需 |
| GitLens | 提交历史与代码归属 | 非必需 |
扩展只需装一次。工程已存在时跳过本节,不要重复执行建工程命令,否则会生成第二份工程。
生成工程
Cmd+Shift+P(Win 为 Ctrl+Shift+P)→ 输入 Spring Initializr: Create a Maven Project:
| 选项 | 取值 |
|---|---|
| 语言 | Java |
| Spring Boot 版本 | 界面与站点只提供当前受支持的版本。 |
| Group / Artifact | 如 com.example / demo |
| 打包方式 | Jar |
| Java | 17 |
依赖勾选:
| 分类 | 依赖 | 说明 |
|---|---|---|
| Web | Spring Web | 必选。构建 RESTful API,支持前后端分离 |
| SQL 数据库 | MySQL Driver | 必选。连接 MySQL 的驱动 |
| SQL 数据库 | MyBatis Framework | Initializr 只提供原生 MyBatis 坐标;持久层按 2.3 整件替换为 MyBatis-Plus |
| 开发者工具 | Lombok | 强烈推荐。注解简化实体类,减少 getter/setter 冗余 |
| 开发者工具 | Spring Boot DevTools | 可选。改代码后自动重启;与 VS Code 断点调试并用时可能出现二次重启,调试为主的环境可不装 |



版本对照:parent 决定坐标名
生成后第一件事是打开 pom.xml,核对 parent 版本与下表坐标名。Initializr 界面只提供原生 MyBatis 选项,MyBatis-Plus 需在生成后手工替换坐标。
| 用途 | Spring Boot 3.x | Spring Boot 4.x |
|---|---|---|
| Web | spring-boot-starter-web | spring-boot-starter-webmvc |
| Web 测试 | spring-boot-starter-test | spring-boot-starter-webmvc-test |
| 持久层(采用) | mybatis-plus-spring-boot3-starter 3.5.14 | mybatis-plus-spring-boot4-starter 3.5.14 |
| 分页插件 | mybatis-plus-jsqlparser 3.5.14(3.5.9 起从主件拆出,须显式引入) | 同左 |
| 持久层(Initializr 默认给的原生件,对照用) | mybatis-spring-boot-starter 3.0.x | mybatis-spring-boot-starter 4.0.x |
采用 MyBatis-Plus 时,把 pom.xml 里的 mybatis-spring-boot-starter 整件换成对应 Boot 版本线的 MP starter,并追加 mybatis-plus-jsqlparser:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.14</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>3.5.14</version>
</dependency>
三点约束:
- 坐标与 parent 版本不匹配的表现是启动期
ClassNotFoundException或自动配置不生效,而不是编译报错,因此必须在 2.2 完成后立即核对。 - 从 4.x 降到 3.x 时,parent、Web、Web 测试、MyBatis 四处要一起改:
spring-boot-starter-webmvc→spring-boot-starter-web、spring-boot-starter-webmvc-test→spring-boot-starter-test、mybatis-spring-boot-starter4.0.1→3.0.5。只降 parent 不改坐标会直接解析不到依赖。 - Boot 2 用的
mybatis-plus-boot-starter随包带 MyBatis-Spring 2.x,与 Boot 3 不兼容;Boot 3 只能用带boot3的坐标,Boot 4 用带boot4的坐标。 - MP starter 随包的 MyBatis-Spring 版本与原生 starter 同线(实测 MP 3.5.5/3.5.6 随包 3.0.3),换框架不换 MyBatis 本体,Mapper XML 的写法不变。
application.yml
server:
port: 8080
spring:
application:
name: demo
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: "jdbc:mysql://localhost:3306/demo_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai"
username: <数据库账号>
password: ${DEMO_DB_PASSWORD} # 环境变量注入,不写死明文
# MyBatis-Plus 配置(前缀只能是 mybatis-plus)
mybatis-plus:
type-aliases-package: com.example.demo.entity
configuration:
map-underscore-to-camel-case: true # 数据库下划线字段转 Java 驼峰
# mapper-locations 默认已是 classpath*:/mapper/**/*.xml,XML 放该目录下无需写此项
四点约束:
type-aliases-package必须与工程实际包名一致。Initializr 生成的包名由 Group + Artifact 拼出,照抄模板值会导致别名不生效。- 前缀写成
mybatis.时 MyBatis-Plus 完全不读取,表现为别名与驼峰转换静默失效,报错形态是ClassNotFound或字段映射不上,而不是配置错误;换回原生 MyBatis 时反过来同理。 - 需要把 XML 放到默认路径之外时才显式写
mapper-locations,且目录必须真实存在(src/main/resources/mapper/)。 url值含&,加引号写更稳妥。
建库与导入表结构
配置写好后,数据库本身要先存在,否则任何一次查询都会失败。
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS demo_db DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;"
# 有现成 SQL 脚本时继续导入:
mysql -u root -p demo_db < /path/to/schema.sql
# 校验表是否到位:
mysql -u root -p -e "USE demo_db; SHOW TABLES;"
启动与分层验证
启动方式三选一:
- 打开
src/main/java/.../Application.java,点击main上方的 Run 按钮。 - Spring Boot Dashboard 面板启动。
- 命令行:
# 推荐直接用已安装的 Maven
mvn -f pom.xml spring-boot:run
# 用工程自带的 Maven Wrapper 时注意前置条件:
# - 首次运行需联网下载发行版,地址见 .mvn/wrapper/maven-wrapper.properties 的 distributionUrl
# - macOS/Linux 提示 Permission denied 时执行 chmod +x mvnw
./mvnw spring-boot:run
验证按三层递进,只过第一层不代表环境可用:
| 层级 | 动作 | 通过标志 |
|---|---|---|
| L1 启动 | 看控制台日志 | Tomcat started on port 8080 (http) with context path '/'(Boot 3.4.8 实测原文,前面还有一行 Tomcat initialized with port 8080 (http);跨版本认前缀 Tomcat started on port 即可) |
| L2 接口 | curl http://localhost:8080/api/hello | 返回预期文本 |
| L3 数据 | 调用一个真正查库的接口,或加一条 CommandLineRunner 执行 SELECT COUNT(*) | 返回结果而非异常栈 |
L2 依赖 4.2 的 HelloController、L3 依赖 2.5 建好的库与 2.7 的 Mapper,因此这三层在第四步配完代理之后再一次性回归;本节只需确认 L1。
L1 通过但 L3 失败是常态:连接池是懒加载,数据库不可达时启动日志依旧正常,问题只在首次查询时暴露。
Mapper 注册
新增 Mapper 接口后必须注册,否则报 NoSuchBeanDefinitionException。继承 BaseMapper 即获得单表 CRUD,注册方式两种选一:
// 写法一:接口上加 @Mapper,并继承 BaseMapper 拿到单表 CRUD
@Mapper
public interface UserMapper extends BaseMapper<User> {
User selectByMobile(String mobile); // 自定义方法,SQL 写在注解或 XML
}
// 写法二:启动类上批量扫描,接口无需注解
@MapperScan("com.example.demo.mapper")
@SpringBootApplication
public class DemoApplication { /* ... */ }
实体类侧配 MP 注解,表名与主键策略在此声明,避免依赖默认推断:
@Data
@TableName("sys_user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String mobile;
}
分页插件
MP 的分页靠拦截器,缺两步就是静默不截断(返回全部数据且不报错),最难察觉:
pom.xml里除 starter 外还要有mybatis-plus-jsqlparser(3.5.9 起分页插件从主件拆出,见 2.3)。- 注册
MybatisPlusInterceptorBean,并显式指定数据库类型:
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
用法:
Page<User> page = new Page<>(current, size); // current 从 1 开始
IPage<User> result = userMapper.selectPage(page,
new QueryWrapper<User>().eq("status", 1));
// result.getRecords() 为当页数据,result.getTotal() 为总数
不指定 DbType.MYSQL 时由数据源自动推断,多数据源或代理层后推断可能出错,显式写更稳。
创建前端 Vue 工程
创建
在后端工程的同级目录下执行(官方推荐 Vite):
npm create vue@latest
按提示输入项目名,其余选项 TypeScript、Router、Pinia、Vitest、ESLint 视需要选择;只要先跑起来可全部选 No。Router 与 Pinia 后续再加需要改动入口文件,初始就勾选更省事。

安装与运行
cd demo-web
npm install
npm run dev

可以命令也可以直接在package.json里面调试

- 终端会给出一个本地地址(通常是
http://localhost:5173),在浏览器打开就能看到 Vue 的欢迎页面了。

配置代理解决跨域
开发期前端在 5173、后端在 8080,同源策略会拦截直接请求。推荐由开发服务器转发请求,前端代码里统一写 /api/xxx。
vite.config.js
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server: {
proxy: {
'/api': {
target: 'http://localhost:8080', // 与 server.port 同值
changeOrigin: true
// 后端接口本身不带 /api 前缀时才需要下面这行
// rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
修改 vite.config.js 后须重启 npm run dev,热更新不覆盖配置文件本身。
后端接口对应写法
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello from Spring Boot!";
}
}
前端请求写法
// fetch
fetch('/api/hello')
.then(res => res.json())
.then(data => console.log(data))
// axios
import axios from 'axios'
axios.get('/api/hello').then(res => console.log(res.data))
/api/hello 返回的是字符串,.json() 会解析失败;接口返回 JSON 时才用 res.json(),纯文本用 res.text()。
rewrite 取舍
| 后端路径写法 | 是否加 rewrite | 请求链路与结果 |
|---|---|---|
@RequestMapping("/api") + @GetMapping("/hello") | 不加 | 前端 /api/hello → http://localhost:8080/api/hello,匹配 |
只有 @GetMapping("/hello") | 要加 | 前端 /api/hello → 去掉 /api → http://localhost:8080/hello |
采用第一种:后端统一带 /api 前缀,配置更简单,上线时也便于区分前后端路径。
端口一致性
同一个端口值出现在三处:后端 server.port、前端 proxy.target、上线后的反向代理上游。改动端口时三处同步,否则表现为代理 502 或连接被拒绝,而日志分属两个进程,不易联想到一起。
端到端验证顺序
- 后端单独可用:
curl http://localhost:8080/api/hello有返回。 - 前端启动:
npm run dev后浏览器打开 5173 页面正常。 - 页面里发请求:开发者工具 Network 面板中
/api/hello状态为 200,Response 为后端文本。 - 只有第 1 步通、第 3 步 404 → 检查
rewrite与后端前缀是否匹配;第 3 步 502 或ECONNREFUSED→ 检查proxy.target端口与后端是否同值、后端是否在跑。
在 VS Code 中的界面操作
只打开父目录时,Java 扩展会自动向下发现 pom.xml;右下角会弹出导入进度,状态栏的 Java 状态图标转为就绪后才可运行。导入未完成时 Run 按钮、Maven 面板、Spring Boot Dashboard 都可能空白,此时先等进度,不要重复执行建工程命令。新增目录或改动 settings.json 后执行 Developer: Reload Window。
视图位置
| 视图 | 在哪里 | 用途 |
|---|---|---|
MAVEN | 资源管理器侧栏下部 | 展开工程 → Lifecycle → 右键 clean / compile / test / package / verify / install;Plugins下展开spring-boot执行spring-boot:run;面板右上的刷新图标重新扫描工程,Custom…` 用于输入自定义 goal |
Java Projects | 资源管理器侧栏 | 查看工程与依赖库、按工程 Build / Rebuild;每个类条目上有 Run / Debug |
Spring Boot Dashboard | 左侧活动栏独立图标 | Apps 列表中悬停条目出现 Run / Debug / Stop / Open In Browser,右键可 Run with Profile... |
Logical Structure | 资源管理器侧栏 | 按 Controller、请求映射分组浏览接口 |
Beans / Endpoint Mappings / Properties / Memory | Spring Boot Dashboard 容器内的页签 | 进程运行中核对已注册接口与生效配置 |


MAVEN 面板逐项用途

Lifecycle 十个阶段,按日常使用频率排列(非执行顺序):
| 阶段 | 做什么 | 什么时候用 |
|---|---|---|
compile | 编译 src/main/java 到 target/classes,同时拷贝资源 | 只想验证能否编译;Run Java 报找不到主类且 target/classes 为空时手动补一次 |
test | 编译并运行单元测试,报告落在 target/surefire-reports | 提交前跑一遍 |
package | 编译 + 测试 + 打成 target/<artifactId>-<version>.jar | 出可执行产物。跳过测试用 Favorites 或 Custom… 输 package -DskipTests |
clean | 删除整个 target/ | 换 JDK、换依赖版本、产物行为诡异时先 clean 再构建 |
install | 把 jar 连同 pom 装进 ~/.m2/repository | 本机其他工程需要引用该 jar 时 |
validate | 校验 pom.xml 与工程结构是否合法 | 依赖坐标写错、profile 不生效时排查 |
test-compile | 只编译 src/test/java 到 target/test-classes | 单独定位测试代码的编译错 |
verify | package 之后再跑集成测试与质量门禁 | 需有插件绑定(如 failsafe),未配则等同空跑 |
site | 生成项目报告站点 | 未配 site 插件时用不到 |
deploy | 发布到远程仓库 | 需 distributionManagement;本地开发阶段不要点,会尝试向远端推送 |
阶段条目上带 ▶ 的,表示该插件在 pom.xml 里配了多个 execution,展开后按 execution id 分别执行。右键任一阶段是 Run/Debug,Debug 挂的是 Maven 进程自身的远程调试,日常用 Run。
其余四个分组:

| 分组 | 用途 |
|---|---|
Plugins | 按插件枚举其全部 goal。展开 spring-boot 执行 spring-boot:run,等价于命令行的 mvn spring-boot:run;插件条目上的刷新图标只重新枚举该插件 |
Dependencies | 依赖树。右键工程条目 Add a dependency... 可直接搜坐标并写回 pom.xml;版本冲突的条目上另有 Resolve Conflict... 与 Go to Effective Dependency,后者跳到合并后的 effective pom 看最终生效版本 |
Favorites | 常用命令收藏。Add a favorite... 存一条带完整参数的命令(如 package -DskipTests),之后一键执行 |
Profiles | 勾选即在每次执行时附加 -P<id>,用来切 dev/prod 这类 profile,改完不必再动运行配置 |
运行与调试后端
| 目的 | 界面入口 |
|---|---|
| 快速跑起来 | 打开 src/main/java/.../Application.java,main 方法上方的 CodeLens 点 Run Java;打断点则点 Debug Java |
| 不离开面板 | 活动栏 Spring Boot Dashboard → 条目上点 Run / Debug;带 profile 用 Debug with Profile... |
| 按配置启动 | 左侧「运行和调试」侧栏 → 顶部下拉选配置 → F5。配置来自 .vscode/launch.json:mainClass 填全限定类名,projectName 填 pom.xml 的 <artifactId>;目录树里存在多份 launch.json 时,下拉列表只显示当前窗口打开那一层的配置 |
| 断点 | 编辑器行号左侧单击设断点;命中后用调试工具栏的 继续 / 单步跳过 / 单步进入 / 跳出,左侧 变量、调用堆栈、断点 面板查看状态 |
| 热改代码 | 调试命令 Hot Code Replace 只替换方法体;新增字段、改方法签名仍需重启 |
| 停止 | 调试工具栏红色方块,或 Dashboard 的 Stop |
运行与调试前端
| 目的 | 界面入口 |
|---|---|
| 启动开发服务器 | 打开 package.json,scripts 中 dev 一行上方出现 Run 小字,点该 Run 即执行;也可在资源管理器右键 package.json → Run Script… |
| 依赖安装 | 同一处 Run 下拉选 install |
| 两个服务并行 | 终端面板(Ctrl+``)右上 +` 新建第二个终端,分别跑后端与前端;面板上方标签可重命名 |
| 端口查看 | 终端面板旁的 端口 页签,可见 Vite 的 5173 与后端端口 |
| Vue 语言服务异常 | 命令面板执行 Vue: Restart Vue servers |
| 前端断点 | launch.json 增加 "type": "chrome" 配置指向 5173;前后端各占一个调试会话,调试工具栏顶部下拉切换 |
面板与日志
| 面板 | 看什么 |
|---|---|
问题 | 编译错误、Lombok 未生效导致的 getter/setter 报错 |
输出 → 下拉选 Language Support for Java | 工程导入与 Maven 依赖解析过程 |
输出 → 下拉选 Spring Boot | Spring Boot 语言服务器日志 |
终端 / 调试控制台 | 运行期日志与断点输出 |
运行和调试 → 调用堆栈 | 启动期异常的定位 |
相关设置项
设置界面(Cmd+,)搜名称即可,也可直接改 settings.json。改后需 Developer: Reload Window。
| 键 | 取值口径 |
|---|---|
maven.executable.path | 指到 <Maven home>/bin/mvn 这个文件,指目录必定报 no such file or directory |
maven.settings.path | 指 ~/.m2/settings.xml |
java.jdt.ls.java.home、java.configuration.runtimes | JDK 17 路径 |
java.jdt.ls.lombokSupport.enabled | true,否则 @Data 报错 |
java.errors.incompleteClasspath.severity | error,让类路径缺失早暴露 |
maven.excludedFolders | 含 **/bin,与 Java 源码目录同名时会连带隐藏,需要看这类目录时临时移除该项 |
排错清单
| 现象 | 原因 | 处置 |
|---|---|---|
no such file or directory: .../maven/current/bin | maven.executable.path 指向了 bin 目录而非可执行文件;或该目录本身不存在 | 填 <Maven home>/bin/mvn 完整文件路径,用 mvn -v 先验证 |
改了 settings.json 不生效 | 扩展缓存旧配置 | Developer: Reload Window |
Run Java 报 找不到或无法加载主类,且 target/classes 里没有对应 .class | 点运行时编译尚未产出。Run Java 走 Java 语言服务器的构建结果而非 Maven 构建,工程导入未完成或语言服务器侧仍有编译错误时,classpath 首项指向的 target/classes 是空目录,而 Run 按钮照样可点 | 等右下角 Java 导入进度结束再运行;或先在 MAVEN → Lifecycle 右键 compile 落一次产物。判读顺序:先看 target/classes 有无 .class,为空则是构建问题,不是启动配置问题 |
F5 启动报找不到主类(.class 已存在) | .vscode/launch.json 的 mainClass/projectName 与真实包名、pom.xml 的 <artifactId> 不一致;Initializr 生成的默认值常对不上 | 两项改成实际值;同一目录树存在多份 launch.json 时先确认当前窗口打开的是哪一层——层级决定 classpath 指向哪个 target/classes |
@Data 报找不到 getter/setter | Lombok 注解处理器未生效 | 设置项 java.jdt.ls.lombokSupport.enabled: true,并在 maven-compiler-plugin 配 annotationProcessorPaths |
启动正常、查询报 Unknown database | 库没建 | 执行 2.5 的 CREATE DATABASE |
导入脚本报 No database selected | 脚本只含 CREATE TABLE,无 CREATE DATABASE/USE | 先建库再 mysql -u root -p <db> < xxx.sql |
接口报 NoSuchBeanDefinitionException: ...Mapper | Mapper 未注册 | 见 2.7 |
| 代理请求 404 | rewrite 与后端前缀不匹配 | 见 4.4 |
代理请求 502 / ECONNREFUSED | proxy.target 端口与后端不一致,或后端未启动 | 见 4.5 |
npm install 失败或告警 | Node 版本不满足工程 engines | 见第一章自检 |
./mvnw 长时间无输出或 Permission denied | Wrapper 需联网下载发行版;脚本无执行权限 | 联网后重试,或直接改用 mvn;chmod +x mvnw |
编译报 PaginationInnerInterceptor 无法解析,或分页返回全部数据且不报错 | 缺 mybatis-plus-jsqlparser,或 MybatisPlusInterceptor Bean 未注册 | 见 2.3 与 2.8 |
| MP 的别名、驼峰转换全部失效 | 前缀写成 mybatis.,MP 只认 mybatis-plus. | 见 2.4 |
Run 按钮不出现、MAVEN 面板或 Dashboard 空白 | 工程未被识别或导入尚未完成;pom.xml 不在被扫描的目录内 | 等状态栏导入结束;MAVEN 面板右上点刷新图标;仍不识别则命令面板执行 Java: Clean Java Language Server Workspace 后 Reload Window |
启动报 Port 8080 was already in use | 上一次进程未退出 | 调试工具栏或 Dashboard 停止;lsof -nP -iTCP:8080 -sTCP:LISTEN 找到 PID 再结束 |
@Data 报错已消失但运行期类找不到 | 语言服务器缓存过期 | Java: Clean Java Language Server Workspace |
生成工程时报 400 Invalid Spring Boot version ... compatibility range is >=4.0.0 | Initializr 站点只保留当前受支持版本,旧版本线不在可选范围 | 先按默认 4.x 生成,再按 2.3 把 parent 与坐标一起改到目标 3.x 版本 |
| 只降 parent 后依赖解析失败 | Web/测试/MyBatis 三处坐标名随版本线不同 | 按 2.3 对照表逐项改名 |
配置与凭据口径
- 数据源口令一律用环境变量占位(
${DEMO_DB_PASSWORD}),不写入配置文件,不提交进版本库。 - 本地调试用的环境变量文件(如
.env)加入.gitignore;VS Code 调试配置中的envFile指向的文件必须先存在,否则启动直接失败。 - 配置项出现的位置写成文件路径与配置项名即可,不落具体口令值。
打包与产物
| 目标 | 界面入口 | 命令等价 | 产物 |
|---|---|---|---|
| 后端可执行 jar | MAVEN → Lifecycle → 右键 package | mvn -DskipTests package | target/<artifactId>-<version>.jar,内含依赖,可直接 java -jar |
| 装进本地仓库供其他模块引用 | 同上 install | mvn -DskipTests install | ~/.m2/repository/<groupPath>/<artifactId>/<version>/ |
| 只跑测试 | 同上 test | mvn test | — |
| 前端静态资源 | package.json 的 build 行点 Run | npm run build | dist/,纯静态,交给任意静态服务器 |
| 前端本地预览打包结果 | 终端执行 preview 脚本 | npm run preview | 输出一个本地地址 |
运行后端产物:
java -jar target/demo-0.0.1-SNAPSHOT.jar --server.port=8080
# profile 与数据库口令同样以参数或环境变量注入
DEMO_DB_PASSWORD=... java -jar target/demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
两条注意:
package会执行测试,测试类里若注入了DataSource而无可用数据库会失败;本地验证跳过测试时用MAVEN面板的Custom…输入package -DskipTests,或直接用命令行的mvn -DskipTests package。- 前端
dist/里的资源路径由base决定,部署到子路径时须同步设置vite.config.js的base,否则白屏报资源 404。开发期的server.proxy不进构建产物。

