Cannot use import statement outside a module
구글 서치 콘솔에 도메인을 등록하고 sitemap을 제출하기위해 next-sitemap 라이브러리를 사용했다.
업로드한 포스트 url을 전부 추가 하고 싶어서 mdx 파일 리스트를 가져오는 식으로 next-sitemap.config.js를 작성했는데 테스트겸 build를 실행하자 에러가 발생했다.
문제가 된 부분은 아래와 같이 작성한 관련 라이브러리 import문.
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
app라우터 방식에서 next.config.mjs를 작성할때 별 생각없이 ES모듈 형식으로 작성해왔기 때문에 next-sitemap.config.js도 당연히 그럴 줄 알았는데 아니었다.
찾아보니 next-sitemap은 CommonJS모듈 형식을 사용해야 한다고 한다. 그 이유는,
- next-sitemap은 Node.js 환경에서 빌드 시점에 실행되는 도구이며, 기본적으로 CommonJS를 사용하도록 설계되어 있다.
- js 확장자는 기본적으로 CommonJS 모듈로 간주된다.
- next.config.mjs 같은 경우는 Node.js 모듈 시스템에서 mjs 확장자가 ES모듈 형식을 사용하도록 지정되기 때문에 ES모듈 형식을 사용해야한다.
- Node.js와 빌드 도구들이 점차 ES모듈을 지원하고 있지만, 대부분의 도구들은 완전히 ES모듈로 전환되지 않았다. 따라서 여전히 js 확장자를 사용하는 방식이 널리 사용되고 있다.
프로젝트 파일 형식을 간단하게 구분해보자면 아래와 같다.
프로젝트/
├── app/ # ESM 사용 (import/export)
├── lib/ # ESM 사용 (import/export)
├── next.config.mjs # ESM 가능 (Next.js는 둘 다 지원)
└── next-sitemap.config.js # CommonJS 사용 (require/module.exports)
이렇게 변경해주니 정상적으로 build에 성공했다.
const fs = require('fs');
const path = require('path');
const matter = require('gray-matter');
앞서 말했듯이 그 동안 별 다른 의심없이 사용해왔는데 이번 에러를 만난 덕분에 왜 이런 방식으로 작성을 하는가? 에 대해서 평소 생각해보지 않고 "다들 이렇게 하니까~" 라는 안일한 생각으로 코딩을 해왔던 스스로를 반성하게됐다.



