1. Standalone 이란?
- Next.js에서 웹 어플리케이션을 실행하는데 필요한 최소한의 코드만 추출하겠다는 의미로 사용
- 배포에 필요한 파일만 복사하는 폴더를 자동으로 생성할 수 있으며, 선택한 파일이 포함됨
// next.config.js
module.exports = {
output: 'standalone',
};
사실 별거 없다. 그냥 next.config.js 파일에 이렇게 output으로 standalone 만 추가하면 끝이다.
그러나 빌드 후 .next/standalone 이 생기지 않았다..
2. 문제 해결
빌드 캐쉬도 제거해보고,
.node_modules 제거 후 다시 인스톨해보고,
.next 도 제거후 다시 빌드해봐도 .. 생기지 않았다.
빌드 로그를 살펴봐도 standalone 에 대한 내용은 1도 없었다.
그러다 문득 next.config.cjs 확장자 때문인가 ?
싶어서 cjs -> js 로 바꿔주고 문법도 바꿔주었다.
// 수정전 next.config.cjs
/** @type {import('next').NextConfig} */
import withTMOriginal from 'next-transpile-modules';
const withTM = withTMOriginal();
const nextConfig = withTM({
output: 'standalone',
compress: true, // : Gzip 압축을 활성화하여 페이지 로딩 속도를 개선
webpack: (config) => {
config.module.rules = config.module.rules || [];
config.module.rules.push({
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions:{
plugins: ['tailwindcss', 'autoprefixer']
},
},
},
],
});
return config;
},
images: {
domains: ['isomorphic-furyroad.s3.amazonaws.com', 'randomuser.me'],
},
reactStrictMode: false,
experimental: {
optimizeCss: true, // CSS 최적화
serverActions: true,
},
swcMinify: true,
compiler: {
removeConsole: process.env.NODE_ENV === 'production', // 프로덕션모드 - 콘솔로그 미출력
},
});
module.exports = nextConfig;
// 수정후 next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
compress: true, // : Gzip 압축을 활성화하여 페이지 로딩 속도를 개선
images: {
domains: ['isomorphic-furyroad.s3.amazonaws.com', 'randomuser.me'],
},
reactStrictMode: false,
experimental: {
optimizeCss: true, // CSS 최적화
scrollRestoration: true,
serverActions: true,
},
swcMinify: true,
compiler: {
removeConsole: process.env.NODE_ENV === 'production', // 프로덕션모드 - 콘솔로그 미출력
},
};
module.exports = nextConfig;
그리고 .next를 삭제후 재빌드 했더니 ..
이렇게 .next/standalone 으로 잘 생기는것을 확인했고 도커에서 문제없이 실행되었다 :)
3. 이유는 ?
우선 .cjs 와 .js 의 차이를 알아보자. Next.js의 next.config.cjs와 next.config.js의 차이를 이해하려면 CommonJS 와 ESModules의 차이와 Next.js가 이 파일들을 처리하는 방식을 알아야 한다.
CommonJS(.cjs)와 ESModules(.js)의 차이
- CommonJS (.cjs): Node.js에서 기본적으로 사용되는 모듈 시스템으로, module.exports와 require()로 모듈을 가져오고 내보냅니다. CommonJS는 동기적으로 모듈을 로드하며, 이 방식은 파일 확장자가 .cjs일 때 강제됩니다.
- ESModules (.js): ECMAScript 모듈 시스템으로, 최신 JavaScript 표준입니다. export와 import 구문을 사용하여 모듈을 내보내고 가져옵니다. ESModules는 비동기적이며, 확장자가 .js일 경우 ESM 방식으로 실행될 수 있습니다. 하지만, Node.js 환경에서 ESModules를 사용하는 경우에는 package.json에 "type": "module" 설정을 추가해야 합니다.
왜 .cjs와 .js의 차이가 빌드에 영향을 주었을까?
Next.js는 ESModules와 CommonJS 모듈 시스템을 모두 지원한다.
하지만 .cjs 파일은 CommonJS 방식으로 동작하는 반면, .js 파일은 ESModules 방식으로 동작한다.
- Next.js의 기본 모듈 시스템 설정
- Next.js는 기본적으로 ESModules 방식을 동작하기 때문에, .js 파일을 ESM 방식으로 읽고 처리하는 것이 더 자연스럽다고 한다.
- 만약 next.config.cjs 파일이 있다면 Next.js는 CommonJS로 처리하는데, 이 과정에서 Next.js가 일부 설정이나 파일 경로 처리를 제대로 처리하지 못했을 가능성이 있다.
- 특히 output: 'standalone' 옵션이 Next.js 의 빌드 방식에 영향을 미치는데, CommonJS 방식으로 처리할 때 해당 옵션이 제대로 적용되지 않은 것이다 - .cjs 파일 내의 설정 인식 문제
- Next.js가 ESModules와 CommonJS의 설정을 다르게 처리하는 경우가 종종 있다
- .js 파일로 전환하면서 Next.js가 설정을 올바르게 읽고 standalone 출력을 생성할 수 있었던 것
- ESModules 방식이 Next.js의 설정 및 빌드 프로세스에 더 잘 맞았다고 볼 수 있다 - 빌드 시스템이나 패키지 문제
- 일부 패키지나 설정이 ESModules로 작성된 환경에서 더 잘 동작할 수 있다
- 특히 Next.js의 최신 기능이나 실험적 옵션(예: experimental.optimizeCss, output: 'standalone')은 ESModules 환경에서 최적화된 방식으로 작동할 수 있다
라고 지피티 교수님은 말씀하셨다 .
지금 보니 next.config.cjs 설정파일의 문법이 좀 잘못된것 같기도 .. ;;
처음에 모노레포 때문에 .cjs 로 기본설정을 했었던 건데 그게 발목을 잡을줄 몰랐다
아무튼 안전하게 .js를 쓰도록 하자!
'개발 지식' 카테고리의 다른 글
AWS Amplify 슬랙 연동하기 (0) | 2024.11.18 |
---|---|
스토리북 사용기 (1) | 2024.07.18 |
AWS amplify 배포해보기 (0) | 2024.07.04 |
[FE] 웹뷰(WebView) 란? (1) | 2024.06.17 |
[FE] 쿠키, 세션, 로컬 스토리지와 세션 스토리지 (0) | 2024.02.07 |