๐Ÿš€ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ๋ฅผ ์ฃฝ์ด๋Š” ๊ฑธ ๋ฉˆ์ถฐ๋ผ

๋ฐœํ–‰: (2025๋…„ 12์›” 26์ผ ์˜ค์ „ 10:11 GMT+9)
6 min read
์›๋ฌธ: Dev.to

Source: Dev.to

Cover Image Description: A split screen showing a heavy, tangled bundle on the left and a clean, direct import structure on the right.

์šฐ๋ฆฌ๋Š” ๋ชจ๋‘ Barrel Files(index.ts ํŒŒ์ผ, ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ๋ชจ๋“  ๊ฒƒ์„ ๋‚ด๋ณด๋‚ด๋Š” ํŒŒ์ผ)๋ฅผ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ๋“ค์€ ์šฐ๋ฆฌ์˜ import ๋ฌธ์„ ๊น”๋”ํ•˜๊ณ  ์ •๋ˆ๋œ ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค:

// ๐Ÿ˜ Looks clean...
import { Button, Header, Footer } from './components';

ํ•˜์ง€๋งŒ ๊ทธ ํ•œ ์ค„์˜ ์ฝ”๋“œ๊ฐ€ CI/CD ์†๋„๋ฅผ ๋Šฆ์ถ”๊ณ , ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ๋ถ€ํ’€๋ฆฌ๋ฉฐ, ์•…๋ชฝ ๊ฐ™์€ โ€œModule is undefinedโ€ ์ˆœํ™˜ ์˜์กด์„ฑ ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ค๊ณ  ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด๊ฒฐํ•ด ์ฃผ๋Š” ๋„๊ตฌ๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ , ์˜ค๋Š˜์€ ์—ฌ๋Ÿฌ๋ถ„๊ณผ ๊ณต์œ ํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.


๋ฐฐ๋Ÿด ํŒŒ์ผ์˜ ์ˆจ๊ฒจ์ง„ ๋น„์šฉ ๐Ÿ“‰

When you import a single named export from a barrel file, many bundlers and test runners (like Jest) end up loading every other file exported in that barrel to resolve the module.

  • ๋А๋ฆฐ ํ…Œ์ŠคํŠธ โ€“ Jest์—์„œ Button์„ ๊ฐ€์ ธ์˜ค๋ฉด Table, Chart, HeavyLibrary๊นŒ์ง€๋„ ๊ฐ™์€ index.ts๋ฅผ ๊ณต์œ ํ•œ๋‹ค๋Š” ์ด์œ ๋งŒ์œผ๋กœ ์‹ค์ˆ˜๋กœ ๋กœ๋“œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํŠธ๋ฆฌโ€‘์‰์ดํ‚น ์‹คํŒจ โ€“ Webpack๊ณผ Rollup์ด ์ ์  ๊ฐœ์„ ๋˜๊ณ  ์žˆ์ง€๋งŒ, ๊นŠ๊ฒŒ ์ค‘์ฒฉ๋œ ๋ฐฐ๋Ÿด ํŒŒ์ผ์€ ์ข…์ข… ํ”„๋กœ๋•์…˜ ๋ฒˆ๋“ค์— ์ฃฝ์€ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ์ˆœํ™˜ ์˜์กด์„ฑ โ€“ ๋ชจ๋“ˆโ€ฏA๊ฐ€ ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ๋ชจ๋“ˆโ€ฏB๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ๋ชจ๋“ˆโ€ฏB๊ฐ€ ๊ฐ™์€ ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ๋ชจ๋“ˆโ€ฏA๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ๋Ÿฐํƒ€์ž„ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ…: ์ง์ ‘ ์ž„ํฌํŠธ ๐Ÿ› ๏ธ

์ˆ˜์ •์€ ๊ฐ„๋‹จํ•˜์ง€๋งŒ ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์„ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค:

import { Button } from './components';

๋‹ค์Œ๊ณผ ๊ฐ™์ด:

import { Button } from './components/Button';

500๊ฐœ ์ด์ƒ์˜ ํŒŒ์ผ์„ ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๊ณ ํ†ต์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ž๋™ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

์†Œ๊ฐœ: no-barrel-file

