You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Heroku部署Django+React项目遇Uncaught SyntaxError问题求助

解决Django+React部署Heroku时bundle.js返回index.html的问题

嘿,这个问题我之前帮朋友排查过,本质上就是Heroku上请求你的bundle.js时,Django没找到对应的静态文件,反而返回了index.html,浏览器把HTML当JS解析自然就报Uncaught SyntaxError: Unexpected token <错了。咱们一步步来解决:

1. 先搞定Heroku的构建顺序

Heroku需要先打包React代码,再收集Django静态文件,所以得调整buildpack的顺序:

  • 登录Heroku控制台,进入你的项目设置,找到Buildpacks
  • 添加两个buildpack:先加heroku/nodejs,再加heroku/python(顺序很重要,先处理Node.js的构建)

2. 确保Webpack打包能在Heroku上自动执行

  • 打开React项目目录下的package.json,在scripts里添加生产环境打包命令:
    "scripts": {
      "build": "webpack --mode production",
      // 其他脚本...
    }
    
  • 如果你的React项目在子目录(比如frontend),根目录的package.json要把build命令指向子目录:
    "scripts": {
      "build": "cd frontend && npm run build"
    }
    

3. 修正Django的静态文件配置(关键)

打开settings.py,调整这些配置:

  • 确保INSTALLED_APPS里whitenoise的顺序正确(在django.contrib.staticfiles之前):
    INSTALLED_APPS = [
        'whitenoise.runserver_nostatic',
        'django.contrib.staticfiles',
        # 你的其他应用...
    ]
    
  • 调整MIDDLEWARE顺序(WhiteNoiseMiddleware要在SecurityMiddleware之后):
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'whitenoise.middleware.WhiteNoiseMiddleware',
        # 其他中间件...
    ]
    
  • 配置静态文件路径,让Django能找到Webpack打包后的文件:
    from pathlib import Path
    BASE_DIR = Path(__file__).resolve().parent.parent
    
    STATIC_URL = '/static/'
    STATIC_ROOT = BASE_DIR / 'staticfiles'  # Heroku收集静态文件的目录
    STATICFILES_DIRS = [
        BASE_DIR / 'frontend' / 'dist',  # 替换成你的Webpack输出目录
    ]
    # 启用Whitenoise的压缩和缓存优化(可选但推荐)
    STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
    

4. 检查Webpack的配置

打开webpack.config.js,确保publicPath和BundleTracker的路径正确:

const path = require('path');
const BundleTracker = require('webpack-bundle-tracker');

module.exports = {
    entry: './src/index.js', // 你的React入口文件
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'), // 输出到对应目录
        publicPath: '/static/' // 关键!生成的bundle路径要以/static/开头
    },
    plugins: [
        new BundleTracker({
            path: path.resolve(__dirname, '../'), // 生成webpack-stats.json到项目根目录
            filename: 'webpack-stats.json'
        })
    ],
    // 其他Webpack配置...
};

5. 修正Django的URL路由顺序

确保你的SPA catch-all路由是最后一个,这样静态文件请求不会被它拦截:

from django.urls import path
from django.views.generic.base import TemplateView

urlpatterns = [
    # 你的API路由、admin路由等...
    # 最后添加SPA的兜底路由
    path('', TemplateView.as_view(template_name='index.html')),
]

6. 最后检查几个细节

  • 确保Heroku上的DEBUG环境变量设为False(生产环境不能开DEBUG):
    用Heroku CLI执行:heroku config:set DEBUG=False
  • 查看Heroku的构建日志,确认:
    • npm run build成功执行,生成了bundle.js
    • python manage.py collectstatic成功把bundle.js复制到了staticfiles目录

这样调整后,Heroku就能正确识别并返回你的bundle.js,不会再返回index.html了。

内容的提问来源于stack exchange,提问作者Jehob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:21:54