【问题标题】:Error: 'Uncaught SyntaxError: Unexpected token <' (Django + React + Webpack)错误:'Uncaught SyntaxError: Unexpected token <' (Django + React + Webpack)
【发布时间】:2018-03-06 10:49:50
【问题描述】:

我关注 this tutorial 来设置 Django 以使用 webpack 生成的包提供模板。我已经按照教程中的方式进行了设置。但是问题是当我转到localhost:8000 时,当我在chrome devtools 中打开控制台时,我得到Uncaught SyntaxError: Unexpected token &lt; 异常。除了 reactjs 包之外,我放入模板文件中的其他 html 都会被渲染。我的文件夹结构如下:

.
├── djangoapp
│   ├── db.sqlite3
│   ├── djangoapp
│   │   ├── __init__.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── manage.py
│   ├── reactapp
│   │   └── static
│   │       ├── bundles
│   │       │   └── main-fdf4c969af981093661f.js
│   │       └── js
│   │           └── index.jsx
│   ├── requirements.txt
│   ├── templates
│   │   └── index.html
│   └── webpack-stats.json
├── package.json
├── package-lock.json
└── webpack.config.js

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'webpack_loader'
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates"), ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WEBPACK_LOADER = {
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'bundles/',
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
    }
}

STATIC_URL = 'static/'

webpack.config.js

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

module.exports = {
  context: __dirname,

  entry: './djangoapp/reactapp/static/js/index.jsx', 

  output: {
      path: path.resolve('./djangoapp/reactapp/static/bundles/'),
      filename: "[name]-[hash].js",
  },

  plugins: [
    new BundleTracker({filename: './djangoapp/webpack-stats.json'}),
  ],

  module: {
    rules: [
      { test: /\.js$/, use: ['babel-loader'], exclude: /node_modules/},
      { test: /\.jsx$/, use: ['babel-loader'], exclude: /node_modules/}
    ]
  },

  resolve: {
    modules: ['node_modules', 'bower_components'],
    extensions: ['.js', '.jsx']
  },


};

模板/index.html

{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>Example</title>
 </head>
 <body>
 <div id="react"></div>
 {% render_bundle 'main' %}
 </body>
</html>

.babelrc

{
  "presets": ["babel-preset-env", "react"]
}

main-fdf4c969af981093661f.js 文件的第 1 行的开头,&lt;!DOCTYPE html&gt; 元素的开始标记上引发异常。我的猜测是浏览器需要 javascript 代码,而是给定了 html。另外,我不明白 Django 是如何知道在哪里查找包的,因为我没有在任何地方指定 static/bundles 的根(reactapp 目录)。

【问题讨论】:

  • 不确定这是否是问题,但您应该将“env”而不是“babel-preset-env”作为 .babelrc 中的预设写
  • @MatanBobi 你是对的,但这并不能解决问题。

标签: javascript django reactjs webpack django-templates


【解决方案1】:

一段时间后我通过将以下代码添加到settings.py 解决了这个问题。

STATICFILES_DIRS = [
   ('bundles', os.path.join(BASE_DIR, 'reactapp/bundles'))
]

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

我还必须将STATIC_URL 更改为/static/

它应该是这样工作的:

  • Webpack 生成捆绑包到 reactapp/bundles 文件夹。
  • 当 Django 服务器运行时,它会扫描 reactapp/bundles 和 每次新更改后,将文件夹的内容复制到由 STATIC_ROOT 设置定义的根 djangoapp/static/ 文件夹。
  • 之后STATIC_ROOT中的文件可以通过STATIC_URL被浏览器访问,如下所示:localhost:8000/static/bundles/&lt;bundle&gt;。它通常默认为localhost:8000/static/&lt;bundle&gt;,但STATICFILES_DIRS 中元组的第一个元素明确告诉Django 复制static/bundles 目录中的内容。
  • 然后,Django 在提供页面时会自动生成指向静态文件的链接。

注意: STATIC_URL 应该在前面加上 / 否则静态路径将被附加到当前页面链接而不是根。例如,在/index 页面上,静态文件的链接将是localhost:8000/index/static/... 而不是localhost:8000/static,这将是错误的,会导致404 not found

【讨论】:

    【解决方案2】:

    这是一个棘手的问题!一切似乎都完美地进行了。首先,请确保django-webpack-loader 已按预期安装。其次,您的担忧似乎是有效的,我们必须告诉 django 究竟在哪里寻找捆绑软件,因为默认情况下它使用 STATIC_URL + bundle_name(如 http://owaislone.org/blog/webpack-plus-reactjs-and-django/ 的文档中所建议的那样)。尝试将publicPath 添加到webpack.config.js 为:

    output: {
      path: path.resolve('./djangoapp/reactapp/static/bundles/'),
      filename: "[name]-[hash].js",
      publicPath: "http://localhost:8080/<path to bundles>"
    },
    

    我不确定它是否会起作用,但如果有帮助,请告诉我!

    【讨论】:

    • 不起作用。 Webpack documentation 表示 publicPath 仅在您将捆绑包托管在不同域上时才有用。无论如何,我尝试用&lt;script type="text/javascript" src="/reactapp/static/bundles/main-fdf4c969af981093661f.js"&gt;&lt;/script&gt; 替换{% render_bundle 'name' %},但仍然没有成功。同样的错误。
    猜你喜欢
    • 2016-06-28
    • 2017-11-16
    • 2017-04-08
    • 2017-01-24
    • 1970-01-01
    • 2021-08-05
    • 2015-04-21
    • 2019-08-08
    • 1970-01-01
    相关资源
    最近更新 更多