【Node.js・Express】multerではなくexpress-fileuploadでファイルをアップロードする方法

# 環境構築

1.以下を実行（もしくは`express-file-upload`フォルダを作成してその中に移動）

```terminal
mkdir express-file-upload
cd express-file-upload
```

2.`package.json`以下を作成して以下をコピペで記述

```json:package.json
{
  "name": "express-file-upload",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "type": "module",
  "scripts": {
    "start": "nodemon server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ejs": "^3.1.8",
    "express": "^4.18.2",
    "express-fileupload": "^1.4.0",
    "nodemon": "^2.0.20"
  }
}

```

3.`express-file-upload`直下で`npm i`を実行して`package.json`を元にモジュールをインストールする

```
npm i
```

# フォルダ構成

- `server.js`
- `views/pages/form.ejs`

の二つを作成

```
.
├── package-lock.json
├── package.json
├── server.js
└── views
    └── pages
        └── form.ejs
```

# ソースコード

## `form.ejs`

```html:form.ejs
<!DOCTYPE html>
<html lang="js">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Form Image Upload</title>
</head>
<body>
    <h1>画像アップロード</h1>
    <form action="/upload" method="post" encType="multipart/form-data">
        <p><input type="text" name="image-name" id=""></p>
        <p><input type="file" name="image-file" id="" accept="image/*" multiple></p>
        <input type="submit" value="送信">
    </form>
</body>
</html>
```

## `server.ejs`

```js:server.js
"use strict";

import Express from "express";
import fileUpload from "express-fileupload";
import path from "path";
import { fileURLToPath } from "url";

const app = Express();
const port = 5050;
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

app.listen(port);
console.log(`http://localhost:${port}`);

app.set("view engine", "ejs");

// body-parserの設定
app.use(Express.json());
app.use(
  Express.urlencoded({
    extended: true,
  })
);
// fileUploadの設定
app.use(fileUpload());

app.get("/", (req, res) => {
  res.status(200).render("pages/form");
});


app.post("/upload", async (req, res) => {
  try {
    /**
     * 画像アップロード
     * @param {*} err
     * @returns
     */
    const imageUpload = function (err) {
      if (err) return res.status(500).send(err);

      console.log("File upload!!");
    };

    const file = req.files["image-file"];
    const name = req.body["image-name"];

    let savePath = [];

    if (file.length) {
      for await (const i of file) {
        const path = __dirname + "/" + new Date().getTime() + i.name;
        savePath.push(path); // 配列にpush
        i.mv(path, imageUpload);
      }
    } else {
      const path = __dirname + "/" + new Date().getTime() + file.name;
      savePath.push(path); // 配列にpush
      file.mv(path, imageUpload);
    }

    console.log(savePath); // これを文字列に変換してDBなどに保存
    res.status(200)
  } catch (error) {
    // console.log(error);
    res.status(500)
  } finally {
    res.redirect("/");
  }
});

// 404の時
app.use((req, res, next) => {
  // res.status(404).send("<h1>ページが見つかりません</h1>");
  console.log('not found');
  res.status(404).redirect('/')
});

```

`app.use(fileUpload());`と`app.post('/upload', ...`からが大事

# 実行

`npm run start`を実行

```
npm run start
```

- `localhost:5050`からフォーム画面を表示して画像のアップロードができる
- 画像はフォルダではなく`express-file-upload`直下に保存される
- `multer`を使いたくなかったので`multer`を使わないで済む方法を探してた