๐Ÿ’ฅ Next.js์—์„œ styled-components ์„ค์ • ์‹œ ๋ฐœ์ƒํ•œ Babel ์—๋Ÿฌ ํ•ด๊ฒฐ๊ธฐ

Yunsungยท2025๋…„ 6์›” 12์ผ
post-thumbnail

โœ… ์ƒํ™ฉ

์˜ค๋Š˜ ํ”„๋กœ์ ํŠธ์—์„œ styled-components๋ฅผ Next.js 15 ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.
SSR๋„ ์ ์šฉํ•˜๊ณ  ์‹ถ์–ด์„œ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๊ณ  babel.config.js์— babel-plugin-styled-components๋ฅผ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

// babel.config.js
module.exports = {
  presets: ['next/babel'],
  plugins: [['styled-components', { ssr: true, displayName: true }]],
};

๊ทธ๋Ÿฐ๋ฐ...


โ— ๋ฌธ์ œ ๋ฐœ์ƒ

Error: Cannot require() ES Module babel.config.js in a cycle
ReferenceError: module is not defined
  • styled-components๋ฅผ ์ ์šฉํ•˜์ž๋งˆ์ž Next.js dev ์„œ๋ฒ„๊ฐ€ ๊นจ์ง€๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • Babel ์„ค์ •์„ ๋ชป ๋ถˆ๋Ÿฌ์˜จ๋‹ค๊ฑฐ๋‚˜, module์ด undefined๋ผ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐ˜๋ณต ๋ฐœ์ƒํ–ˆ๊ณ ,

  • .next/fallback-build-manifest.json๋„ ์—†๋‹ค๊ณ  ํ•˜๋ฉฐ ์ปดํŒŒ์ผ๋„ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ” ์›์ธ ๋ถ„์„

  • babel.config.js๋Š” CommonJS ํ˜•์‹์œผ๋กœ ์ž‘์„ฑ๋˜์–ด์•ผ ํ•˜์ง€๋งŒ,
    ๋‚ด package.json์— "type": "module"์ด ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— Next.js๋Š” ์ด ํŒŒ์ผ์„ ESM์œผ๋กœ ์ธ์‹ํ•˜๊ฒŒ ๋จ.

  • .cjs ํ™•์žฅ์ž๋ฅผ ์จ๋„ Next.js 15์—์„œ๋Š” babel.config.cjs๋ฅผ ์•„์˜ˆ ์ง€์›ํ•˜์ง€ ์•Š์Œ.

  • babel-plugin-styled-components ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์“ฐ๋ฉด ๋˜ ์—๋Ÿฌ ๋ฐœ์ƒ.

โ†’ ์ด๋ž˜์ €๋ž˜ ๊ผฌ์ด๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ” ์‹œ๋„ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  1. "type": "module" ์ œ๊ฑฐ

  2. babel.config.js์—์„œ CommonJS(module.exports) ๋ช…ํ™•ํžˆ ์ง€์ •

  3. .cjs๋กœ ํ™•์žฅ์ž ๋ฐ”๊ฟ”๋ณด๊ธฐ

  4. cross-env ์„ค์น˜ํ•ด์„œ NODE_OPTIONS ์ „๋‹ฌ

  5. babel-plugin-styled-components ์ง์ ‘ ์„ค์น˜

ํ•˜์ง€๋งŒ Next.js 15์—์„œ๋Š” Babel ๋กœ๋”๊ฐ€ .cjs, .mjs ํŒŒ์ผ ์ž์ฒด๋ฅผ ์•„์˜ˆ ๊ฑฐ๋ถ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์—
๊ฒฐ๊ตญ Babel ์„ค์ • ๋ฐฉ์‹์œผ๋กœ๋Š” styled-components๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์ ์šฉํ•˜๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.


โœ… ์ตœ์ข… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

Next.js 12 ์ด์ƒ์—์„œ๋Š” ์‚ฌ์‹ค styled-components๋ฅผ Babel ์—†์ด๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ์•Œ๊ฒŒ ๋์Šต๋‹ˆ๋‹ค.

๐Ÿ“ฆ ํ•ด๊ฒฐ ์ ˆ์ฐจ

  1. babel.config.js ์™„์ „ ์‚ญ์ œ

  2. next.config.js ์ƒˆ๋กœ ์ƒ์„ฑ ํ›„ ์•„๋ž˜ ์„ค์ • ์ถ”๊ฐ€

/** @type {import('next').NextConfig} */
const nextConfig = {
  compiler: {
    styledComponents: true,
  },
};

module.exports = nextConfig;
  1. package.json์—์„œ "type": "module" ์ œ๊ฑฐ

  2. eslint.config.js์—์„œ globals: globals.node๋กœ ์ˆ˜์ •ํ•ด ESLint ์˜ค๋ฅ˜ ํ•ด๊ฒฐ

  3. dev ์Šคํฌ๋ฆฝํŠธ๋Š” ๊ธฐ๋ณธ ์œ ์ง€ ("dev": "next dev")


๐Ÿš€ ๊ฒฐ๊ณผ

  • styled-components SSR ๋ฐ displayName ์ ์šฉ๋จ

  • hydration mismatch ํ•ด๊ฒฐ

  • Babel ๊ด€๋ จ ์—๋Ÿฌ ์‚ฌ๋ผ์ง

  • ESLint ๊ฒฝ๊ณ ๋„ ์ •๋ฆฌ๋จ


๐Ÿ’ก ๋ฐฐ์šด ์ 

  • Next.js 12 ์ด์ƒ์—์„œ๋Š” Babel ์—†์ด๋„ styled-components์˜ SSR ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋ฏ€๋กœ compiler.styledComponents: true ์„ค์ •๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•จ

  • "type": "module"์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ Babel ์„ค์ •์€ ๋” ๋ณต์žกํ•ด์ง€๋ฏ€๋กœ ๋ช…ํ™•ํ•œ ๊ธฐ์ค€์œผ๋กœ CommonJS / ESM ๊ตฌ๋ถ„ ํ•„์š”

  • Babel ์„ค์ •์€ ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ฉด ํ”ผํ•˜๋Š” ๊ฒƒ๋„ ์œ ์ง€๋ณด์ˆ˜์— ์ข‹์Œ

styled-components๋ฅผ Next.js์—์„œ ์“ธ ๋• ๋จผ์ € next.config.js์—์„œ compiler.styledComponents๋ฅผ ์ผœ๋Š” ๋ฐฉ์‹๋ถ€ํ„ฐ ์‹œ๋„ํ•ด๋ณด๋Š” ๊ฒŒ ํ›จ์”ฌ ์•ˆ์ „ํ•˜๋‹ค๋Š” ๊ฑธ ๋ฐฐ์› ๋‹ค!

profile
ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž๋กœ์„œ์˜ ๋„์ „์„ ํ•˜๋Š” ์ค‘์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ์‘์› ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค!!๐Ÿ˜

0๊ฐœ์˜ ๋Œ“๊ธ€