1

I want to resize and compress images using sharp library in node.js. The code was taken from this article, but for some reason returns an error.

Error

PS D:\Code\Web\image-compressor-nodejs> node index.js
[Error: ./uploads/2022-08-10T18:35:49.251Z-2021-11-18_23.44.45.png.webp: unable to open for write
windows error: ���������� �� �������� �������.

]

Code

const express = require("express");
const multer = require("multer");
const sharp = require("sharp");
const fs = require("fs");

const app = express();
const storage = multer.memoryStorage();
const upload = multer({ storage });

app.use(express.static("./uploads"));

app.post("/", upload.single("picture"), async (req, res) => {
  try {
    fs.access("./uploads", (error) => {
      if (error) {
        fs.mkdirSync("./uploads");
      }
    });
    const { buffer, originalname } = req.file;
    const timestamp = new Date().toISOString();
    const ref = `${timestamp}-${originalname}.webp`;
    await sharp(buffer)
      .webp({ quality: 20 })
      .toFile("./uploads/" + ref);
    const link = `http://localhost:3000/${ref}`;
    return res.json({ link });
  } catch (error) {
    console.log(error);
  }
});

app.listen(3000);

Tobi
  • 11
  • 1

2 Answers2

1

The error message is rather inconclusive. The problem is that the timestamp consists of characters that are not valid on Windows systems but on a Linux-based system it should work fine.

Try the following instead:

const timestamp = new Date()
      .toISOString()
      .replace(/[^a-zA-Z0-9_\\-]/g, "-");
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
0

Try this:

const express = require("express");
const multer = require("multer");
const sharp = require("sharp");
const fs = require("fs");

const app = express();
const storage = multer.memoryStorage();
const upload = multer({ storage });

app.use(express.static("./uploads"));

app.post("/", upload.single("picture"), async (req, res) => {
  try {
    if (!fs.existsSync("./uploads")) { // check if directory exists. Do so synchronously.
      fs.mkdirSync("./uploads");
    }
    const { buffer, originalname } = req.file;
    const timestamp = new Date().toISOString();
    const ref = `${timestamp}-${originalname}.webp`;
    await sharp(buffer)
      .webp({ quality: 20 })
      .toFile("./uploads/" + ref);
    const link = `http://localhost:3000/${ref}`;
    return res.json({ link });
  } catch (error) {
    console.log(error);
  }
});

app.listen(3000);

You need to check to see if the ./uploads directory exists in a synchronous manner. fs.access in your original code is asynchronous.

Stephen Taylor
  • 798
  • 7
  • 19