Невозможно просмотреть загруженное изображение (на внутреннем сервере) с помощью Webpack с url-loader / file-loader в React - PullRequest
0 голосов
/ 25 марта 2020

Я работаю над FileUploader (пока что изображения), который позволит пользователю загружать несколько файлов на внутренний сервер за один go.

У меня есть следующие настройки

  1. Webpack настроен с помощью url-загрузчика, поддерживающего все виды изображений.
  2. У меня есть клиент React, работающий на порте 9002 внутри отдельного каталога, называемого клиентом. У этого есть компонент, названный "UploadDocumentsContainer". Этот компонент позволит пользователю выбрать несколько входных файлов для загрузки. Компонент делает ax ios вызов бэкэнд-сервера в конечной точке "/uploads".
  3. Бэкэнд-сервер узла работает на один каталог выше, чем каталог клиента, работающий на порте 9001. Он имеет конечную точку загрузки, настроенную на обслуживать загруженные изображения. Сервер перемещает изображения в / client / public / uploads и отправляет ответ клиенту с fileName и filePath изображения.
  4. В клиенте React также есть отдельный компонент с именем ProgressFileUpload, который запускается после начала загрузки от 0 до 100% в зависимости от статуса загрузки.

Проблема Пока в следующем.

  1. Изображение успешно загружено на сервер, и мы получаем ответ 200 назад с сервера с fileName и filePath изображения.
  2. Но во время рендеринга тех же загруженных изображений с использованием компонента DisplayFile приложение вылетает со следующей ошибкой.

Я пытался получить это работает с последних 3 дней. Я прошел много постов github и stackoverflow, но не нашел решения для того же самого. Я буду очень признателен, если смогу получить какой-то вклад / отзыв / решение по этому же вопросу

Думаю, что-то не так с моим Webpack.configs (publicPath или url-загрузчиком) или filePath изображений не указывает в правильном направлении после создания пакета.

Вышеуказанная ошибка произошла в компоненте: в DisplayFile (создан UploadDocumentsContainer) в форме (созданной UploadDocumentsContainer) в div (созданной UploadDocumentsContainer) в div (созданной UploadDocumentsContainer) в div (созданной UploadDocumentsContainer) в UploadDocumentsContainer

Error: Cannot find module './wallpaper-1680x1050.jpg' bundle.js line 96 > eval:14:11
TypeError: _context.t0.response is undefined

Ссылка песочницы выдает ошибку «Запрос не выполнен с кодом состояния 422»

GITHUB LINK: - https://github.com/aryan21710/FileUploader.git

Webpack.config. js: -

const path = require("path");
const webpack = require("webpack");
const dotenv=require("dotenv");


module.exports = () => {
     // call dotenv and it will return an Object with a parsed key 


  return {
    mode: "development",
    // babel-polyfill allows us to use all the latest es7 javascript features like Array.includes , Array.from and so on
    // 
    entry: ["babel-polyfill", path.join(__dirname, "client/src/app.js")],
    devServer: {
      proxy: {
        "/client/public/uploads/": "http://localhost:9001"
      },
      // index.html will be inside build and not dist after installing htmlWebpackPlugin.
      contentBase: path.join(__dirname, "client", "public", "build"),
      hot: false,
      inline: true,
      historyApiFallback: true,
      watchContentBase: true,
      port: 9002,
      watchOptions: {
        ignored: [
          path.resolve(__dirname, "fileUploadServer/server.js"),
          path.resolve(__dirname, "node_modules/")
        ]
      }
    },
    output: {
      path: path.join(__dirname, "client", "public", "build"),
      // Will generate a new bundle.js with name "main.somerandomhash.bundle.js" every time when app changes.
      filename: "bundle.js",
    },
    module: {
      rules: [
        {
          loader: "babel-loader",
          test: /\.js$/,
          exclude: /node_modules/
        },
        {
          test: /\.s?css$/,
          use: ["style-loader", "css-loader", "sass-loader"]
        },
        {
          test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg|jpg)$/,
          loader: "url-loader",

        }
      ]
    },
    devtool: "cheap-module-eval-source-map"
  };
};

UploadDocumentsContainer. js: -

import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import axios from "axios";
import ProgressFileUpload from "./ProgressFileUpload";