์˜คํ”ˆโ€‘์†Œ์Šค CLI ๋„๊ตฌ์ด์ž GitHub Action์œผ๋กœ, ํ”„๋กœ์ ํŠธ๋ฅผ ์Šค์บ”ํ•˜์—ฌ ๋ฐฐ๋Ÿด ํŒŒ์ผ์— ์˜์กดํ•˜๋Š” import๋ฅผ ์ฐพ์•„ ์ง์ ‘ ๊ฒฝ๋กœ๋กœ ์ž๋™ ์žฌ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

โœจ ํŠน์ง•

  • ์ž๋™ ์ˆ˜์ • โ€“ ts-morph(AST ๋ณ€ํ™˜, ์ •๊ทœ์‹์ด ์•„๋‹˜)๋ฅผ ์‚ฌ์šฉํ•ด import๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์žฌ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์Šค๋งˆํŠธ โ€“ tsconfig.json์˜ paths์™€ ๋ณ„์นญ์„ ์กด์ค‘ํ•ฉ๋‹ˆ๋‹ค.
  • ์œ ์—ฐ โ€“ npx๋กœ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ์ „์—ญ ์„ค์น˜, CI์—์„œ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ’ป ๋กœ์ปฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•

๋ฐฉ๋ฒ•โ€ฏ1 โ€“ โ€œํ•œ ๋ฒˆ๋งŒโ€ (์„ค์น˜ ์—†์ด)

์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜์ง€ ์•Š๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ npx๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

# Just list the barrel files
npx no-barrel-file display

# Fix the imports
npx no-barrel-file replace --alias-config-path tsconfig.json

๋ฐฉ๋ฒ•โ€ฏ2 โ€“ โ€œํ”„๋กœ์ ํŠธ ํ‘œ์ค€โ€ (๊ฐœ๋ฐœ ์˜์กด์„ฑ)

ํŒ€ ์ „์ฒด๊ฐ€ ๋ฐฐ๋Ÿด ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋ ค๋ฉด ๊ฐœ๋ฐœ ์˜์กด์„ฑ์œผ๋กœ ์„ค์น˜ํ•˜์„ธ์š”.

npm install -D no-barrel-file
# or
pnpm add -D no-barrel-file

package.json์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

{
  "scripts": {
    "fix:barrels": "no-barrel-file replace --alias-config-path tsconfig.json",
    "check:barrels": "no-barrel-file display"
  }
}

์ด์ œ ํŒ€์˜ ๋ˆ„๊ตฌ๋“ ์ง€ npm run fix:barrels๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฉ๋ฒ•โ€ฏ3 โ€“ โ€œํŒŒ์›Œ ์œ ์ €โ€ (์ „์—ญ ์„ค์น˜)

์—ฌ๋Ÿฌ ์ €์žฅ์†Œ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์ด ๋„๊ตฌ๋ฅผ ํ„ฐ๋ฏธ๋„ ์–ด๋””์„œ๋“  ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด:

npm install -g no-barrel-file

# Now you can run it anywhere
no-barrel-file display

๐Ÿค– GitHub Actions๋กœ ์ž๋™ํ™”ํ•˜๊ธฐ

์ฝ”๋“œ ํ’ˆ์งˆ์„ ์œ ์ง€ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ž๋™ํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋ฐฐ๋Ÿด ํŒŒ์ผ์ด ์ €์žฅ์†Œ์— ๋“ค์–ด์˜ค์ง€ ์•Š๋„๋ก GitHub Action์„ ๊ณต๊ฐœํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ต์…˜โ€ฏA โ€“ ์ž๋™ ์ˆ˜์ • ๋ชจ๋“œ (๊ถŒ์žฅ)

์ด ์›Œํฌํ”Œ๋กœ๋Š” ํ’€ ๋ฆฌํ€˜์ŠคํŠธ์—์„œ ์ง€์—ฐ๋œ(import) ์ž„ํฌํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ž๋™์œผ๋กœ ์ˆ˜์ •ํ•œ ๋’ค ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ธŒ๋žœ์น˜์— ํ‘ธ์‹œํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ผ: .github/workflows/fix-barrels.yml

name: Auto-Fix Barrel Files
on: [pull_request]

permissions:
  contents: write # Required to commit changes

jobs:
  fix-imports:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run No Barrel File
        uses: chintan9/no-barrel-file@v1
        with:
          mode: 'replace'
          alias-config-path: 'tsconfig.json'
          extensions: '.ts,.tsx'

      - name: Commit changes
        uses: stefanzweifel/git-auto-commit-action@v5
        with:
          commit_message: "refactor: resolve barrel file imports"

