๐ ๋ฒ๋ค ์ฌ์ด์ฆ๋ฅผ ์ฃฝ์ด๋ ๊ฑธ ๋ฉ์ถฐ๋ผ
Source: Dev.to
์ฐ๋ฆฌ๋ ๋ชจ๋ 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! ๐
์ฝ๋ฉ ์ฆ๊ฒ๊ฒ! ๐