μν¬νΈ λ§΅μ μ¬μ©ν μλ°μ€ν¬λ¦½νΈ λͺ¨λ ν΄μ μ¬μΈ΅ λΆμ. μν¬νΈ λ§΅ μ€μ , μμ‘΄μ± κ΄λ¦¬, κ²¬κ³ ν μ ν리μΌμ΄μ μ μν μ½λ κ΅¬μ± κ°ν λ°©λ²μ λ°°μ보μΈμ.
μλ°μ€ν¬λ¦½νΈ λͺ¨λ ν΄μ: μ΅μ κ°λ°μ μν μν¬νΈ λ§΅ λ§μ€ν°νκΈ°
λμμμ΄ λ°μ νλ μλ°μ€ν¬λ¦½νΈ μΈκ³μμ, νμ₯ κ°λ₯νκ³ μ μ§λ³΄μνκΈ° μ¬μ΄ μ ν리μΌμ΄μ μ ꡬμΆνλ €λ©΄ μμ‘΄μ±μ κ΄λ¦¬νκ³ μ½λλ₯Ό ν¨κ³Όμ μΌλ‘ ꡬμ±νλ κ²μ΄ μ€μν©λλ€. μλ°μ€ν¬λ¦½νΈ λ°νμμ΄ λͺ¨λμ μ°Ύκ³ λ‘λνλ κ³Όμ μΈ μλ°μ€ν¬λ¦½νΈ λͺ¨λ ν΄μ(resolution)μ μ¬κΈ°μ μ€μ¬μ μΈ μν μ ν©λλ€. μμ¬μ μΌλ‘ μλ°μ€ν¬λ¦½νΈμλ νμ€νλ λͺ¨λ μμ€ν μ΄ μμκΈ° λλ¬Έμ CommonJS (Node.js)λ AMD (λΉλκΈ° λͺ¨λ μ μ)μ κ°μ λ€μν μ κ·Ό λ°©μμ΄ λ±μ₯νμ΅λλ€. νμ§λ§ ES λͺ¨λ(ECMAScript Modules)μ΄ λμ λκ³ μΉ νμ€ μ±νμ΄ μ¦κ°νλ©΄μ, μν¬νΈ λ§΅(import maps)μ λΈλΌμ°μ λ΄μμ, κ·Έλ¦¬κ³ μ μ°¨ μλ² μΈ‘ νκ²½μμλ λͺ¨λ ν΄μμ μ μ΄νλ κ°λ ₯ν λ©μ»€λμ¦μΌλ‘ λΆμνμ΅λλ€.
μν¬νΈ λ§΅μ΄λ 무μμΈκ°?
μν¬νΈ λ§΅μ μλ°μ€ν¬λ¦½νΈ λͺ¨λ μ§μ μ(import λ¬Έμ μ¬μ©λλ λ¬Έμμ΄)κ° νΉμ λͺ¨λ URLλ‘ ν΄μλλ λ°©μμ μ μ΄ν μ μκ² ν΄μ£Όλ JSON κΈ°λ° μ€μ μ
λλ€. μ‘°ν ν
μ΄λΈμ²λΌ λ
Όλ¦¬μ μΈ λͺ¨λ μ΄λ¦μ ꡬ체μ μΈ κ²½λ‘λ‘ λ³ννλ€κ³ μκ°ν μ μμ΅λλ€. μ΄λ μλΉν μ μ°μ±κ³Ό μΆμνλ₯Ό μ 곡νμ¬ λ€μκ³Ό κ°μ μμ
μ κ°λ₯νκ² ν©λλ€:
- λͺ¨λ μ§μ μ μ¬λ§€ν:
importλ¬Έ μ체λ₯Ό μμ νμ§ μκ³ λͺ¨λμ΄ λ‘λλλ μμΉλ₯Ό λ³κ²½ν©λλ€. - λ²μ κ΄λ¦¬: λΌμ΄λΈλ¬λ¦¬μ μ¬λ¬ λ²μ κ°μ μ½κ² μ νν©λλ€.
- μ€μ μ§μ€μ μ€μ : λ¨μΌ μ€μ μμΉμμ λͺ¨λ μμ‘΄μ±μ κ΄λ¦¬ν©λλ€.
- μ½λ μ΄μμ± ν₯μ: μ¬λ¬ νκ²½(λΈλΌμ°μ , Node.js)μμ μ½λλ₯Ό λ μ½κ² μ΄μν μ μλλ‘ λ§λλλ€.
- κ°λ° λ¨μν: κ°λ¨ν νλ‘μ νΈμ κ²½μ° λΉλ λꡬ μμ΄ λΈλΌμ°μ μμ μ§μ λ² μ΄(bare) λͺ¨λ μ§μ μ(μ:
import lodash from 'lodash';)λ₯Ό μ¬μ©ν©λλ€.
μ μν¬νΈ λ§΅μ μ¬μ©ν΄μΌ νλκ°?
μν¬νΈ λ§΅ μ΄μ μλ κ°λ°μλ€μ΄ λͺ¨λ μμ‘΄μ±μ ν΄κ²°νκ³ λΈλΌμ°μ μ© μ½λλ₯Ό λ²λ€λ§νκΈ° μν΄ μ’ μ’ λ²λ€λ¬(webpack, Parcel, Rollup λ±)μ μμ‘΄νμ΅λλ€. λ²λ€λ¬λ μ½λ μ΅μ ν λ° λ³ν(μ: νΈλμ€νμΌλ§, μ΅μν) μνμ μ¬μ ν μ μ©νμ§λ§, μν¬νΈ λ§΅μ λͺ¨λ ν΄μμ μν λ€μ΄ν°λΈ λΈλΌμ°μ μ루μ μ μ 곡νμ¬ νΉμ μλ리μ€μμ 볡μ‘ν λΉλ μ€μ μ νμμ±μ μ€μ¬μ€λλ€. μ΄μ λ€μ λ μμΈν μ΄ν΄λ³΄κ² μ΅λλ€:
λ¨μνλ κ°λ° μν¬νλ‘μ°
μκ·λͺ¨μμ μ€κ° κ·λͺ¨μ νλ‘μ νΈμ κ²½μ°, μν¬νΈ λ§΅μ κ°λ° μν¬νλ‘μ°λ₯Ό ν¬κ² λ¨μνν μ μμ΅λλ€. 볡μ‘ν λΉλ νμ΄νλΌμΈμ μ€μ νμ§ μκ³ λ λΈλΌμ°μ μμ μ§μ λͺ¨λμ μλ°μ€ν¬λ¦½νΈ μ½λλ₯Ό μμ±ν μ μμ΅λλ€. μ΄λ νλ‘ν νμ΄ν, νμ΅ λ° μκ·λͺ¨ μΉ μ ν리μΌμ΄μ μ νΉν μ μ©ν©λλ€.
μ±λ₯ ν₯μ
μν¬νΈ λ§΅μ μ¬μ©νλ©΄ λΈλΌμ°μ μ λ€μ΄ν°λΈ λͺ¨λ λ‘λλ₯Ό νμ©ν μ μμΌλ©°, μ΄λ ν° λ²λ€ μλ°μ€ν¬λ¦½νΈ νμΌμ μμ‘΄νλ κ²λ³΄λ€ λ ν¨μ¨μ μΌ μ μμ΅λλ€. λΈλΌμ°μ λ λͺ¨λμ κ°λ³μ μΌλ‘ κ°μ Έμ¬ μ μμ΄ μ΄κΈ° νμ΄μ§ λ‘λ μκ°μ κ°μ νκ³ κ° λͺ¨λμ νΉνλ μΊμ± μ λ΅μ μ¬μ©ν μ μμ΅λλ€.
ν₯μλ μ½λ ꡬμ±
μν¬νΈ λ§΅μ μμ‘΄μ± κ΄λ¦¬λ₯Ό μ€μ μ§μ€ννμ¬ λ λμ μ½λ ꡬμ±μ μ΄μ§ν©λλ€. μ΄λ₯Ό ν΅ν΄ μ ν리μΌμ΄μ μ μμ‘΄μ±μ λ μ½κ² μ΄ν΄νκ³ μ¬λ¬ λͺ¨λμ κ±Έμ³ μΌκ΄μ± μκ² κ΄λ¦¬ν μ μμ΅λλ€.
λ²μ μ μ΄ λ° λ‘€λ°±
μν¬νΈ λ§΅μ μ¬μ©νλ©΄ λΌμ΄λΈλ¬λ¦¬μ μ¬λ¬ λ²μ κ°μ κ°λ¨νκ² μ νν μ μμ΅λλ€. λΌμ΄λΈλ¬λ¦¬μ μ λ²μ μ λ²κ·Έκ° λ°μνλ©΄ μν¬νΈ λ§΅ μ€μ λ§ μ λ°μ΄νΈνμ¬ μ΄μ λ²μ μΌλ‘ μ μνκ² λλ릴 μ μμ΅λλ€. μ΄λ μμ‘΄μ± κ΄λ¦¬λ₯Ό μν μμ λ§μ μ 곡νκ³ μ ν리μΌμ΄μ μ λΈλ μ΄νΉ 체μΈμ§(breaking changes)κ° λμ λ μνμ μ€μ¬μ€λλ€.
νκ²½μ ꡬμ λ°μ§ μλ κ°λ°
μ μ€νκ² μ€κ³νλ©΄ μν¬νΈ λ§΅μ νκ²½μ ꡬμ λ°μ§ μλ μ½λλ₯Ό λ§λλ λ° λμμ΄ λ μ μμ΅λλ€. κ°λ°, νλ‘λμ λ± λ€μν νκ²½μ λν΄ μλ‘ λ€λ₯Έ μν¬νΈ λ§΅μ μ¬μ©νμ¬ λμ νκ²½μ λ°λΌ λ€λ₯Έ λͺ¨λμ΄λ λͺ¨λ λ²μ μ λ‘λν μ μμ΅λλ€. μ΄λ μ½λ 곡μ λ₯Ό μ©μ΄νκ² νκ³ νκ²½λ³ μ½λμ νμμ±μ μ€μ¬μ€λλ€.
μν¬νΈ λ§΅ μ€μ λ°©λ²
μν¬νΈ λ§΅μ HTML νμΌμ <script type="importmap"> νκ·Έ μμ μμΉνλ JSON κ°μ²΄μ
λλ€. κΈ°λ³Έ ꡬ쑰λ λ€μκ³Ό κ°μ΅λλ€:
<script type="importmap">
{
"imports": {
"module-name": "/path/to/module.js",
"another-module": "https://cdn.example.com/another-module.js"
}
}
</script>
imports μμ±μ import λ¬Έμ μ¬μ©νλ λͺ¨λ μ§μ μλ₯Ό ν€λ‘, ν΄λΉ λͺ¨λ νμΌμ URL λλ κ²½λ‘λ₯Ό κ°μΌλ‘ κ°λ κ°μ²΄μ
λλ€. λͺ κ°μ§ μ€μ μμ λ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€.
μμ 1: λ² μ΄ λͺ¨λ μ§μ μ λ§€ν
νλ‘μ νΈμμ Lodash λΌμ΄λΈλ¬λ¦¬λ₯Ό λ‘컬μ μ€μΉνμ§ μκ³ μ¬μ©νκ³ μΆλ€κ³ κ°μ ν΄ λ΄
μλ€. λ² μ΄ λͺ¨λ μ§μ μ lodashλ₯Ό Lodash λΌμ΄λΈλ¬λ¦¬μ CDN URLμ λ§€νν μ μμ΅λλ€:
<script type="importmap">
{
"imports": {
"lodash": "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"
}
}
</script>
<script type="module">
import _ from 'lodash';
console.log(_.shuffle([1, 2, 3, 4, 5]));
</script>
μ΄ μμ μμ μν¬νΈ λ§΅μ λΈλΌμ°μ κ° import _ from 'lodash'; λ¬Έμ λ§λ¬μ λ μ§μ λ CDN URLμμ Lodash λΌμ΄λΈλ¬λ¦¬λ₯Ό λ‘λνλλ‘ μ§μν©λλ€.
μμ 2: μλ κ²½λ‘ λ§€ν
μν¬νΈ λ§΅μ μ¬μ©νμ¬ λͺ¨λ μ§μ μλ₯Ό νλ‘μ νΈ λ΄μ μλ κ²½λ‘μ λ§€νν μλ μμ΅λλ€:
<script type="importmap">
{
"imports": {
"my-module": "./modules/my-module.js"
}
}
</script>
<script type="module">
import myModule from 'my-module';
myModule.doSomething();
</script>
μ΄ κ²½μ°, μν¬νΈ λ§΅μ λͺ¨λ μ§μ μ my-moduleμ HTML νμΌμ κΈ°μ€μΌλ‘ μλμ μΈ μμΉμ μλ ./modules/my-module.js νμΌμ λ§€νν©λλ€.
μμ 3: κ²½λ‘λ₯Ό μ¬μ©ν λͺ¨λ μ€μ½ν
μν¬νΈ λ§΅μ κ²½λ‘ μ λμ¬λ₯Ό κΈ°λ°μΌλ‘ ν λ§€νλ νμ©νμ¬ νΉμ λλ ν 리 λ΄μ λͺ¨λ κ·Έλ£Ήμ μ μνλ λ°©λ²μ μ 곡ν©λλ€. μ΄λ λͺ νν λͺ¨λ ꡬ쑰λ₯Ό κ°μ§ λκ·λͺ¨ νλ‘μ νΈμ νΉν μ μ©ν μ μμ΅λλ€.
<script type="importmap">
{
"imports": {
"utils/": "./utils/",
"lodash": "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"
}
}
</script>
<script type="module">
import arrayUtils from 'utils/array-utils.js';
import dateUtils from 'utils/date-utils.js';
import _ from 'lodash';
console.log(arrayUtils.unique([1, 2, 2, 3]));
console.log(dateUtils.formatDate(new Date()));
console.log(_.shuffle([1, 2, 3]));
</script>
μ¬κΈ°μ, "utils/": "./utils/"λ λΈλΌμ°μ μκ² utils/λ‘ μμνλ λͺ¨λ λͺ¨λ μ§μ μκ° ./utils/ λλ ν 리λ₯Ό κΈ°μ€μΌλ‘ ν΄μλμ΄μΌ ν¨μ μ립λλ€. λ°λΌμ, import arrayUtils from 'utils/array-utils.js';λ ./utils/array-utils.jsλ₯Ό λ‘λν©λλ€. lodash λΌμ΄λΈλ¬λ¦¬λ μ¬μ ν CDNμμ λ‘λλ©λλ€.
κ³ κΈ μν¬νΈ λ§΅ κΈ°μ
κΈ°λ³Έμ μΈ μ€μ μ λμ΄, μν¬νΈ λ§΅μ λ 볡μ‘ν μλ리μ€λ₯Ό μν κ³ κΈ κΈ°λ₯μ μ 곡ν©λλ€.
μ€μ½ν(Scopes)
μ€μ½νλ₯Ό μ¬μ©νλ©΄ μ ν리μΌμ΄μ
μ μ¬λ¬ λΆλΆμ λν΄ μλ‘ λ€λ₯Έ μν¬νΈ λ§΅μ μ μν μ μμ΅λλ€. μ΄λ μλ‘ λ€λ₯Έ μμ‘΄μ±μ΄λ λμΌν μμ‘΄μ±μ λ€λ₯Έ λ²μ μ νμλ‘ νλ μ¬λ¬ λͺ¨λμ΄ μμ λ μ μ©ν©λλ€. μ€μ½νλ μν¬νΈ λ§΅μ scopes μμ±μ μ¬μ©νμ¬ μ μλ©λλ€.
<script type="importmap">
{
"imports": {
"lodash": "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"
},
"scopes": {
"./admin/": {
"lodash": "https://cdn.jsdelivr.net/npm/lodash@3.0.0/lodash.min.js",
"admin-module": "./admin/admin-module.js"
}
}
}
</script>
<script type="module">
import _ from 'lodash'; // lodash@4.17.21 λ²μ μ λ‘λν©λλ€
console.log(_.VERSION);
</script>
<script type="module">
import _ from './admin/admin-module.js'; // admin-module λ΄λΆμμ lodash@3.0.0 λ²μ μ λ‘λν©λλ€
console.log(_.VERSION);
</script>
μ΄ μμ μμ μν¬νΈ λ§΅μ ./admin/ λλ ν 리 λ΄μ λͺ¨λμ λν μ€μ½νλ₯Ό μ μν©λλ€. μ΄ λλ ν 리 λ΄μ λͺ¨λμ λλ ν 리 λ°μ λͺ¨λ(4.17.21)κ³Όλ λ€λ₯Έ λ²μ μ Lodash(3.0.0)λ₯Ό μ¬μ©νκ² λ©λλ€. μ΄λ μ€λλ λΌμ΄λΈλ¬λ¦¬ λ²μ μ μμ‘΄νλ λ κ±°μ μ½λλ₯Ό λ§μ΄κ·Έλ μ΄μ
ν λ λ§€μ° μ μ©ν©λλ€.
μΆ©λνλ μμ‘΄μ± λ²μ ν΄κ²° (λ€μ΄μλͺ¬λ μμ‘΄μ± λ¬Έμ )
λ€μ΄μλͺ¬λ μμ‘΄μ± λ¬Έμ λ νλ‘μ νΈκ° μ¬λ¬ μμ‘΄μ±μ κ°μ§κ³ μκ³ , μ΄ μμ‘΄μ±λ€μ΄ λ€μ λμΌν νμ μμ‘΄μ±μ λ€λ₯Έ λ²μ μ μμ‘΄ν λ λ°μν©λλ€. μ΄λ μΆ©λκ³Ό μκΈ°μΉ μμ λμμΌλ‘ μ΄μ΄μ§ μ μμ΅λλ€. μ€μ½νκ° μλ μν¬νΈ λ§΅μ μ΄λ¬ν λ¬Έμ λ₯Ό μννλ κ°λ ₯ν λꡬμ λλ€.
νλ‘μ νΈκ° λ κ°μ λΌμ΄λΈλ¬λ¦¬ Aμ Bμ μμ‘΄νλ€κ³ μμν΄ λ³΄μΈμ. λΌμ΄λΈλ¬λ¦¬ Aλ λΌμ΄λΈλ¬λ¦¬ Cμ λ²μ 1.0μ νμλ‘ νκ³ , λΌμ΄λΈλ¬λ¦¬ Bλ λΌμ΄λΈλ¬λ¦¬ Cμ λ²μ 2.0μ νμλ‘ ν©λλ€. μν¬νΈ λ§΅μ΄ μλ€λ©΄, λ λΌμ΄λΈλ¬λ¦¬κ° κ°κ°μ C λ²μ μ μ¬μ©νλ €κ³ ν λ μΆ©λμ΄ λ°μν μ μμ΅λλ€.
μν¬νΈ λ§΅κ³Ό μ€μ½νλ₯Ό μ¬μ©νλ©΄ κ° λΌμ΄λΈλ¬λ¦¬μ μμ‘΄μ±μ 격리νμ¬ μ¬λ°λ₯Έ λ²μ μ λΌμ΄λΈλ¬λ¦¬ Cλ₯Ό μ¬μ©νλλ‘ λ³΄μ₯ν μ μμ΅λλ€. μλ₯Ό λ€μ΄:
<script type="importmap">
{
"imports": {
"library-a": "./library-a.js",
"library-b": "./library-b.js"
},
"scopes": {
"./library-a/": {
"library-c": "https://cdn.example.com/library-c-1.0.js"
},
"./library-b/": {
"library-c": "https://cdn.example.com/library-c-2.0.js"
}
}
}
</script>
<script type="module">
import libraryA from 'library-a';
import libraryB from 'library-b';
libraryA.useLibraryC(); // library-c λ²μ 1.0 μ¬μ©
libraryB.useLibraryC(); // library-c λ²μ 2.0 μ¬μ©
</script>
μ΄ μ€μ μ library-a.jsμ κ·Έ λλ ν 리 λ΄μμ μν¬νΈνλ λͺ¨λ λͺ¨λμ΄ νμ library-cλ₯Ό λ²μ 1.0μΌλ‘ ν΄μνκ³ , library-b.jsμ κ·Έ λͺ¨λλ€μ library-cλ₯Ό λ²μ 2.0μΌλ‘ ν΄μνλλ‘ λ³΄μ₯ν©λλ€.
ν΄λ°±(Fallback) URL
κ²¬κ³ μ±μ λνκΈ° μν΄ λͺ¨λμ λν ν΄λ°± URLμ μ§μ ν μ μμ΅λλ€. μ΄λ λΈλΌμ°μ κ° μ¬λ¬ μμΉμμ λͺ¨λ λ‘λλ₯Ό μλν μ μκ² νμ¬ ν μμΉλ₯Ό μ¬μ©ν μ μλ κ²½μ° μ€λ³΅μ±μ μ 곡ν©λλ€. μ΄λ μν¬νΈ λ§΅μ μ§μ μ μΈ κΈ°λ₯μ μλμ§λ§, λμ μν¬νΈ λ§΅ μμ μ ν΅ν΄ λ¬μ±ν μ μλ ν¨ν΄μ λλ€.
μλ°μ€ν¬λ¦½νΈλ‘ μ΄λ₯Ό λ¬μ±ν μ μλ κ°λ μ μΈ μλ λ€μκ³Ό κ°μ΅λλ€:
async function loadWithFallback(moduleName, urls) {
for (const url of urls) {
try {
const importMap = {
"imports": { [moduleName]: url }
};
// λμ μΌλ‘ μν¬νΈ λ§΅ μΆκ° λλ μμ
const script = document.createElement('script');
script.type = 'importmap';
script.textContent = JSON.stringify(importMap);
document.head.appendChild(script);
return await import(moduleName);
} catch (error) {
console.warn(`${moduleName}μ(λ₯Ό) ${url}μμ λ‘λνλ λ° μ€ν¨νμ΅λλ€:`, error);
// λ‘λ μ€ν¨ μ μμ μν¬νΈ λ§΅ νλͺ© μ κ±°
document.head.removeChild(script);
}
}
throw new Error(`${moduleName}μ(λ₯Ό) μ 곡λ URL μ€ μ΄λ κ³³μμλ λ‘λνμ§ λͺ»νμ΅λλ€.`);
}
// μ¬μ©λ²:
loadWithFallback('my-module', [
'https://cdn.example.com/my-module.js',
'./local-backup/my-module.js'
]).then(module => {
module.doSomething();
}).catch(error => {
console.error("λͺ¨λ λ‘λ© μ€ν¨:", error);
});
μ΄ μ½λλ λͺ¨λ μ΄λ¦κ³Ό URL λ°°μ΄μ μ
λ ₯μΌλ‘ λ°λ loadWithFallback ν¨μλ₯Ό μ μν©λλ€. λ°°μ΄μ κ° URLμμ ν λ²μ νλμ© λͺ¨λ λ‘λλ₯Ό μλν©λλ€. νΉμ URLμμ λ‘λμ μ€ν¨νλ©΄ κ²½κ³ λ₯Ό κΈ°λ‘νκ³ λ€μ URLμ μλν©λλ€. λͺ¨λ URLμμ λ‘λμ μ€ν¨νλ©΄ μ€λ₯λ₯Ό λ°μμν΅λλ€.
λΈλΌμ°μ μ§μ λ° ν΄λ¦¬ν
μν¬νΈ λ§΅μ μ΅μ λΈλΌμ°μ μ λ°μ κ±Έμ³ νλ₯ν λΈλΌμ°μ μ§μμ μ 곡ν©λλ€. νμ§λ§ ꡬν λΈλΌμ°μ μμλ λ€μ΄ν°λΈλ‘ μ§μνμ§ μμ μ μμ΅λλ€. μ΄λ° κ²½μ°, ν΄λ¦¬νμ μ¬μ©νμ¬ μν¬νΈ λ§΅ κΈ°λ₯μ μ 곡ν μ μμ΅λλ€. ꡬν λΈλΌμ°μ μμ μν¬νΈ λ§΅μ κ°λ ₯νκ² μ§μνλ es-module-shimsμ κ°μ μ¬λ¬ ν΄λ¦¬νμ΄ μμ΅λλ€.
Node.jsμμ ν΅ν©
μν¬νΈ λ§΅μ μ΄κΈ°μ λΈλΌμ°μ μ©μΌλ‘ μ€κ³λμμ§λ§, Node.js νκ²½μμλ μΈκΈ°λ₯Ό μ»κ³ μμ΅λλ€. Node.jsλ --experimental-import-maps νλκ·Έλ₯Ό ν΅ν΄ μν¬νΈ λ§΅μ λν μ€νμ μ§μμ μ 곡ν©λλ€. μ΄λ₯Ό ν΅ν΄ λΈλΌμ°μ μ Node.js μ½λ λͺ¨λμ λμΌν μν¬νΈ λ§΅ μ€μ μ μ¬μ©ν μ μμ΄ μ½λ 곡μ λ₯Ό μ΄μ§νκ³ νκ²½λ³ μ€μ μ νμμ±μ μ€μΌ μ μμ΅λλ€.
Node.jsμμ μν¬νΈ λ§΅μ μ¬μ©νλ €λ©΄ μν¬νΈ λ§΅ μ€μ μ΄ ν¬ν¨λ JSON νμΌ(μ: importmap.json)μ λ§λ€μ΄μΌ ν©λλ€. κ·Έλ° λ€μ, --experimental-import-maps νλκ·Έμ μν¬νΈ λ§΅ νμΌμ κ²½λ‘λ₯Ό μ¬μ©νμ¬ Node.js μ€ν¬λ¦½νΈλ₯Ό μ€νν μ μμ΅λλ€:
node --experimental-import-maps importmap.json your-script.js
μ΄λ Node.jsμκ² your-script.jsμ λͺ¨λ μ§μ μλ₯Ό ν΄μνκΈ° μν΄ importmap.jsonμ μ μλ μν¬νΈ λ§΅μ μ¬μ©νλλ‘ μ§μν©λλ€.
μν¬νΈ λ§΅ μ¬μ©μ μν λͺ¨λ² μ¬λ‘
μν¬νΈ λ§΅μ μ΅λν νμ©νλ €λ©΄ λ€μ λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄μμμ€:
- μν¬νΈ λ§΅μ κ°κ²°νκ² μ μ§: λΆνμν λ§€νμ μν¬νΈ λ§΅μ ν¬ν¨νμ§ λ§μμμ€. μ ν리μΌμ΄μ μμ μ€μ λ‘ μ¬μ©νλ λͺ¨λλ§ λ§€ννμμμ€.
- μ€λͺ μ μΈ λͺ¨λ μ§μ μ μ¬μ©: λͺ ννκ³ μ€λͺ μ μΈ λͺ¨λ μ§μ μλ₯Ό μ ννμμμ€. μ΄λ κ² νλ©΄ μ½λλ₯Ό λ μ½κ² μ΄ν΄νκ³ μ μ§λ³΄μν μ μμ΅λλ€.
- μν¬νΈ λ§΅ κ΄λ¦¬ μ€μν: μ μ© νμΌμ΄λ μ€μ λ³μμ κ°μ μ€μ μμΉμ μν¬νΈ λ§΅μ μ μ₯νμμμ€. μ΄λ κ² νλ©΄ μν¬νΈ λ§΅μ λ μ½κ² κ΄λ¦¬νκ³ μ λ°μ΄νΈν μ μμ΅λλ€.
- λ²μ κ³ μ μ¬μ©: μν¬νΈ λ§΅μμ μμ‘΄μ±μ νΉμ λ²μ μ κ³ μ νμμμ€. μ΄λ μλ μ λ°μ΄νΈλ‘ μΈν μκΈ°μΉ μμ λμμ λ°©μ§ν©λλ€. μ μμ λ²μ (semver) λ²μλ μ μ€νκ² μ¬μ©νμμμ€.
- μν¬νΈ λ§΅ ν μ€νΈ: μν¬νΈ λ§΅μ΄ μ¬λ°λ₯΄κ² μλνλμ§ μ² μ ν ν μ€νΈνμμμ€. μ΄λ₯Ό ν΅ν΄ μ€λ₯λ₯Ό μ‘°κΈ°μ λ°κ²¬νκ³ νλ‘λμ μμ λ¬Έμ λ₯Ό μλ°©ν μ μμ΅λλ€.
- μν¬νΈ λ§΅ μμ± λ° κ΄λ¦¬ λꡬ μ¬μ© κ³ λ €: λκ·λͺ¨ νλ‘μ νΈμ κ²½μ°, μν¬νΈ λ§΅μ μλμΌλ‘ μμ±νκ³ κ΄λ¦¬ν μ μλ λꡬλ₯Ό μ¬μ©νλ κ²μ κ³ λ €νμμμ€. μ΄λ μκ°κ³Ό λ Έλ ₯μ μ μ½νκ³ μ€λ₯λ₯Ό λ°©μ§νλ λ° λμμ΄ λ μ μμ΅λλ€.
μν¬νΈ λ§΅μ λμ
μν¬νΈ λ§΅μ΄ λͺ¨λ ν΄μμ μν κ°λ ₯ν μ루μ μ μ 곡νμ§λ§, λμμ μΈμ§νκ³ μ΄λ€ κ²½μ°μ λ μ ν©ν μ μλμ§ μλ κ²μ΄ μ€μν©λλ€.
λ²λ€λ¬ (Webpack, Parcel, Rollup)
λ²λ€λ¬λ 볡μ‘ν μΉ μ ν리μΌμ΄μ μμ μ¬μ ν μ§λ°°μ μΈ μ κ·Ό λ°©μμ λλ€. λ€μκ³Ό κ°μ μμ μ νμν©λλ€:
- μ½λ μ΅μ ν: μ΅μν(Minification), νΈλ¦¬ μμ΄νΉ(μ¬μ©νμ§ μλ μ½λ μ κ±°), μ½λ λΆν .
- νΈλμ€νμΌλ§: λΈλΌμ°μ νΈνμ±μ μν΄ μ΅μ μλ°μ€ν¬λ¦½νΈ(ES6+)λ₯Ό ꡬλ²μ μΌλ‘ λ³ν.
- μμ° κ΄λ¦¬: μλ°μ€ν¬λ¦½νΈμ ν¨κ» CSS, μ΄λ―Έμ§ λ° κΈ°ν μμ° μ²λ¦¬.
λ²λ€λ¬λ κ΄λ²μν μ΅μ νμ νλμ λΈλΌμ°μ νΈνμ±μ΄ νμν νλ‘μ νΈμ μ΄μμ μ λλ€. κ·Έλ¬λ λΉλ λ¨κ³λ₯Ό λμ νμ¬ κ°λ° μκ°κ³Ό 볡μ‘μ±μ μ¦κ°μν¬ μ μμ΅λλ€. κ°λ¨ν νλ‘μ νΈμ κ²½μ° λ²λ€λ¬μ μ€λ²ν€λκ° λΆνμν μ μμΌλ―λ‘ μν¬νΈ λ§΅μ΄ λ μ ν©ν©λλ€.
ν¨ν€μ§ κ΄λ¦¬μ (npm, Yarn, pnpm)
ν¨ν€μ§ κ΄λ¦¬μλ μμ‘΄μ± κ΄λ¦¬μλ λ°μ΄λμ§λ§, λΈλΌμ°μ μμ μ§μ λͺ¨λ ν΄μμ μ²λ¦¬νμ§λ μμ΅λλ€. npmμ΄λ Yarnμ μ¬μ©νμ¬ μμ‘΄μ±μ μ€μΉν μλ μμ§λ§, μ΄λ¬ν μμ‘΄μ±μ λΈλΌμ°μ μμ μ¬μ©ν μ μκ² νλ €λ©΄ μ¬μ ν λ²λ€λ¬λ μν¬νΈ λ§΅μ΄ νμν©λλ€.
Deno
Denoλ λͺ¨λκ³Ό μν¬νΈ λ§΅μ λ΄μ₯ μ§μνλ μλ°μ€ν¬λ¦½νΈ λ° νμ μ€ν¬λ¦½νΈ λ°νμμ λλ€. Denoμ λͺ¨λ ν΄μ μ κ·Ό λ°©μμ μν¬νΈ λ§΅κ³Ό μ μ¬νμ§λ§ λ°νμμ μ§μ ν΅ν©λμ΄ μμ΅λλ€. Denoλ λν 보μμ μ°μ μνλ©° Node.jsμ λΉν΄ λ νλμ μΈ κ°λ° κ²½νμ μ 곡ν©λλ€.
μ€μ μ¬λ‘ λ° μ¬μ© μ¬λ‘
μν¬νΈ λ§΅μ λ€μν κ°λ° μλ리μ€μμ μ€μ©μ μΈ μ©λλ₯Ό μ°Ύκ³ μμ΅λλ€. λͺ κ°μ§ μμλ λ€μκ³Ό κ°μ΅λλ€:
- λ§μ΄ν¬λ‘ νλ‘ νΈμλ: λ§μ΄ν¬λ‘ νλ‘ νΈμλ μν€ν μ²λ₯Ό μ¬μ©ν λ μν¬νΈ λ§΅μ μ μ©ν©λλ€. κ° λ§μ΄ν¬λ‘ νλ‘ νΈμλλ μ체 μν¬νΈ λ§΅μ κ°μ§ μ μμ΄ μμ‘΄μ±μ λ 립μ μΌλ‘ κ΄λ¦¬ν μ μμ΅λλ€.
- νλ‘ν νμ΄ν λ° μ μν κ°λ°: λΉλ νλ‘μΈμ€μ μ€λ²ν€λ μμ΄ λ€μν λΌμ΄λΈλ¬λ¦¬μ νλ μμν¬λ₯Ό μ μνκ² μ€νν©λλ€.
- λ κ±°μ μ½λλ² μ΄μ€ λ§μ΄κ·Έλ μ΄μ : κΈ°μ‘΄ λͺ¨λ μ§μ μλ₯Ό μ λͺ¨λ URLμ λ§€ννμ¬ λ κ±°μ μ½λλ² μ΄μ€λ₯Ό μ μ§μ μΌλ‘ ES λͺ¨λλ‘ μ νν©λλ€.
- λμ λͺ¨λ λ‘λ©: μ¬μ©μ μνΈ μμ©μ΄λ μ ν리μΌμ΄μ μνμ λ°λΌ λͺ¨λμ λμ μΌλ‘ λ‘λνμ¬ μ±λ₯μ κ°μ νκ³ μ΄κΈ° λ‘λ μκ°μ μ€μ λλ€.
- A/B ν μ€νΈ: A/B ν μ€νΈ λͺ©μ μΌλ‘ λͺ¨λμ μ¬λ¬ λ²μ κ°μ μ½κ² μ νν©λλ€.
μμ : κΈλ‘λ² μ΄μ»€λ¨Έμ€ νλ«νΌ
μ¬λ¬ ν΅νμ μΈμ΄λ₯Ό μ§μν΄μΌ νλ κΈλ‘λ² μ΄μ»€λ¨Έμ€ νλ«νΌμ μκ°ν΄ 보μΈμ. μ¬μ©μμ μμΉμ λ°λΌ λ‘μΌμΌλ³ λͺ¨λμ λμ μΌλ‘ λ‘λνκΈ° μν΄ μν¬νΈ λ§΅μ μ¬μ©ν μ μμ΅λλ€. μλ₯Ό λ€λ©΄ λ€μκ³Ό κ°μ΅λλ€:
// μ¬μ©μμ λ‘μΌμΌμ λμ μΌλ‘ κ²°μ (μ: μΏ ν€ λλ APIμμ)
const userLocale = 'fr-FR';
// μ¬μ©μμ λ‘μΌμΌμ λν μν¬νΈ λ§΅ μμ±
const importMap = {
"imports": {
"currency-formatter": `/locales/${userLocale}/currency-formatter.js`,
"date-formatter": `/locales/${userLocale}/date-formatter.js"
}
};
// νμ΄μ§μ μν¬νΈ λ§΅ μΆκ°
const script = document.createElement('script');
script.type = 'importmap';
script.textContent = JSON.stringify(importMap);
document.head.appendChild(script);
// μ΄μ λ‘μΌμΌλ³ λͺ¨λμ μν¬νΈν μ μμ΅λλ€
import('currency-formatter').then(formatter => {
console.log(formatter.formatCurrency(1000, 'EUR')); // νλμ€ λ‘μΌμΌμ λ°λΌ ν΅ν μμ μ§μ
});
κ²°λ‘
μν¬νΈ λ§΅μ μλ°μ€ν¬λ¦½νΈ λͺ¨λ ν΄μμ μ μ΄νλ κ°λ ₯νκ³ μ μ°ν λ©μ»€λμ¦μ μ 곡ν©λλ€. κ°λ° μν¬νλ‘μ°λ₯Ό λ¨μννκ³ , μ±λ₯μ κ°μ νλ©°, μ½λ ꡬμ±μ ν₯μμν€κ³ , μ½λμ μ΄μμ±μ λμ¬μ€λλ€. λ²λ€λ¬κ° 볡μ‘ν μ ν리μΌμ΄μ μ μ¬μ ν νμμ μ΄μ§λ§, μν¬νΈ λ§΅μ λ κ°λ¨ν νλ‘μ νΈ λ° νΉμ μ¬μ© μ¬λ‘μ λν κ°μΉ μλ λμμ μ 곡ν©λλ€. μ΄ κ°μ΄λμμ μ€λͺ ν μμΉκ³Ό κΈ°μ μ μ΄ν΄ν¨μΌλ‘μ¨, μν¬νΈ λ§΅μ νμ©νμ¬ κ²¬κ³ νκ³ μ μ§λ³΄μ κ°λ₯νλ©° νμ₯ κ°λ₯ν μλ°μ€ν¬λ¦½νΈ μ ν리μΌμ΄μ μ ꡬμΆν μ μμ΅λλ€.
μΉ κ°λ° νκ²½μ΄ κ³μ λ°μ ν¨μ λ°λΌ, μν¬νΈ λ§΅μ μλ°μ€ν¬λ¦½νΈ λͺ¨λ κ΄λ¦¬μ λ―Έλλ₯Ό νμ±νλ λ° μ μ λ μ€μν μν μ ν κ²μ λλ€. μ΄ κΈ°μ μ μμ©νλ©΄ λ κΉ¨λνκ³ , λ ν¨μ¨μ μ΄λ©°, λ μ μ§λ³΄μνκΈ° μ¬μ΄ μ½λλ₯Ό μμ±ν μ μκ² λμ΄, κΆκ·Ήμ μΌλ‘ λ λμ μ¬μ©μ κ²½νκ³Ό λ μ±κ³΅μ μΈ μΉ μ ν리μΌμ΄μ μΌλ‘ μ΄μ΄μ§ κ²μ λλ€.