์˜ต์…˜โ€ฏB โ€“ ๊ฐ์‚ฌ ๋ชจ๋“œ

์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  CI ๋กœ๊ทธ์— ๋ฐฐ๋Ÿด ํŒŒ์ผ ๋ณด๊ณ ์„œ๋งŒ ๋ฐ›๊ณ  ์‹ถ๋‹ค๋ฉด:

- name: Audit Barrel Files
  uses: chintan9/no-barrel-file@v1
  with:
    mode: 'display'
    root-path: 'src'

๊ฒฐ๊ณผ

  • Jest ์‹œ์ž‘ ์‹œ๊ฐ„: ์•ฝ 30% ๊ฐ์†Œ.
  • ์ˆœํ™˜ ์˜์กด์„ฑ ์˜ค๋ฅ˜: ์™„์ „ํžˆ ์‚ฌ๋ผ์ง.
  • ๋ฒˆ๋“ค ํฌ๊ธฐ: ์•ฝ๊ฐ„ ๊ฐ์†Œ (๊ธฐ์กด ํŠธ๋ฆฌ์‰์ดํ‚น ์„ค์ •์— ๋”ฐ๋ผ ๋‹ค๋ฆ„).

์ง์ ‘ ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ!

์—ฌ๋Ÿฌ๋ถ„์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋“ฃ๊ณ  ์‹ถ์–ด์š”. ์‹œ๊ฐ„์ด ์ ˆ์•ฝ๋˜์—ˆ๋‹ค๋ฉด GitHub์— ๋ณ„ํ‘œ๋ฅผ ๋‹ฌ์•„ ์ฃผ์„ธ์š”!

[no-barrel-file](https://www.npmjs.com/package/no-barrel-file)

๐Ÿ™ **GitHub:** [github.com/chintan9/no-barrel-file](https://github.com/chintan9/no-barrel-file)

Happy coding! ๐Ÿš€

์ฝ”๋”ฉ ์ฆ๊ฒ๊ฒŒ! ๐Ÿš€

Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

Next js์—์„œ ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•

์ œ๊ฐ€ ์ฒ˜์Œ Next.js๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ, ๊ธฐ๋ณธ ์„ค์ •๋งŒ์œผ๋กœ๋„ ์–ผ๋งˆ๋‚˜ ๋น ๋ฅธ์ง€ ์ •๋ง ์ข‹์•˜์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ ์ปค์ง€๋ฉด์„œ bundle size๊ฐ€ ๊ณ„์† ์ฆ๊ฐ€ํ•ด ๋กœ๋“œ๊ฐ€ ๋А๋ ค์กŒ์Šต๋‹ˆ๋‹ค.

Knip: JavaScript ๋ฐ TypeScript ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ๊ถ๊ทน์ ์ธ ์ฃฝ์€ ์ฝ”๋“œ ํƒ์ง€๊ธฐ

์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋ฅผ ๋ฐฐํฌํ•˜์ง€ ๋งˆ์„ธ์š”. ๋ฒˆ๋“ค๊ณผ ํŒ€์ด ๊ฐ์‚ฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ: dead code๋Š” ์–ด๋””์—๋‚˜ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์„ฑ์ˆ™ํ•œ ์ฝ”๋“œ๋ฒ ์ด์Šค๋Š” ๋”๋Ÿฌ์šด ๋น„๋ฐ€์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค: dead code. The u...

2025๋…„์— JavaScript ๋ฒˆ๋“ค ํฌ๊ธฐ ์ค„์ด๋Š” ๋ฐฉ๋ฒ• ๐Ÿš€

์†Œ๊ฐœ: JavaScript ๋ฒˆ๋“ค ํฌ๊ธฐ๋Š” ์›น ์„ฑ๋Šฅ์— ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ํฐ ๋ฒˆ๋“ค์€ ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ๊ฐ„์„ ๋Šฆ์ถ”๊ณ  Core Web Vitals์— ์•…์˜ํ–ฅ์„ ์ฃผ๋ฉฐ ์‚ฌ์šฉ์ž๋ฅผ ์ขŒ์ ˆ์‹œํ‚ต๋‹ˆ๋‹ค. Eve...