必须用 vscode 的 launch.json 配 "module": "flask" 模式启动调试,否则断点不生效、热重载失效、flask shell 不可用;因终端环境变量和虚拟环境不被 vscode 调试器识别,且 "program": "app.py" 会绕过 flask cli。

直接结论:不能靠终端里敲 flask run 或 python app.py 启动调试,必须用 VSCode 的 launch.json 配 "module": "flask" 模式,否则断点不生效、热重载失效、flask shell 不可用。
为什么 flask run 在终端能跑,但 VSCode 调试按钮点不动
VSCode 的调试器不读你终端里 export FLASK_APP=app.py 的环境变量,也不自动激活虚拟环境。它只认 launch.json 里写的 env 或 envFile。更关键的是:如果配置成 "program": "app.py",就绕过了 Flask CLI,所有基于 CLI 的功能(--reload、--debug、flask shell)全失效,断点也大概率不触发。
- 必须用
"module": "flask",不是"program" -
envFile必须指向项目根目录下的.env文件,内容为:FLASK_APP=app.py<br>FLASK_DEBUG=1
(注意:Flask ≥2.3 已弃用FLASK_ENV) - 项目必须用
File → Open Folder打开整个文件夹,不能只打开app.py单个文件 - 确保 VSCode 底部状态栏显示的 Python 解释器路径,和你
pip install flask的环境一致
launch.json 必须包含哪些字段才能稳定调试
缺一不可,否则要么找不到应用,要么端口绑定失败,要么断点进不去。
-
"module": "flask"—— 强制走 Flask 官方启动流程,支持 CLI 特性 -
"args": ["run", "--host=127.0.0.1:5000", "--no-reload", "--no-debugger"]——--no-reload防止 Werkzeug fork 子进程导致断点丢失;--no-debugger避免和 VSCode 调试器冲突 -
"envFile": "${workspaceFolder}/.env"—— 不能写相对路径或硬编码绝对路径 -
"justMyCode": true—— 关闭第三方库断点干扰(调试 Flask 自身逻辑时可临时设为false)
完整示例:
{
"name": "Flask: Run",
"type": "python",
"request": "launch",
"module": "flask",
"args": ["run", "--host=127.0.0.1:5000", "--no-reload", "--no-debugger"],
"envFile": "${workspaceFolder}/.env",
"justMyCode": true
}
用了工厂函数 create_app() 怎么配
入口不再是 app = Flask(...),而是通过函数返回实例,FLASK_APP 无法直接指向文件,必须显式指定模块和函数名。
-
.env中删掉FLASK_APP=app.py,改用args传参 -
"args"改为:["--app", "app:create_app", "run", "--debug", "--no-reload"](假设app.py里定义了create_app()) - 若文件在子目录如
src/app.py,则写成"--app", "src.app:create_app",并确保项目根目录是 Python 模块搜索路径(即src上级目录被设为工作区) - 代码中不能保留
if __name__ == '__main__': app.run(...),会和launch.json冲突
断点不生效、改代码后静默退出的真正原因
根本不是 Flask 配置错,而是 Werkzeug 的 --reload 机制在 fork 子进程,VSCode 默认只 attach 主进程,旧断点挂在已销毁的进程上。
- 最稳方案:调试阶段坚持用
--no-reload,手动Ctrl+C+ 重启 - 非要热重载?可试
"subProcess": true,但 Windows 下成功率低,且可能 attach 失败 - 检查文件编码是否为 UTF-8 无 BOM,BOM 会导致
ImportError,进而让 reloader 静默失败 - 断点别打在模块顶层(比如
app.run()下面),必须打在路由函数内部——只有请求上下文里,request、session等对象才可用
复杂点在于:路径、环境变量、启动方式三者必须对齐。少一个,Could not locate a Flask application 就立刻报出来;多一个干扰项(比如残留的 app.run()),调试就变成玄学。