const UploadDocumentsContainer = () => {
  const [selectedFile, setSelectedFile] = useState("Choose File");
  const [displayFile, setDisplayFile] = useState([]);
  const [file, setFile] = useState([]);
  const [uploadPercentage, setUploadPercentage] = useState(0);





  const onChangeFile = event => {
    console.log("event.target.files", event.target.files[0]);

    for (let i = 0; i < event.target.files.length; i++) {
      let _ = event.target.files[i];
      setFile(file => [...file, _]);
    }
    event.target.files.length > 1
      ? setSelectedFile(`${event.target.files.length} Files`)
      : setSelectedFile(event.target.files[0].name);
  };

  const onUpload = async e => {
    e.preventDefault();
    console.log("file", file);
    console.log("selectedFile", selectedFile);
    const formData = new FormData();
    file.forEach(_ => {
      console.log("_", _);
      formData.append("file", _);
    });
    console.log("FORMDATA INSIDE UploadDocumentsContainer", formData);

    try {
      const response = await axios.post(
        "http://localhost:9001/client/public/uploads",
        formData,
        {
          headers: {
            "Access-Control-Allow-Origin": "*",
            "Content-type": "multipart/form-data"
          },
          onUploadProgress: progressEvent => {
            setUploadPercentage(
              parseInt(
                Math.round((progressEvent.loaded * 100) / progressEvent.total)
              )
            );

            // Clear percentage
            setTimeout(() => setUploadPercentage(0), 10000);
          }
        }
      );

      let { fileName, filePath } = response.data;
      console.log("response.data", response.data);
      fileName = fileName.split(",");
      filePath = filePath.split(",");
      console.log("fileName", fileName);
      console.log("filePath", filePath);

      setDisplayFile(displayFile => [...displayFile, ...fileName]);
      console.log(
        "displayFile from the server",
        displayFile,
        ":",
        displayFile.length
      );
      console.log("response back from server:-", fileName, " AND ", filePath);

      // const importAll = r => {
      //   return r.keys().map(r);
      // };

      // setImages(
      //   importAll(
      //     require.context(
      //       "./../../../../../../../public/uploads/",
      //       false,
      //       /\.(png|jpeg|svg|jpg)$/
      //     )
      //   )
      // );
    } catch (error) {
      if (error.response.status == 500) {
        console.log("There was a problem with the server");
      } else {
        console.log(error.response.data.msg);
      }
    }
  };

  const DisplayFile = () => {
    console.log("displayFile", displayFile);
    console.log("uploadPercentage", uploadPercentage);
    return (
      <div className="displayFileContainer">
        {displayFile.length > 0
          ? displayFile.map((_, idx) => {
              const myimg = require(`./../../../../../../../public/uploads/${_}`)
                .default;
              console.log("myimg", myimg);
              return (
                <div className="fileDimension" key={idx}>
                  <img src={myimg} />
                </div>
              );
            })
          : null}
      </div>
    );
  };

  return (
    <div className="formOuterWrapper">
      <div className="formInnerWrapper">
        <div className="fileUploadContainer">
          <form className="fileUploadForm " name="myForm" onSubmit={onUpload}>
            <div className="custom-file mb-5">
              <input
                type="file"
                multiple
                className="custom-file-input"
                id="customFile"
                onChange={onChangeFile}
              />
              <label className="custom-file-label" htmlFor="customFile">
                {selectedFile}
              </label>
            </div>

            <div className="progressbar">
              <ProgressFileUpload percentage={uploadPercentage} />
            </div>

            <input
              type="submit"
              value="Upload"
              className="btn btn-primary btn-block mt-5"
            />
            <DisplayFile />
          </form>
        </div>
      </div>

    </div>
  );
};

export default UploadDocumentsContainer;

Внутренний сервер FILE (fileUploadServer): -

const express = require("express");
const fileUpload = require("express-fileupload");
const morgan = require("morgan");

const app = express();
const path = require("path");
const cors = require("cors");
const port = 9001;
const publicPath = path.join(__dirname, "..", "client", "public");
// eslint-disable-next-line no-console
console.log("publicpath", publicPath);
app.use(express.static(publicPath));
app.use(cors());
app.use(fileUpload());
app.use(morgan("dev"));

app.post("/client/public/uploads", (req, res) => {
  if (req.files === null) {
    return res.status(400).json({ msg: "NO FILE UPLOADED" });
  }



  const filename = [],
    filepath = [];
  if (Object.keys(req.files.file).includes("name")) {
    const file = req.files.file;
    filename.push(file.name);
    filepath.push(`${publicPath}/uploads/${file.name}`);
    file.mv(`${publicPath}/uploads/${file.name}`, err => {
      if (err) {
        console.log("err while moving the file to different directory", err);
        return res.status(500).send(err);
      }
    });
  } else {
    for (let i in req.files.file) {
      const file = req.files.file[i];
      filename.push(file.name);
      filepath.push(`${publicPath}/uploads/${file.name}`);
      console.log("INSIDE UPLOADS", file.name);
      file.mv(`${publicPath}/uploads/${file.name}`, err => {
        if (err) {
          console.log("err while moving the file to different directory", err);
          return res.status(500).send(err);
        }
      });
    }
  }

  console.log(filename, "::::", filepath);

  res.json({ fileName: `${[filename]}`, filePath: `${filepath}` });
});
app.listen(port, () => {
  // eslint-disable-next-line no-console
  console.log(`SERVER IS LISTENING ON PORT ${port}`);
});

Структура каталогов: -

enter image description here

...