next.config.js 여러 플러그인 연결하기

다음 플러그인 사용하기
https://www.npmjs.com/package/next-compose-plugins

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const withTM = require("next-transpile-modules")([
"@fullcalendar/common",
"@babel/preset-react",
"@fullcalendar/common",
"@fullcalendar/daygrid",
"@fullcalendar/interaction",
"@fullcalendar/react",
"@fullcalendar/timegrid",
]);

const withPlugins = require("next-compose-plugins");

const nextConfig = {
async rewrites() {
return [
{
source: "/:path*",
destination: `https://dev.aistudios.com/:path*`,
},
];
},
};

module.exports = withPlugins([withTM({})], nextConfig);
// withPlugins([plugins],nextConfig);

nextjs css-npm 에러

next.js의 경우 node_modules내부의 패키지에서 전역으로 css를 import하면 에러를 발생시킨다.
구글링을 통해 해결하였다.

1
./node_modules/@fullcalendar/common/main.css Global CSS cannot be imported from within node_modules. Read more: https://err.sh/next.js/css-npm Location: node_modules/@fullcalendar/common/main.js

해결방법

1
npm i next-transpile-modules @babel/preset-react

next-transpile-modules 는 node_modules 내부의 패키지에 css/scss파일이 포함 될 수 있도록 transpile 하는 플러그인이다.

이후 next.config.js 파일을 다음과같이 작성해주었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/** @type {import('next').NextConfig} */
const withTM = require("next-transpile-modules")([
"@fullcalendar/common",
"@babel/preset-react",
"@fullcalendar/common",
"@fullcalendar/daygrid",
"@fullcalendar/interaction",
"@fullcalendar/react",
"@fullcalendar/timegrid",
]);

module.exports = withTM({
// your custom config goes here
});

개선방안

공부할 예정인 next-compose-plugins를 통해 간편하게 여러 플러그인을 import 할 수 있다.

ref

next css-npm
How To Use Fullcalendar With Next.js (v10 or higher)

nextjs + mongo 연동하기

nextjs+ mongoDB 연동을 해보았다.

.env 설정

루트 디렉토리에 .env 파일을 만들어준다.
.gitignore가 존재할 경우 .env도 추가해주어야 한다.

.env

1
MONGODB_URL=mongodb+srv://<사용자명>:<사용자 비밀번호>@cluster0.gvztc.mongodb.net/<DB이름>?retryWrites=true&w=majority

mongooose 설치

nodejs와 연동하기 위해 mongoose 모듈을 설치해준다.

1
npm i mongoose

db 연결하기

캐시를 통해 핫리로드가 가능하게 하고 데이터베이스를 불러온다.

공식문서에서 가져왔다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import mongoose from "mongoose";

const MONGODB_URI = process.env.MONGODB_URI;

if (!MONGODB_URI) {
throw new Error(
"Please define the MONGODB_URI environment variable inside .env.local"
);
}

/**
* Global is used here to maintain a cached connection across hot reloads
* in development. This prevents connections growing exponentially
* during API Route usage.
*/
let cached = global.mongoose;

if (!cached) {
cached = global.mongoose = { conn: null, promise: null };
}

async function dbConnect() {
if (cached.conn) {
return cached.conn;
}

if (!cached.promise) {
const opts = {
bufferCommands: false,
};

cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
return mongoose;
});
}
cached.conn = await cached.promise;
return cached.conn;
}

export default dbConnect;

스키마 정의하고 모델 반환하기

스키마를 정의해주고 모델을 반환한다.
db에 해당 스키마가 존재하지 않을 경우 생성하고 모델을 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import mongoose from "mongoose";

const ProductSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
maxlength: 60,
},
desc: {
type: String,
required: true,
maxlength: 200,
},
img: {
type: String,
required: true,
},
prices: {
type: [Number],
required: true,
},
extraOptions: {
type: [
{
text: { type: String, required: true },
price: { type: Number, required: true },
},
],
},
},
{ timestamps: true }
);

export default mongoose.models.Product ||
mongoose.model("Product", ProductSchema);

사용하기

next.js에서는 api를 만드는 기능을 제공한다.
express와 비슷하다. RESTful한 API도 생성이 가능하다.

1
2
3
4
5
/pages/api/product/index.js 주소/api/product로 접근 가능

/pages/api/product/[id].js 주소/api/product/asdf로 {id:asdf}에 접근 가능

/pages/api/product/[...data].js 주소/api/user/의 하위 경로들로 전부 접근 가능

아래 코드는 주소/api/product를 통해 접근 가능하다.

/pages/api/products/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import dbConnect from "../../../util/mongo";
import Product from "../../../models/Product";
export default async function handler(req, res) {
const { method } = req;

dbConnect();

if (method === "GET") {
try {
const products = await Product.find();
res.status(200).json(products);
} catch (err) {
res.status(500, json(err));
}
}

if (method === "POST") {
try {
const product = await Product.create(req.body);
res.status(201).json(product);
} catch (err) {
res.status(500).json(err);
}
}
}