通过静态文件(混合模型)在 django teamplates 中使用 React JS 组件 - 怎么了? (新手JS/React问题)

using React JS components in django teamplates though static files (hybrid model) - what's wrong? (newbie JS/React question)

我是 JS/React/npm/webpack 的新手,也是 Django 的新手。我正在尝试为我现有的 Django Web 应用程序构建搜索体验(即前端),并且我计划为此使用 elastic/search-ui 组件。 我做了一些研究 () and I am following the hybrid model guide (https://www.saaspegasus.com/guides/modern-javascript-for-django-developers/integrating-javascript-pipeline/),其中 Django 模板中使用了静态 JS 文件。

我已经到了可以在 Django 模板中显示 JS 脚本的一些文本的地步,现在我试图显示导入的 JS 组件,但我卡住了。这是我的代码:

package.json:

...
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --mode development"
  },
...
  "devDependencies": {
    "@elastic/search-ui": "^1.5.1",
    "babel": "^6.23.0",
    "babel-loader": "^8.1.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "^4.0.3",
    "webpack": "^5.26.3",
    "webpack-cli": "^4.5.0"
  }

webpack.config.js:

const path = require('path');

module.exports = {
  entry: './ui-react-src/index.js',  // path to our input file
  output: {
    filename: 'index-bundle.js',  // output bundle file name
    path: path.resolve(__dirname, './reviewer/static/ui-react-build'),  // path to our Django static directory
  },
};

django html 模板我想加载 React 组件到:

{% extends "base_generic.html" %}

{% block content %}

    Test React component

    <hr>

    {% load static %}
    
    <div id ='root'></div>
    <script src="{% static 'ui-react-build/index-bundle.js' %}"> </script>

{% endblock %}

这些是我用于构建的源 JS 文件(npm run dev):

ui-react-src/App.js:

import {
  SearchBox,
} from "@elastic/react-search-ui";


export default function App() {
    return (
        <div className="App">
            <SearchBox />
        </div>
    );
}

ui-react-src/index.js:

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

最后一个文件似乎给我错误(当我运行npm run dev):

ERROR in ./ui-react-src/index.js 17:16
Module parse failed: Unexpected token (17:16)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| 
| const rootElement = document.getElementById("root");
> ReactDOM.render(<App />, rootElement);

我在这里遗漏了什么/做错了什么?

解决方案:

将以下内容添加到 webpack.config.hs

  module: {
    rules: [
      {
        test: /\.(mjs|js|jsx)$/,
        exclude: /node_modules/,
        loader: 'babel-loader',

        options: {
          presets: [
            '@babel/preset-react',
            {
              plugins: [
                '@babel/plugin-syntax-jsx'
              ]
            }
          ]
        },


      }
    ],
  }

并使用 npm 安装上面提到的@babel 库解决了这个问题。

我相当有信心这是因为它无法解析您的 js 文件中的 <App />(因为它是 jsx 语法)所以您的 webpack.config.js 需要稍微调整一下。

尝试更新您的 webpack 配置,使其看起来像这样。

const path = require('path');

module.exports = {
  entry: './ui-react-src/index.js',  // path to our input file
  output: {
    filename: 'index-bundle.js',  // output bundle file name
    path: path.resolve(__dirname, './reviewer/static/ui-react-build'),  // path to our Django static directory
  },
  module: {
    rules: [
      {
        include: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
};

可能需要进一步调整,具体取决于项目的文件结构。