next.config.js webpack 설정 커스터마이징
Next.js에서 webpack 설정을 커스터마이징하여 모듈 해석과 번들링을 제어하는 방법을 알아봅니다.
next.config.js webpack 설정 커스터마이징
Introduction
Next.js는 내부적으로 webpack을 사용하여 모듈을 번들링합니다. 때로는 기본 설정으로는 충분하지 않은 경우가 있으며, 이럴 때 webpack 설정을 커스터마이징해야 합니다. 이 글에서는 webpack 설정을 안전하게 변경하는 방법과 일반적인 사용 사례를 다룹니다.
Environment
# 프로젝트 구조
my-app/
├── next.config.js
├── webpack.config.js
├── lib/
│ └── custom-loaders/
│ └── yaml-loader.js
├── types/
│ └── global.d.ts
└── package.json
# 기술 스택
Next.js: 14.2.5
webpack: 5.90.0
Node.js: 18.17.0Problem
기본 webpack 설정으로는 특정 파일 형식이나 모듈 해석이 안 될 때가 있습니다:
// ❌ 경로 별칭 미설정 시 import 에러
import { helper } from '@/utils/helper'; // Cannot resolve '@/utils/helper'// ❌ 커스텀 로더 미등록 시 파일 파싱 에러
import data from './config.yaml'; // Module parse failedAnalysis
Next.js의 webpack 설정 커스터마이징은:
next.config.js의webpack함수를 통해 가능- 기존 설정과 병합 가능
- 개발/프로덕션 환경별 차별 적용 가능
- 빌드 성능에 직접적 영향
Solution
1. 기본 webpack 설정 구조
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { isServer, dev }) => {
// config: 기존 webpack 설정
// isServer: 서버 사이드 번들 여부
// dev: 개발 모드 여부
console.log('Webpack version:', config.plugins.length);
console.log('Is server:', isServer);
console.log('Is dev:', dev);
return config;
},
};
module.exports = nextConfig;2. 경로 별칭 설정
// next.config.js
const path = require('path');
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
// 기존 alias 설정
config.resolve.alias = {
...config.resolve.alias,
'@': path.join(__dirname),
'@components': path.join(__dirname, 'components'),
'@utils': path.join(__dirname, 'utils'),
'@lib': path.join(__dirname, 'lib'),
'@hooks': path.join(__dirname, 'hooks'),
};
return config;
},
};
module.exports = nextConfig;3. 커스텀 로더 설정
// lib/custom-loaders/yaml-loader.js
module.exports = function yamlLoader(source) {
const yaml = require('js-yaml');
const json = yaml.load(source);
return `module.exports = ${JSON.stringify(json)};`;
};// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
// YAML 로더 추가
config.module.rules.push({
test: /\.yaml$/,
use: [
{
loader: path.join(__dirname, 'lib/custom-loaders/yaml-loader.js'),
},
],
});
// GraphQL 로더 추가
config.module.rules.push({
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
use: [
{
loader: 'graphql-tag/loader',
},
],
});
return config;
},
};
module.exports = nextConfig;4. 번들 분석기 설정
// next.config.js
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { isServer }) => {
// 개발 환경에서만 번들 분석기 활성화
if (!isServer && process.env.ANALYZE === 'true') {
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: '../bundle-analyzer-report.html',
openAnalyzer: false,
})
);
}
return config;
},
};
module.exports = nextConfig;# 번들 분석기 실행
ANALYZE=true npm run build5. 소스 맵 제어
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { isServer, dev }) => {
// 프로덕션 환경에서 소스 맵 제거
if (!dev) {
config.devtool = false;
}
// 개발 환경에서 빠른 소스 맵 사용
if (dev) {
config.devtool = 'eval-cheap-module-source-map';
}
return config;
},
};
module.exports = nextConfig;6. 환경별 설정 분리
// next.config.js
const baseConfig = {
webpack: (config, { isServer, dev }) => {
return config;
},
};
const developmentConfig = {
webpack: (config) => {
// 개발 전용 설정
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
};
return config;
},
};
const productionConfig = {
webpack: (config) => {
// 프로덕션 전용 설정
config.optimization = {
...config.optimization,
minimize: true,
splitChunks: {
chunks: 'all',
maxSize: 244000,
},
};
return config;
},
};
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, options) => {
// 기본 설정 적용
let finalConfig = baseConfig.webpack(config, options);
// 환경별 설정 적용
if (options.dev) {
finalConfig = developmentConfig.webpack(finalConfig, options);
} else {
finalConfig = productionConfig.webpack(finalConfig, options);
}
return finalConfig;
},
};
module.exports = nextConfig;7. 타입 안전한 설정
// next.config.ts
import type { NextConfig } from 'next';
import type { Configuration } from 'webpack';
import path from 'path';
const nextConfig: NextConfig = {
webpack: (config: Configuration, options) => {
const { isServer, dev } = options;
// 타입 안전한 설정
if (!config.resolve) {
config.resolve = {};
}
config.resolve.alias = {
...config.resolve.alias,
'@': path.join(__dirname),
};
return config;
},
};
export default nextConfig;Lessons Learned
- 설정 변경 최소화: 필요한 경우에만 webpack 설정 변경
- 환경 분리: 개발/프로덕션 환경에 따른 차별적 설정
- 성능 모니터링: 설정 변경 후 빌드 시간 및 번들 크기 확인
- Next.js 업데이트 고려: 설정 변경이 Next.js 업데이트 시 호환성 유지하는지 확인
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.