이번 포스팅에서는 NestJs에서 multer
을 사용하여 이미지 업로드를 해보고자 한다.
$ npm i -g @nestjs/cli
$ nest new file-upload
$ nest g controller file
$ nest g service file
$ nest g module file
$ npm i -D @types/multer
// 업로드 가능한 확장자 설정
export const imageFileFilter = (req, file, callback) => {
if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) {
return callback(new Error("Only image files are allowed!"), false);
}
callback(null, true);
};
// 파일명 중복을 피하기 위해 파일명 수정
export const editFileName = (req, file, callback) => {
const name = file.originalname.split(".")[0];
const fileExtName = file.originalname.slice(((file.originalname.lastIndexOf(".") - 1) + 2));
const time = Date.now();
const randomName = `${name}-${time}`
callback(null, `${randomName}.${fileExtName}`);
};
💡 파일 업로드할 때 필요한 설정이다.
참고로 파일명을 재설정 하는 작업에서Timestemp
로 random 값을 만들었는데 다양한 방법으로 설정해도 상관없다.
import { Module } from "@nestjs/common";
import { MulterModule } from "@nestjs/platform-express";
import { FileController } from "./file.controller";
import { FileService } from "./file.service";
@Module({
imports: [
MulterModule.register({
dest: "./upload"
})
],
controllers: [FileController],
providers: [FileService]
})
export class FileModule {
}
💡 MulterModule.register() improt 하고 업로드할 경로 설정하기
import {
Controller, Get, Param,
Post, Res,
UploadedFiles,
UseInterceptors
} from "@nestjs/common";
import { FileService } from "./file.service";
import { FilesInterceptor } from "@nestjs/platform-express";
import { diskStorage } from "multer";
import { editFileName, imageFileFilter } from "../lib/multerOptions";
// @ts-ignore
@Controller("file")
export class FileController {
constructor(private readonly fileService: FileService) {
}
@Post("/")
// @ts-ignore
@UseInterceptors(FilesInterceptor("files", 5, {
storage: diskStorage({
destination: './upload',
filename: editFileName
}),
fileFilter: imageFileFilter
}))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
return this.fileService.uploadFiles(files);
}
}
💡
files
필드명으로 5개까지 업로드 할 수 있도록 설정했다.
filename
과fileFilter
은 방금 만든 src/lib/multerOptions.ts 에서 import 했다.
import { Injectable } from "@nestjs/common";
@Injectable()
export class FileService {
public uploadFiles(files: Array<Express.Multer.File>) {
const result = [];
files.forEach((file) => {
const res = {
originalname: file.originalname,
filename: file.filename
};
result.push(res);
});
return result;
}
}
import { NestFactory } from "@nestjs/core";
import { NestExpressApplication } from "@nestjs/platform-express";
import { join } from "path";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(
AppModule
);
app.useStaticAssets(join(__dirname, "..", "upload"));
await app.listen(9001).then(() => {
console.log(`http://localhost:9001`);
});
}
bootstrap();
💡 정적 파일 경로 설정해주기
// 기존 코드에 추가하기
@Get("/:imgpath")
seeUploadedFile(@Param("imgpath") image, @Res() res) {
return res.sendFile(image, { root: "./upload" });
}