์ž‘๊ฐ€:
    ์ƒ์„ฑ:2026-09-02๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ:2026-09-28

    2026๋…„์—๋„ vue-i18n์„ ๊ณ„์† ์จ์•ผ ํ• ๊นŒ์š”?

    Vue ์ƒํƒœ๊ณ„์—์„œ vue-i18n๋งŒํผ ์••๋„์ ์ธ ์ ์œ ์œจ์„ ๊ธฐ๋กํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋“œ๋ญ…๋‹ˆ๋‹ค. Vue 2 ์‹œ์ ˆ๋ถ€ํ„ฐ Kazupon์˜ ์ฃผ๋„ํ•˜์— ์„ฑ์žฅํ•ด ์™”์œผ๋ฉฐ, @nuxtjs/i18n์˜ ๊ธฐ๋ฐ˜์ด์ž ๋‹ค๊ตญ์–ด ์ง€์› Vue ํ”„๋กœ์ ํŠธ์˜ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ด์—ˆ์Šต๋‹ˆ๋‹ค.

    ๊ทธ๋Ÿฌ๋‚˜ 2026๋…„ ๋ฒค์น˜๋งˆํฌ ๊ฒฐ๊ณผ๋Š” ๋†€๋ผ์šด ์‚ฌ์‹ค์„ ๋“œ๋Ÿฌ๋ƒˆ์Šต๋‹ˆ๋‹ค. vue-i18n์€ ํ…Œ์ŠคํŠธํ•œ ๋ชจ๋“  ์ฃผ์š” ํ”„๋ก ํŠธ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ๊ฐ€์žฅ ๋ฌด๊ฑฐ์šด ์ง€์—ญํ™” ๋Ÿฐํƒ€์ž„์ด์—ˆ์Šต๋‹ˆ๋‹ค.

    Vite + Vue ๊ธฐ๋ฐ˜์˜ ๊ฐ€๋ฒผ์šด ๊ธฐ๋ณธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(31.5 KB)์— vue-i18n์„ ์ถ”๊ฐ€ํ•˜์ž, ํŽ˜์ด์ง€๋‹น ํ‰๊ท  JavaScript ํฌ๊ธฐ๊ฐ€ 136.4 KB๋กœ 4๋ฐฐ ์ด์ƒ ์น˜์†Ÿ์•˜์Šต๋‹ˆ๋‹ค.

    ๋ณธ๋ž˜ ๊ฐ€๋ณ๊ณ  ๊ธฐ๋ฏผํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์‚ฌ๋ž‘๋ฐ›๋Š” Vue์—์„œ, ์™œ i18n ๋„๊ตฌ๋งŒ ์ดํ† ๋ก ๋น„๋Œ€ํ•ด์กŒ์„๊นŒ์š”? ๊ทธ๋ฆฌ๊ณ  ์ˆœ์ˆ˜ ๋Ÿฐํƒ€์ž„ ๋ชจ๋ธ์€ ์˜ค๋Š˜๋‚ ์—๋„ ์œ ํšจํ• ๊นŒ์š”?

    ํ•ต์‹ฌ ์š”์•ฝ

    ํ…Œ์ŠคํŠธ ๋Œ€์ƒ ์ค‘ ๊ฐ€์žฅ ๋ฌด๊ฑฐ์šด ๋Ÿฐํƒ€์ž„:

    ํ…์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๋„ ์ „์— ์ด๋ฏธ 24.3 KB (gzip ๊ธฐ์ค€, Minified ์‹œ 83.2 KB)์˜ ํฌ๊ธฐ๋ฅผ ์ฐจ์ง€ํ•˜์—ฌ, intlayer ์ฝ”์–ด ๋Ÿฐํƒ€์ž„(2.7 KB) ๋Œ€๋น„ ์•ฝ 9๋ฐฐ ๋ฌด๊ฒ์Šต๋‹ˆ๋‹ค.

    ํŽ˜์ด์ง€ ํŽ˜์ด๋กœ๋“œ 330% ์ฆ๊ฐ€:

    vue-i18n์€ 31.5 KB์— ๋ถˆ๊ณผํ–ˆ๋˜ ๊ธฐ๋ณธ Vue ํŽ˜์ด์ง€๋ฅผ 136.4 KB๋กœ ๋Š˜๋ ค๋†“์•˜์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Intlayer๋Š” 59.3 KB์— ๊ทธ์ณ 56% ๋” ๊ฐ€๋ฒผ์šด ํŽ˜์ด๋กœ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    ๋ธŒ๋ผ์šฐ์ €๋กœ ๋ฒˆ๋“ค๋ง๋˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ:

    ๋ฒˆ๋“ค๋Ÿฌ์— ํŠน์ • ๋ณ„์นญ(alias)์„ ์ˆ˜๋™ ์„ค์ •ํ•˜์ง€ ์•Š๋Š” ํ•œ, vue-i18n์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ…์ŠคํŠธ๋ฅผ ์‹ค์‹œ๊ฐ„ ํŒŒ์‹ฑํ•˜๊ธฐ ์œ„ํ•ด ์ „์ฒด ๋ฉ”์‹œ์ง€ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

    ์œ ์ง€๋ณด์ˆ˜ ์ถ”์„ธ:

    ์ง€๋‚œ 1๋…„๊ฐ„ vue-i18n์€ ์•ฝ 259๊ฐœ์˜ ์ปค๋ฐ‹์„ ๊ธฐ๋กํ–ˆ์œผ๋‚˜, ๋Œ€๋ถ€๋ถ„ ๋ฒ„๊ทธ ์ˆ˜์ •๊ณผ Vue ๋งˆ์ด๋„ˆ ๋ฒ„์ „ ๋Œ€์‘์— ์ง‘์ค‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

    ๊ณต์‹ ํ˜„๋Œ€์  ๋„๊ตฌ์˜ ๋ถ€์žฌ:

    ๊ณต์‹ Language Server (LSP), AI์šฉ MCP ์„œ๋ฒ„, CLI ๊ธฐ๋ฐ˜ ์ž๋™ ๋ฒˆ์—ญ ๋“ฑ ์ฐจ์„ธ๋Œ€ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์œ„ํ•œ ๋„๊ตฌ๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.

    ์œ ์ง€๋ณด์ˆ˜ vs. ํ˜„๋Œ€์  ๋„๊ตฌ ๋น„๊ต

    ์ €์žฅ์†Œ์Šคํƒ€์ „์ฒด ์ปค๋ฐ‹์—ฐ๊ฐ„ ์ปค๋ฐ‹์ตœ๊ทผ ์ปค๋ฐ‹
    intlify/vue-i18nstarscommitsyearlylast
    aymericzip/intlayerstarscommitsyearlylast

    ์ตœ๊ทผ 12๊ฐœ์›” ํ™œ๋™ ๋น„๊ต:

    • intlify/vue-i18n: 259 ์ปค๋ฐ‹ (Vue 3 ๋ฐ Nuxt ์œ ์ง€๋ณด์ˆ˜ ์œ„์ฃผ).
    • aymericzip/intlayer: 4,343 ์ปค๋ฐ‹ (์ปดํŒŒ์ผ๋Ÿฌ ๊ณ ๋„ํ™”, LSP ๋„๊ตฌ, AI ์—์ด์ „ํŠธ ์—ฐ๋™ ์ž‘์—… ๋“ฑ ์ง€์† ๊ฐœ๋ฐœ).

    Star History Chart

    • intlify/vue-i18n
    • aymericzip/intlayer

    ๊ธฐ๋ณธ ๋ธŒ๋žœ์น˜์˜ ์ปค๋ฐ‹ ์ˆ˜, ์ถœ์ฒ˜: GitHub API.

    ์˜ค๋ž˜๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์•ˆ์ •์„ฑ์ด ๋›ฐ์–ด๋‚ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์˜ค๋Š˜๋‚ ์˜ ํ”„๋ก ํŠธ์—”๋“œ๋Š” ๋นŒ๋“œ ํƒ€์ž„ AST ๋ณ€ํ™˜, ๋ฐ๋“œ ์ฝ”๋“œ ์ œ๊ฑฐ, AI ์ž๋™ํ™”์— ๊ธฐ๋ฐ˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„์— ์ข…์†๋œ ๊ตฌ์กฐ๋กœ๋Š” ์ด๋Ÿฌํ•œ ํ˜์‹ ์„ ์˜จ์ „ํžˆ ๋”ฐ๋ผ์žก๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

    ์ด๋Ÿฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์–ด๋””์—์„œ ์™”๋Š”์ง€ ์ดํ•ดํ•˜๋ ค๋ฉด JavaScript i18n์˜ ์—ญ์‚ฌ๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”.

    npm ๋‹ค์šด๋กœ๋“œ

    • vue-i18n
    • vue-intlayer

    ์ถœ์ฒ˜: npm ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋‹ค์šด๋กœ๋“œ API.

    ๋‹ค์šด๋กœ๋“œ ์ˆ˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ์†”๋ฃจ์…˜์ด ์•„๋‹ˆ๋ผ ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ์†”๋ฃจ์…˜์— ๋ณด์ƒ์„ ์ค๋‹ˆ๋‹ค. ์ˆ˜๋…„ ์ „์— ์ถœ์‹œ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋‹น์‹œ ์ด๋ฅผ ์„ ํƒํ•œ ๋ชจ๋“  ํ”„๋กœ์ ํŠธ, ๋ชจ๋“  CI ์‹คํ–‰, ์ด์— ์˜์กดํ•˜๋Š” ๋ชจ๋“  ํŒจํ‚ค์ง€์— ์˜ํ•ด ์—ฌ์ „ํžˆ ์„ค์น˜๋ฉ๋‹ˆ๋‹ค. ์ด ์ˆ˜์น˜๋Š” ์ƒˆ๋กœ์šด ์„ ํƒ๋ณด๋‹ค ๊ด€์„ฑ์„ ์ธก์ •ํ•ฉ๋‹ˆ๋‹ค.

    AI ์–ด์‹œ์Šคํ„ดํŠธ๋Š” ์ด ํšจ๊ณผ๋ฅผ ๋” ํ‚ค์›๋‹ˆ๋‹ค. next-intl, i18next, vue-i18n์€ AI๊ฐ€ ํ•™์Šตํ•œ ์ฝ”๋“œ ๊ณณ๊ณณ์— ์žˆ์œผ๋ฏ€๋กœ, AI๋Š” ๋Œ€์•ˆ์„ ๋น„๊ตํ•˜์ง€ ์•Š๊ณ  ์ด๋“ค์„ ๊ธฐ๋ณธ์œผ๋กœ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. ์ถ”์ฒœ์ด ๋‹ค์šด๋กœ๋“œ๋ฅผ ๋Š˜๋ฆฌ๊ณ , ๊ทธ ๋‹ค์šด๋กœ๋“œ๊ฐ€ ๋‹ค์Œ ์ถ”์ฒœ์„ ๋ถ€์ถ”๊น๋‹ˆ๋‹ค. ๋‹ค์šด๋กœ๋“œ ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฒค์น˜๋งˆํฌ๋กœ ๋น„๊ตํ•˜์„ธ์š”.

    Vite + Vue ์„ฑ๋Šฅ ์ธก์ • ๊ฒฐ๊ณผ

    Vite ๋ฐ Vue 3 ๊ธฐ๋ฐ˜ 10๊ฐœ ํŽ˜์ด์ง€, 10๊ฐœ ์–ธ์–ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธก์ •:

    ์ธก์ •ํ•ญ๋ชฉ

    ๋™์  JSON ๋กœ๋“œ

    ๋Ÿฐํƒ€์ž„์— ๋ฒˆ์—ญ์„ ์ง€์—ฐ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค

    ๋ฒ”์œ„๊ฐ€ ์ง€์ •๋œ JSON (๋„ค์ž„์ŠคํŽ˜์ด์‹ฑ)

    ํŽ˜์ด์ง€๋ณ„ ๋ฒˆ์—ญ ๋„ค์ž„์ŠคํŽ˜์ด์Šค

    ์ด ์ธก์ •ํ•ญ๋ชฉ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

    ๊ตญ์ œํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒˆ๋“ค์˜ ์ด gzip ์••์ถ• ํฌ๊ธฐ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ํŠธ๋ฆฌ ์‰์ดํ‚น ๋ฐ ๋ฏธ๋‹ˆํ”ผ์ผ€์ด์…˜ ํ›„์˜ ํ”„๋กœ๋ฐ”์ด๋” ๋ฐ ์ฝ˜ํ…์ธ  ๊ฒ€์ƒ‰ ๋กœ์ง๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

    ์™œ ์ค‘์š”ํ•œ๊ฐ€์š”?

    ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํฌ๊ธฐ๊ฐ€ ์ž‘์œผ๋ฉด ์ดˆ๊ธฐ JavaScript ํŽ˜์ด๋กœ๋“œ๊ฐ€ ์ค„์–ด๋“ค์–ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋‹ค์šด๋กœ๋“œ ๋ฐ ์‹คํ–‰ ์‹œ๊ฐ„์ด ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค.

    ๋ณด๊ธฐ ํ˜•์‹

    ํ”„๋กœ๋•์…˜ gzip ์••์ถ•์„ ์ ์šฉํ•˜์—ฌ ์‹ค์ œ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ธก์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์„ธ๋ถ€ ์‚ฌํ•ญ์€ Vue ๋ฒค์น˜๋งˆํฌ ๋ฌธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ดˆ๊ธฐ ์˜ค๋ฒ„ํ—ค๋“œ

    ๋ฒˆ์—ญ ํ…์ŠคํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์ „์˜ ์ˆœ์ˆ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํฌ๊ธฐ:

    ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌGzip ๊ธฐ์ค€Minified ๊ธฐ์ค€
    vue-i18n@11.4.024.3 KB83.2 KB
    intlayer@8.7.122.7 KB7.6 KB

    vue-i18n์˜ ๋Ÿฐํƒ€์ž„ ์—”์ง„๋งŒ์œผ๋กœ 24.3 KB (gzip)์— ๋‹ฌํ•ด Vue ์ฝ”์–ด ์ „์ฒด ํฌ๊ธฐ์™€ ๋งž๋จน์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Intlayer๋Š” ๋‹จ 2.7 KB๋งŒ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค.

    ํŽ˜์ด์ง€ ํฌ๊ธฐ ๋ฐ ๋ถˆํ•„์š”ํ•œ ๋ฒˆ์—ญ ๋ˆ„์ˆ˜

    ๊ตฌ์„ฑํ‰๊ท  ํŽ˜์ด์ง€ JS (gz)ํƒ€ ์–ธ์–ด ๋ˆ„์ˆ˜์œจํƒ€ ํŽ˜์ด์ง€ ๋ˆ„์ˆ˜์œจํ‰๊ท  ์ปดํฌ๋„ŒํŠธ (gz)
    ๊ธฐ๋ณธ(i18n ์—†์Œ)31.5 KB0.0%90.0%0.9 KB
    vue-i18n136.4 KB50.2%90.0%196.0 KB
    Intlayer59.3 KB51.1%0.0%6.5 KB

    ์ธก์ • ์ฃผ์š” ๊ฒฐ๊ณผ

    ๋†’์€ ์ƒ๋Œ€์  ์ฆ๊ฐ€์œจ:

    Vue ํ”„๋ ˆ์ž„์›Œํฌ ์ž์ฒด์˜ ๊ธฐ๋ณธ ํฌ๊ธฐ๊ฐ€ ์›Œ๋‚™ ์ž‘๊ธฐ ๋•Œ๋ฌธ์—(~31 KB), vue-i18n์„ ๋„์ž…ํ•˜๋ฉด ํŽ˜์ด์ง€ ํŽ˜์ด๋กœ๋“œ๊ฐ€ 4๋ฐฐ ์ด์ƒ ์ปค์ง‘๋‹ˆ๋‹ค.

    ํƒ€ ํŽ˜์ด์ง€๋กœ์˜ ๋ฒˆ์—ญ ๋ฐ์ดํ„ฐ ๋ˆ„์ˆ˜:

    ๊ธฐ๋ณธ ์„ค์ • ์ƒํƒœ์—์„œ๋Š” ํŠน์ • ๋ผ์šฐํŠธ์— ๋‚ด๋ ค์˜ค๋Š” ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ์˜ 90%๊ฐ€ ๋‹ค๋ฅธ ํŽ˜์ด์ง€์šฉ์ž…๋‹ˆ๋‹ค. Intlayer๋Š” ์ด๋ฅผ ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜์—ฌ ๋ˆ„์ˆ˜์œจ 0.0%๋ฅผ ๊ธฐ๋กํ–ˆ์Šต๋‹ˆ๋‹ค.

    ๊ฐœ๋ณ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋น„๋Œ€ํ™”:

    ์‚ฌ์ „์ด ๋ฐ˜๋ณต ๋ณต์ œ๋˜๋ฉด์„œ vue-i18n์˜ ์ง€์—ญ ์Šค์ฝ”ํ”„ ์ปดํฌ๋„ŒํŠธ ํฌ๊ธฐ๋Š” ํ‰๊ท  196 KB๊นŒ์ง€ ์น˜์†Ÿ์•˜์œผ๋‚˜, Intlayer์—์„œ๋Š” 6.5 KB์— ๋ถˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค.

    ๋ˆ„์ˆ˜๊ฐ€ ์ปค์ง€๋Š” ๋ฐฉ์‹:

    ์•„๋ž˜ ๊ทธ๋ž˜ํ”„๋Š” 110๊ฐœ์˜ ํŽ˜์ด์ง€๋ฅผ 110๊ฐœ ์–ธ์–ด๋กœ ๋ฒˆ์—ญํ•œ ์ด๋ก ์ƒ์˜ ์•ฑ(ํŽ˜์ด์ง€๋‹น ์•ฝ 30KB์˜ ํ…์ŠคํŠธ)์˜ ์ฝ˜ํ…์ธ  ์šฉ๋Ÿ‰์„ ์ถ”์ •ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋กœ์ผ€์ผ๋ณ„ ๋™์  ๋กœ๋”ฉ์€ ์–ธ์–ด ์ถ•์„ ์—†์• ๊ณ , ์ปดํฌ๋„ŒํŠธ๋‚˜ ๋ผ์šฐํŠธ ๋‹จ์œ„๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์Šค์ฝ”ํ”„ํ•˜๋ฉด ํŽ˜์ด์ง€ ์ถ•์ด ์—†์–ด์ง€๋ฉฐ, ๋‘ ๊ฐ€์ง€๋ฅผ ๊ฒฐํ•ฉํ–ˆ์„ ๋•Œ๋งŒ ์šฉ๋Ÿ‰์ด ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

    ์•„ํ‚คํ…์ฒ˜๋ณ„ ์ด๋ก ์ƒ์˜ ์ฝ˜ํ…์ธ  ๋ˆ„์ˆ˜

    vue-i18n์ด ๋ฌด๊ฑฐ์šด ์ด์œ 

    ๋ธŒ๋ผ์šฐ์ €๋กœ ์ „์†ก๋˜๋Š” AST ์ปดํŒŒ์ผ๋Ÿฌ

    vue-i18n์€ ์ž์ฒด ๋ฉ”์‹œ์ง€ ํ˜•์‹ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋‚ด์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณต์ˆ˜ํ˜• ๊ทœ์น™์ด๋‚˜ ๋ณ€์ˆ˜ ์น˜ํ™˜ ๋กœ์ง์ด ๋ธŒ๋ผ์šฐ์ € ๋Ÿฐํƒ€์ž„์—์„œ AST(์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ)๋กœ ์‹ค์‹œ๊ฐ„ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

    ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ๋ฒˆ๋“ค๋Ÿฌ์—์„œ vue-i18n/dist/vue-i18n.runtime.esm-bundler.js๋กœ ๋ณ„์นญ์„ ์ง€์ •ํ•˜๊ณ  @intlify/unplugin-vue-i18n์„ ํ†ตํ•ด ์‚ฌ์ „ ์ปดํŒŒ์ผ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜์ง€๋งŒ, ๋งŽ์€ ํ”„๋กœ์ ํŠธ์—์„œ ์ด ๊ณผ์ •์ด ์ƒ๋žต๋ฉ๋‹ˆ๋‹ค.

    ๋ชจ๋†€๋ฆฌ์‹ ๊ธฐ๋Šฅ ๊ตฌ์กฐ

    ๋‚ ์งœ ๋ฐ ์ˆซ์ž ํฌ๋งคํ„ฐ, ๋งํฌ๋“œ ๋ฉ”์‹œ์ง€, ๋ ˆ๊ฑฐ์‹œ Options API ์ง€์› ๋ธŒ๋ฆฌ์ง€($t, v-t), ๋ฐ˜์‘ํ˜• ํ”„๋ก์‹œ๊ฐ€ ๋ชจ๋‘ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. <script setup> ๋‚ด์—์„œ ๋‹จ์ˆœ ํ…์ŠคํŠธ๋งŒ ํ‘œ์‹œํ•˜๊ณ  ์‹ถ๋”๋ผ๋„ ์ „์ฒด ์‹œ์Šคํ…œ์ด ํ•จ๊ป˜ ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.

    ๋™์  ํ‚ค๋กœ ์ธํ•œ ํŠธ๋ฆฌ ์‰์ดํ‚น ์ฐจ๋‹จ

    "home.hero.title" ํ‚ค๊ฐ€ ๋Ÿฐํƒ€์ž„์— ํ‰๊ฐ€๋˜๋ฏ€๋กœ ๋ฒˆ๋“ค๋Ÿฌ๋Š” ์‹ค์ œ๋กœ ์“ฐ์ด๋Š” ํ…์ŠคํŠธ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์“ฐ์ด์ง€ ์•Š๋Š” ๋ฌธ๊ตฌ๋„ ๋ฒˆ๋“ค์— ๋‚จ์•„ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

    Hero.vue
    <script setup>
    import { useI18n } from "vue-i18n";
    
    const { t } = useI18n();
    </script>
    
    <template>
      <h1>{{ t("home.hero.title") }}</h1>
    </template>
    
    Hero.vue
    <script setup>
    import { useIntlayer } from "vue-intlayer";
    
    const { title } = useIntlayer("hero");
    </script>
    
    <template>
      <h1>{{ title }}</h1>
    </template>
    

    Intlayer ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ ‘๊ทผํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ช…ํ™•ํžˆ ํŒŒ์•…ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค ์ƒ์„ฑ ์ „์— ๋ฏธ์‚ฌ์šฉ ๋ฒˆ์—ญ์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐฐ์ œํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ฒˆ๋“ค ์ตœ์ ํ™”๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

    ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜ (DX) ๋น„๊ต

    ๊ฒฉ๋ฆฌ๋œ JSON ํด๋” vs. ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ๋ฐฐ์น˜

    vue-i18n์—์„œ๋Š” ํ…์ŠคํŠธ๊ฐ€ ๋ฉ€๋ฆฌ ๋–จ์–ด์ง„ locales/ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋จธ๋ญ…๋‹ˆ๋‹ค. Intlayer๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ ๋ฐ”๋กœ ์˜†์— ์ฝ˜ํ…์ธ  ํŒŒ์ผ์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    locales/en.json
    {
      "hero": {
        "title": "Ship in every language"
      }
    }
    
    locales/ko.json
    {
      "hero": {
        "title": "๋ชจ๋“  ์–ธ์–ด๋กœ ์ถœ์‹œํ•˜์„ธ์š”"
      }
    }
    
    Hero.vue
    <script setup>
    import { useI18n } from "vue-i18n";
    
    const { t } = useI18n();
    </script>
    
    <template>
      <h1>{{ t("hero.title") }}</h1>
    </template>
    
    Hero.content.ts
    import { t, type Dictionary } from "intlayer";
    
    export default {
      key: "hero",
      content: {
        title: t({
          en: "Ship in every language",
          ko: "๋ชจ๋“  ์–ธ์–ด๋กœ ์ถœ์‹œํ•˜์„ธ์š”",
        }),
      },
    } satisfies Dictionary;
    
    Hero.vue
    <script setup>
    import { useIntlayer } from "vue-intlayer";
    
    const { title } = useIntlayer("hero");
    </script>
    
    <template>
      <h1>{{ title }}</h1>
    </template>
    

    Hero.vue๋ฅผ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ์ด๋™ํ•˜๋ฉด ํ•ด๋‹น ์ฝ˜ํ…์ธ  ์„ ์–ธ ํŒŒ์ผ๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ•จ๊ป˜ ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

    ์—๋””ํ„ฐ ์ž๋™์™„์„ฑ vs. ์—„๊ฒฉํ•œ ์™„์ „์„ฑ ๋ณด์žฅ

    DefineLocaleMessage๋ฅผ ํ†ตํ•ด ๊ธฐ๋ณธ ์Šคํ‚ค๋งˆ ๊ธฐ์ค€์˜ ์ž๋™์™„์„ฑ์€ ์ง€์›๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ชจ๋“  ์–ธ์–ด์˜ ์™„๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•˜์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค. ko.json์—์„œ ํ‚ค๋ฅผ ์ง€์›Œ๋„ TypeScript ๋นŒ๋“œ๊ฐ€ ๋ฉˆ์ถ”์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    Intlayer๋Š” ์‚ฌ์ „์„ ์—„๊ฒฉํ•˜๊ฒŒ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. strictMode๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ฉด ์–ด๋–ค ์–ธ์–ด์—์„œ๋“  ๋ฒˆ์—ญ์ด ๋ˆ„๋ฝ๋  ๊ฒฝ์šฐ ์ฆ‰๊ฐ ๋นŒ๋“œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

    IDE ๋ฐ AI ๋„๊ตฌ ์ง€์›

    ๊ธฐ๋Šฅvue-i18nIntlayer
    VS Code ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์„œ๋“œํŒŒํ‹ฐ (i18n Ally)โœ… ๊ณต์‹ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ
    Language Server (LSP)โŒ ์—†์Œโœ… ์ „์šฉ LSP
    AI์šฉ MCP ์„œ๋ฒ„โŒ ์—†์Œโœ… ๋‚ด์žฅ MCP ์„œ๋ฒ„
    ์—์ด์ „ํŠธ ์Šคํ‚ฌ ์„ธํŠธโŒ ์—†์Œโœ… ์ž์œจ ์—์ด์ „ํŠธ ์Šคํ‚ฌ
    ์ธ์ปจํ…์ŠคํŠธ ๋น„์ฃผ์–ผ CMSโŒ ์—†์Œโœ… ๋ฌด๋ฃŒ ์˜คํ”ˆ์†Œ์Šค CMS

    ๋ฒˆ์—ญ ์›Œํฌํ”Œ๋กœ์šฐ

    vue-i18n์—๋Š” ์ž์ฒด์ ์ธ ๋ฒˆ์—ญ ์ƒ์„ฑ ๋ช…๋ น์–ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋“ค์€ ํŒŒ์ผ์„ Crowdin์ด๋‚˜ Phrase ๊ฐ™์€ ์™ธ๋ถ€ ํ”Œ๋žซํผ์œผ๋กœ ๋‚ด๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    Intlayer๋Š” ์™„์ „ํ•œ ๋„ค์ดํ‹ฐ๋ธŒ ๋„๊ตฌ๋ฅผ ๊ธฐ๋ณธ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    ๋กœ์ปฌ AI ์ž๋™ ์ฑ„์šฐ๊ธฐ (intlayer fill):

    ์†Œ์œ ํ•œ OpenAI, Anthropic, Mistral, Gemini API ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ˆ„๋ฝ๋œ ๋ฒˆ์—ญ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    ์ž์ฒด ํ˜ธ์ŠคํŒ… ๋น„์ฃผ์–ผ CMS:

    Intlayer CMS๋ฅผ ์—ฐ๋™ํ•˜๋ฉด ๊ธฐํš์ž๋‚˜ ๋งˆ์ผ€ํ„ฐ๊ฐ€ ์›น UI์—์„œ ๋ฌธ๊ตฌ๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ Git์— ์ปค๋ฐ‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด์„ ์Šค:

    ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ Apache 2.0 ๋ผ์ด์„ ์Šค๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

    ์ง€๊ธˆ๋„ vue-i18n์ด ์œ ํšจํ•œ ๊ฒฝ์šฐ๋Š”?

    ๋ผ์šฐํŒ… ๊ตฌ์กฐ๊ฐ€ @nuxtjs/i18n๊ณผ ๊นŠ๊ฒŒ ์–ฝํ˜€ ์žˆ๋‹ค๋ฉด ์‹œ์Šคํ…œ์„ ์ „๋ฉด ๊ฐœํŽธํ•˜๋Š” ๊ฒƒ์ด ๋ถ€๋‹ด์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๊ณ ๋„๋กœ ์ค‘์ฒฉ๋œ ๋ฉ”์‹œ์ง€ ๋งํฌ๋‚˜ ๋ณต์žกํ•œ ์ˆซ์ž/๋‚ ์งœ ๊ทœ์น™์„ ํญ๋„“๊ฒŒ ์‚ฌ์šฉ ์ค‘์ธ ๊ฒฝ์šฐ.

    ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์„ฑ๋Šฅ์ด๋‚˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ๊ฒฐ์ •์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ.

    ๊ธฐ์กด vue-i18n ์„ค์ •์„ ์–ด๋–ป๊ฒŒ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

    Intlayer๋Š” vue-i18n ๋ฐ @nuxtjs/i18n์˜ ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜(useI18n, $t, <i18n-t>)๋ฅผ ๊ทธ๋Œ€๋กœ ์žฌํ˜„ํ•˜๋Š” ๋“œ๋กญ์ธ ํ˜ธํ™˜์„ฑ ํŒจํ‚ค์ง€๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ์ด๋‚˜ Composable์„ ๋‹ค์‹œ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ์ปดํŒŒ์ผ๋Ÿฌ ๊ธฐ๋ฐ˜์˜ ๊ฐ€๋ฒผ์šด ์•„ํ‚คํ…์ฒ˜๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํ˜œํƒ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์„ค์ •์€ ๋‹จ ํ•œ ์ค„์˜ ๋ช…๋ น์–ด๋กœ ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค:

    bash
    npx intlayer init --interactive
    

    ์ด ๋Œ€ํ™”ํ˜• CLI๋Š” ๋‹ค์Œ ์ž‘์—…์„ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค:

    1. @intlayer/vue-i18n ๋˜๋Š” @intlayer/nuxt-i18n ํ˜ธํ™˜์„ฑ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
    2. Vite ๋˜๋Š” Nuxt ๋ฒˆ๋“ค๋Ÿฌ ๋ณ„์นญ(alias)์„ ์„ค์ •ํ•˜์—ฌ ๊ธฐ์กด ์ž„ํฌํŠธ ๋ฐ ํ…œํ”Œ๋ฆฟ ํƒœ๊ทธ๊ฐ€ Intlayer๋กœ ์›ํ™œํ•˜๊ฒŒ ๋ผ์šฐํŒ…๋˜๋„๋ก ์—ฐ๊ฒฐํ•˜๋ฏ€๋กœ, vue-i18n์„ package.json์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    3. ์—๋””ํ„ฐ ๋‚ด ์–ธ์–ด ์„œ๋ฒ„(LSP) ์ง„๋‹จ์„ ์ฆ‰์‹œ ํ™œ์„ฑํ™”ํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค์—์„œ 24KB ํฌ๊ธฐ์˜ AST ํŒŒ์„œ๋ฅผ ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜๋ฉฐ, ๋Œ€๋Œ€์ ์ธ ๋ฆฌํŒฉํ† ๋ง ์—†์ด ๋กœ์ปฌ AI ๋ฒˆ์—ญ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

    ๋‹จ๊ณ„๋ณ„ ์„ธ๋ถ€ ๋‚ด์šฉ์€ ๋‹ค์Œ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”:

    ๋ฌด๋ฃŒ i18n SEO ์Šค์บ๋„ˆ๋ฅผ ํ†ตํ•ด ํ˜„์žฌ ์›น์‚ฌ์ดํŠธ์˜ ๋ฒˆ๋“ค ๋ˆ„์ˆ˜์™€ ํฌ๊ธฐ๋ฅผ ๋ถ„์„ํ•ด ๋ณด์„ธ์š”:

    ๊ด€๋ จ ๊ธ€ ๋ณด๊ธฐ

    ๋Œ“๊ธ€

    ์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋กœ ์˜๊ฒฌ์„ ๋‚˜๋ˆ ๋ณด์„ธ์š”.

    ๊ด€๋ จ ๊ฒŒ์‹œ๋ฌผ

    ์ตœ๊ทผ ๊ฒŒ์‹œ๋ฌผ