๐์ด ๊ธ์ ๋ด์ฉ ์ค ์ค์ํ ๋ถ๋ถ์ ํ์ํ๋ฉฐ ์ดํดํ๊ธฐ ์ฝ๊ฒ ์ฒจ์ธํ ๊ธ์ ๋๋ค.
๐DOMContentLoaded, load, beforeunload, unload ์ด๋ฒคํธ ๊ทธ๋ฆฌ๊ณ defer, async ํ ๋ฒ์ ์ดํดํ๊ธฐ ๊ธ๊ณผ ์ด์ด์ง๋ ๋ด์ฉ์ ๋๋ค.

๋ชจ๋ ์๊ฐ
๊ฐ๋ฐํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํฌ๊ธฐ๊ฐ ์ปค์ง๋ฉด ์ธ์ ๊ฐ ํ์ผ์ ์ฌ๋ฌ ๊ฐ๋ก ๋ถ๋ฆฌํด์ผ ํ๋ ์์ ์ด ์ต๋๋ค. ์ด๋ ๋ถ๋ฆฌ๋ ํ์ผ ๊ฐ๊ฐ์ '๋ชจ๋(module)'์ด๋ผ๊ณ ๋ถ๋ฅด๋๋ฐ, ๋ชจ๋์ ๋๊ฐ ํด๋์ค ํ๋ ํน์ ํน์ ํ ๋ชฉ์ ์ ๊ฐ์ง ๋ณต์์ ํจ์๋ก ๊ตฌ์ฑ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ๋๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋์ ํ์ผ ๋จ์๋ก ๋ถ๋ฆฌ๋์ด ์์ผ๋ฉฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์์ ๋ฐ๋ผ ๋ช ์์ ์ผ๋ก ๋ชจ๋์ ๋ก๋ํ์ฌ ์ฌ์ฌ์ฉํฉ๋๋ค. ์ฆ, ๋ชจ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ถ๋ฆฌ๋์ด ๊ฐ๋ณ์ ์ผ๋ก ์กด์ฌํ๋ค๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ก๋์ ์ํด ๋น๋ก์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ผ์์ด ๋ฉ๋๋ค. ๋ชจ๋์ ๊ธฐ๋ฅ๋ณ๋ก ๋ถ๋ฆฌ๋์ด ์์ฑ๋๋ฏ๋ก ์ฝ๋์ ๋จ์๋ฅผ ๋ช ํํ ๋ถ๋ฆฌํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ฑํ ์ ์์ผ๋ฉฐ ์ฌ์ฌ์ฉ์ฑ์ด ์ข์์ ๊ฐ๋ฐ ํจ์จ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ง๋ค์ด์ง ์ง ์ผ๋ง ์ ๋์์ ๋๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ง๋ ์คํฌ๋ฆฝํธ์ ํฌ๊ธฐ๋ ์๊ณ ๊ธฐ๋ฅ๋ ๋จ์ํ๊ธฐ ๋๋ฌธ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ ๊ธด ์ธ์ ๋์ ๋ชจ๋ ๊ด๋ จ ํ์ค ๋ฌธ๋ฒ ์์ด ์ฑ์ฅํ ์ ์์์ต๋๋ค. ์๋ก์ด ๋ฌธ๋ฒ์ ๋ง๋ค ํ์๊ฐ ์์๋ ๊ฒ์ด์ฃ .
๊ทธ๋ฐ๋ฐ ์คํฌ๋ฆฝํธ์ ํฌ๊ธฐ๊ฐ ์ ์ฐจ ์ปค์ง๊ณ ๊ธฐ๋ฅ๋ ๋ณต์กํด์ง์ ์๋ฐ์คํฌ๋ฆฝํธ ์ปค๋ฎค๋ํฐ๋ ํน๋ณํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค์ด ํ์ํ ๋ชจ๋์ ์ธ์ ๋ ์ง ๋ถ๋ฌ์ฌ ์ ์๊ฒ ํด์ค๋ค๊ฑฐ๋ ์ฝ๋๋ฅผ ๋ชจ๋ ๋จ์๋ก ๊ตฌ์ฑํด ์ฃผ๋ ๋ฐฉ๋ฒ์ ๋ง๋๋ ๋ฑ ๋ค์ํ ์๋๋ฅผ ํ๊ฒ ๋ฉ๋๋ค.
๊ทธ ์๋๋ ๋ค์๊ณผ ๊ฐ์ ๋ชจ๋ ์์คํ ์ผ๋ก ์ด์ด์ก์ต๋๋ค.
- `AMD` – ๊ฐ์ฅ ์ค๋๋ ๋ชจ๋ ์์คํ ์ค ํ๋๋ก require.js๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ฒ์ ๊ฐ๋ฐ๋์์ต๋๋ค.
- `CommonJS` – Node.js ์๋ฒ๋ฅผ ์ํด ๋ง๋ค์ด์ง ๋ชจ๋ ์์คํ ์ ๋๋ค.
- `UMD` – AMD์ CommonJS์ ๊ฐ์ ๋ค์ํ ๋ชจ๋ ์์คํ ์ ํจ๊ป ์ฌ์ฉํ๊ธฐ ์ํด ๋ง๋ค์ด์ก์ต๋๋ค.
์ด๋ฐ ๋ชจ๋ ์์คํ
์ ์ค๋๋ ์คํฌ๋ฆฝํธ์์ ์ฌ์ ํ ๋ฐ๊ฒฌํ ์ ์๋๋ฐ, ์ด์ ๋ ์ญ์ฌ์ ๋ค์๊ธธ๋ก ์ฌ๋ผ์ ธ๊ฐ๊ณ ์์ต๋๋ค.
๋ชจ๋ ์์คํ
์ 2015๋
์ ํ์ค์ผ๋ก ๋ฑ์ฌ๋์์ต๋๋ค. ์ด ์ดํ๋ก ๊ด๋ จ ๋ฌธ๋ฒ์ ์งํ๋ฅผ ๊ฑฐ๋ญํด ์ด์ ๋ ๋๋ถ๋ถ์ ์ฃผ์ ๋ธ๋ผ์ฐ์ ์ Node.js๊ฐ ๋ชจ๋ ์์คํ
์ ์ง์ํ๊ณ ์์ต๋๋ค. ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฐ์ด๋ ๋ชจ๋์ ๋ํด ์์๋ด
์๋ค.
๋ชจ๋์ด๋
๋ชจ๋์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ฑํ๋ ๊ฐ๋ณ์ ์์๋ก์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋ ์กฐ๊ฐ์ ์๋ฏธํฉ๋๋ค. ๋ชจ๋์ ์ธ๋ถ ์ฌํญ์ ์บก์ํํ๊ณ ๊ณต๊ฐ๊ฐ ํ์ํ API๋ง์ ์ธ๋ถ์ ๋ ธ์ถํฉ๋๋ค.

์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋์ ํ์ผ ๋จ์๋ก ๋ถ๋ฆฌ๋์ด ์์ต๋๋ค. ์คํฌ๋ฆฝํธ ํ๋๋ ๋ชจ๋ ํ๋์
๋๋ค.
๋ชจ๋์ ํน์ํ ์ง์์ `export`์ `import`๋ฅผ ์ ์ฉํ๋ฉด ๊ณต๊ฐ๋ ๋ค๋ฅธ ๋ชจ๋์ ๋ถ๋ฌ์ ๋ถ๋ฌ์จ ๋ชจ๋์ ์๋ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ ๊ณต์ ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- `export` ์ง์์๋ฅผ ๋ณ์๋ ํจ์ ์์ ๋ถ์ด๋ฉด ์ธ๋ถ ๋ชจ๋์์ ํด๋น ๋ณ์๋ ํจ์์ ์ ๊ทผํ ์ ์์ต๋๋ค(`๋ชจ๋ ๋ด๋ณด๋ด๊ธฐ`).
- `import` ์ง์์๋ฅผ ์ฌ์ฉํ๋ฉด ์ธ๋ถ ๋ชจ๋์ ๊ธฐ๋ฅ์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค(`๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ`).
`export` ์ง์์๋ฅผ ์ฌ์ฉํด ํ์ผ `sayHi.js` ๋ด๋ถ์ ํจ์ `sayHi`๋ฅผ ์ธ๋ถ๋ก ๋ด๋ณด๋ด ๋ด
์๋ค.
// ๐ sayHi.js
export function sayHi(user) {
alert(`Hello, ${user}!`);
}
์ด์ `import` ์ง์์๋ฅผ ์ฌ์ฉํด `main.js`์์ ํจ์ `sayHi`๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํด๋ด ์๋ค.
// ๐ main.js
import {sayHi} from './sayHi.js';
alert(sayHi); // ํจ์
sayHi('John'); // Hello, John!
์ ์์์์ `import` ์ง์์๋ ์๋ ๊ฒฝ๋ก(`./sayHi.js`) ๊ธฐ์ค์ผ๋ก ๋ชจ๋์ ๊ฐ์ ธ์ค๊ณ `sayHi.js`์์ ๋ด๋ณด๋ธ ํจ์ `sayHi`๋ฅผ ์์ํ๋ ๋ณ์์ ํ ๋นํฉ๋๋ค.
์ด์ ๋ธ๋ผ์ฐ์ ์์ ๋ชจ๋์ด ์ด๋ป๊ฒ ๋์ํ๋์ง ์์๋ฅผ ์ด์ฉํด ์์๋ด
์๋ค.
๋ชจ๋์ ํน์ํ ํค์๋๋ ๊ธฐ๋ฅ๊ณผ ํจ๊ป ์ฌ์ฉ๋๋ฏ๋ก `<script type="module">` ๊ฐ์ ์์ฑ์ ์ค์ ํด ํด๋น ์คํฌ๋ฆฝํธ๊ฐ ๋ชจ๋์ด๋ ๊ฑธ ๋ธ๋ผ์ฐ์ ๊ฐ ์ ์ ์๊ฒ ํด์ค์ผ ํฉ๋๋ค.
์๋์ ๊ฐ์ด ๋ง์ด์ฃ .
/* say.js */
export function sayHi(user) {
return `Hello, ${user}!`;
}
<!-- index.html -->
<!doctype html>
<script type="module">
import {sayHi} from './say.js';
document.body.innerHTML = sayHi('John');
</script>
๋ธ๋ผ์ฐ์ ๊ฐ ์๋์ผ๋ก ๋ชจ๋์ ๊ฐ์ ธ์ค๊ณ ํ๊ฐํ ๋ค์, ์ด๋ฅผ ์คํํ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
- ๋ชจ๋์ ๋ก์ปฌ ํ์ผ์์ ๋์ํ์ง ์๊ณ , HTTP ๋๋ HTTPS ํ๋กํ ์ฝ์ ํตํด์๋ง ๋์ํฉ๋๋ค.
๋ก์ปฌ์์ file:// ํ๋กํ ์ฝ์ ์ฌ์ฉํด ์นํ์ด์ง๋ฅผ ์ด๋ฉด import, export ์ง์์๊ฐ ๋์ํ์ง ์์ต๋๋ค. ์์๋ฅผ ์คํํ๋ ค๋ฉด ๋ก์ปฌ ์น ์๋ฒ์ธ static-server๋, ์ฝ๋ ์๋ํฐ์ ‘๋ผ์ด๋ธ ์๋ฒ’ ์ต์คํ ์ (Visual Studio Code ์๋ํฐ์ ๊ฒฝ์ฐ Live Server Extension)์ ์ฌ์ฉํ์ธ์.
๋ชจ๋์ ํต์ฌ ๊ธฐ๋ฅ
‘์ผ๋ฐ’ ์คํฌ๋ฆฝํธ์ ๋ชจ๋์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น์?
๋ชจ๋ ํธ์คํธ ํ๊ฒฝ์ ๊ณตํต์ผ๋ก ์ ์ฉ๋๋ ๋ชจ๋์ ํต์ฌ ๊ธฐ๋ฅ์ ๋ํด ์์๋ด
์๋ค.
์๊ฒฉ ๋ชจ๋๋ก ์คํ๋จ
๋ชจ๋์ ํญ์ ์๊ฒฉ ๋ชจ๋(use strict)๋ก ์คํ๋ฉ๋๋ค. ์ ์ธ๋์ง ์์ ๋ณ์์ ๊ฐ์ ํ ๋นํ๋ ๋ฑ์ ์ฝ๋๋ ์๋ฌ๋ฅผ ๋ฐ์์ํต๋๋ค.
<script type="module">
a = 5; // ์๋ฌ
</script>
๋ชจ๋ ๋ ๋ฒจ ์ค์ฝํ
๋ชจ๋์ ์์ ๋ง์ ์ค์ฝํ๊ฐ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ชจ๋ ๋ด๋ถ์์ ์ ์ํ ๋ณ์๋ ํจ์๋ ๋ค๋ฅธ ์คํฌ๋ฆฝํธ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
user.js์ hello.js๋ฅผ ๊ฐ์ ธ์ค๊ณ user.js์์ ์ ์ธํ ๋ณ์ user๋ฅผ hello.js์์ ์ฌ์ฉํด๋ด
์๋ค. ์๋ฌ๊ฐ ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค(๊ฐ๋ฐ์ ๋๊ตฌ ํ์ธ).
<!-- index.html -->
<!doctype html>
<script type="module" src="user.js"></script>
<script type="module" src="hello.js"></script>
/* user.js */
let user = "John";
/* hello.js */
alert(user); // ๋ชจ๋์ ๋ณ์๋ฅผ ๊ณต์ ํ์ง ์๊ธฐ ๋๋ฌธ์ `Uncaught ReferenceError: user is not defined`๋ผ๋ ์๋ฌ๊ฐ ์ฝ์ ํจ๋์ ์ถ๋ ฅ๋ฉ๋๋ค.
์ธ๋ถ์ ๊ณต๊ฐํ๋ ค๋ ๋ชจ๋์ `export` ํด์ผ ํ๊ณ , ๋ด๋ณด๋ด์ง ๋ชจ๋์ ๊ฐ์ ธ์ ์ฌ์ฉํ๋ ค๋ฉด `import` ํด์ค์ผ ํฉ๋๋ค.
์ ์ญ๋ณ์๋ฅผ ๋์ ํ์ฌ hello.js์ user.js๋ฅผ ๊ฐ์ ธ์ ํ์ํ ๊ธฐ๋ฅ์ ์ป์ ์ ์์ต๋๋ค.
์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ ํ๋ฉด ์ ์์ ์ผ๋ก ๋์ํฉ๋๋ค.(script๊ฐ ํ๋๋ก ์ค์ด๋ค์๋ค๋ ์ ๋ ์ธ์ง)
<!-- index.html -->
<!doctype html>
<script type="module" src="hello.js"></script>
/* user.js */
export let user = "John";
import {user} from './user.js';
document.body.innerHTML = user; // John
๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์๋ `<script type="module">`์ ์ฌ์ฉํด ๋ชจ๋์ ๋ง๋ค๋ฉด ๋ ๋ฆฝ์ ์ธ ์ค์ฝํ๊ฐ ๋ง๋ค์ด์ง๋๋ค.
<script type="module">
// user๋ ํด๋น ๋ชจ๋ ์์์๋ง ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
let user = "John";
</script>
<script type="module">
alert(user); // Error: user is not defined
</script>
์ฐธ๊ณ ๋ก ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ๋ถ๋์ดํ๊ฒ `window` ๋ ๋ฒจ ์ ์ญ ๋ณ์๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค๋ฉด `window` ๊ฐ์ฒด์ ๋ณ์๋ฅผ ๋ช ์์ ์ผ๋ก ํ ๋น(์๋ฅผ ๋ค์ด `window.user = John`)ํ๊ณ `window.user`์ ๊ฐ์ด ์ ๊ทผํ๋ ๋ฐฉ์์ ์ทจํ์๋ฉด ๋ฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๋ฐฉ๋ฒ์ ์ ๋ง ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ๊ธธ ๊ถ์ ํฉ๋๋ค.
๋จ ํ ๋ฒ๋ง ํ๊ฐ๋จ
๋์ผํ ๋ชจ๋์ด ์ฌ๋ฌ ๊ณณ์์ ์ฌ์ฉ๋๋๋ผ๋ ๋ชจ๋์ ์ต์ด ํธ์ถ ์ ๋จ ํ ๋ฒ๋ง ์คํ๋ฉ๋๋ค. ์คํ ํ ๊ฒฐ๊ณผ๋ ์ด ๋ชจ๋์ ๊ฐ์ ธ๊ฐ๋ ค๋ ๋ชจ๋ ๋ชจ๋์ ๋ด๋ณด๋ด ์ง๋๋ค.
์ด๋ฐ ์๋ ๋ฐฉ์์ ์ค์ํ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํฉ๋๋ค. ์์๋ฅผ ํตํด ์ด์ ๋ํด ์์๋ด
์๋ค.
alert ํจ์๊ฐ ์๋ ๋ชจ๋(alert.js)์ ์ฌ๋ฌ ๋ชจ๋์์ ๊ฐ์ ธ์ค๊ธฐ๋ก ํด๋ด
์๋ค. ์ผ๋ฟ ์ฐฝ์ ๋จ ํ ๋ฒ๋ง ๋ํ๋ฉ๋๋ค.
// ๐ alert.js
alert("๋ชจ๋์ด ํ๊ฐ๋์์ต๋๋ค!");
// ๋์ผํ ๋ชจ๋์ ์ฌ๋ฌ ๋ชจ๋์์ ๊ฐ์ ธ์ค๊ธฐ
// ๐ 1.js
import `./alert.js`; // ์ผ๋ฟ์ฐฝ์ '๋ชจ๋์ด ํ๊ฐ๋์์ต๋๋ค!'๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
// ๐ 2.js
import `./alert.js`; // ์๋ฌด ์ผ๋ ๋ฐ์ํ์ง ์์ต๋๋ค.
์ค๋ฌด์์ ์ต์์ ๋ ๋ฒจ ๋ชจ๋์ ๋๊ฐ ์ด๊ธฐํ๋ ๋ด๋ถ์์ ์ฐ์ด๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๊ณ ์ด๋ฅผ ๋ด๋ณด๋ด ์ฌ์ฌ์ฉํ๊ณ ์ถ์ ๋ ์ฌ์ฉํฉ๋๋ค.
์ด์ ์ข ๋ ์ด๋ ค์ด ์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๊ฐ์ฒด๋ฅผ ๋ด๋ณด๋ด๋ ๋ชจ๋์ ๋ง๋ค์ด๋ด
์๋ค.
// ๐ admin.js
export let admin = {
name: "John"
};
์ด ๋ชจ๋์ ๊ฐ์ ธ์ค๋ ๋ชจ๋์ด ์ฌ๋ฌ ๊ฐ์ด๋๋ผ๋ ์์ ์ค๋ช
ํ ๊ฒ์ฒ๋ผ ๋ชจ๋์ ์ต์ด ํธ์ถ ์ ๋จ ํ ๋ฒ๋ง ํ๊ฐ๋ฉ๋๋ค. ์ด๋ `admin` ๊ฐ์ฒด๊ฐ ๋ง๋ค์ด์ง๊ณ ์ด ๋ชจ๋์ ๊ฐ์ ธ์ค๋ ๋ชจ๋ ๋ชจ๋์ `admin` ๊ฐ์ฒด๊ฐ ์ ๋ฌ๋ฉ๋๋ค.
๊ฐ ๋ชจ๋์ ๋์ผํ `admin` ๊ฐ์ฒด๊ฐ ์ ๋ฌ๋๋ ๊ฒ์ด์ฃ .
// ๐ 1.js
import {admin} from './admin.js';
admin.name = "Pete";
// ๐ 2.js
import {admin} from './admin.js';
alert(admin.name); // Pete
// 1.js์ 2.js ๋ชจ๋ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ฏ๋ก
// 1.js์์ ๊ฐ์ฒด์ ๊ฐํ ์กฐ์์ 2.js์์๋ ํ์ธํ ์ ์์ต๋๋ค.
์, ๋ค์ ํ๋ฒ ๋ง์๋๋ฆฌ๊ฒ ์ต๋๋ค. ๋ชจ๋์ ๋จ ํ ๋ฒ๋ง ์คํ๋๊ณ ์คํ๋ ๋ชจ๋์ ํ์ํ ๊ณณ์ ๊ณต์ ๋๋ฏ๋ก ์ด๋ ํ ๋ชจ๋์์ admin ๊ฐ์ฒด๋ฅผ ์์ ํ๋ฉด ๋ค๋ฅธ ๋ชจ๋์์๋ ๋ณ๊ฒฝ์ฌํญ์ ํ์ธํ ์ ์์ต๋๋ค.
์ด๋ฐ ํน์ง์ ์ด์ฉํ๋ฉด ๋ชจ๋ ์ค์ (configuration)์ ์ฝ๊ฒ ํ ์ ์์ต๋๋ค. ์ต์ด๋ก ์คํ๋๋ ๋ชจ๋์ ๊ฐ์ฒด ํ๋กํผํฐ๋ฅผ ์ํ๋ ๋๋ก ์ค์ ํ๋ฉด ๋ค๋ฅธ ๋ชจ๋์์ ์ด ์ค์ ์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ด์ฃ .
์์๋ฅผ ํตํด ์ด์ ๋ํด ์์ธํ ์์๋ด
์๋ค. ์๋ `admin.js` ๋ชจ๋์ ์ด๋ค ํน์ ํ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ฃผ๋๋ฐ, ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ฉด ์ธ๋ถ์์ `admin` ๊ฐ์ฒด์ ๊ด๋ จ๋ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ฐ์์์ผ ํ๋ค๊ณ ๊ฐ์ ํด๋ด
์๋ค.
// ๐ admin.js
export let admin = { };
export function sayHi() {
alert(`${admin.name}๋, ์๋
ํ์ธ์!`);
}
์ต์ด๋ก ์คํ๋๋ ์คํฌ๋ฆฝํธ์ธ `init.js`์์ `admin.name`์ ์ค์ ํด์ฃผ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด `admin.js`๋ฅผ ํฌํจํ ์ธ๋ถ ์คํฌ๋ฆฝํธ์์ `admin.name`์ ์ ์ฅ๋ ์ ๋ณด๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
// ๐ init.js
import {admin} from './admin.js';
admin.name = "๋ณด๋ผ";
๋ ๋ค๋ฅธ ๋ชจ๋์์๋ `admin.name`์ ์ ์ฅ๋ ์ ๋ณด๋ฅผ ๋ณผ ์ ์๋ค๋ ๊ฑธ ํ์ธํด ๋ด ์๋ค.
// ๐ other.js
import {admin, sayHi} from './admin.js';
alert(admin.name); // ๋ณด๋ผ
sayHi(); // ๋ณด๋ผ๋, ์๋
ํ์ธ์!
import.meta
`import.meta` ๊ฐ์ฒด๋ ํ์ฌ ๋ชจ๋์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ค๋๋ค.
ํธ์คํธ ํ๊ฒฝ์ ๋ฐ๋ผ ์ ๊ณตํ๋ ์ ๋ณด์ ๋ด์ฉ์ ๋ค๋ฅธ๋ฐ, ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ์คํฌ๋ฆฝํธ์ URL ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค. HTML ์์ ์๋ ๋ชจ๋์ด๋ผ๋ฉด, ํ์ฌ ์คํ ์ค์ธ ์นํ์ด์ง์ URL ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค.
<script type="module">
alert(import.meta.url); // script URL (์ธ๋ผ์ธ ์คํฌ๋ฆฝํธ๊ฐ ์์นํด ์๋ html ํ์ด์ง์ URL)
</script>
this๋ undefined
์ฌ์ํ ๋ด์ฉ์ด์ง๋ง ํํ ๋ฆฌ์ผ์ ์์ ์ฑ์ ์ํด ์ด ๋ด์ฉ์ ์ธ๊ธํ๊ณ ๋์ด๊ฐ์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค.
๋ชจ๋ ์ต์์ ๋ ๋ฒจ์ `this`๋ `undefined`์
๋๋ค.
๋ชจ๋์ด ์๋ ์ผ๋ฐ ์คํฌ๋ฆฝํธ์ `this`๋ ์ ์ญ ๊ฐ์ฒด์ธ ๊ฒ๊ณผ ๋์กฐ๋ฉ๋๋ค.
<script>
alert(this); // window
</script>
<script type="module">
alert(this); // undefined
</script>
๐๋ธ๋ผ์ฐ์ ํน์ ๊ธฐ๋ฅ
๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ `type="module"`์ด ๋ถ์ ์คํฌ๋ฆฝํธ๊ฐ ์ผ๋ฐ ์คํฌ๋ฆฝํธ์ ์ด๋ค ์ ์ด ๋ค๋ฅธ์ง ์์๋ด ์๋ค.
์ง์ฐ ์คํ(defer)
๋ชจ๋ ์คํฌ๋ฆฝํธ๋ ํญ์ ์ง์ฐ ์คํ๋ฉ๋๋ค. ์ธ๋ถ ์คํฌ๋ฆฝํธ, ์ธ๋ผ์ธ ์คํฌ๋ฆฝํธ์ ๊ด๊ณ์์ด ๋ง์น defer ์์ฑ์ ๋ถ์ธ ๊ฒ์ฒ๋ผ ์คํ๋ฉ๋๋ค
๋ฐ๋ผ์ ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ ์๋์ ๊ฐ์ ํน์ง(defer์ ์์ ๋์ผ)์ ๋ณด์
๋๋ค.
- ์ธ๋ถ ๋ชจ๋ ์คํฌ๋ฆฝํธ <script type="module" src="...">๋ฅผ ๋ค์ด๋ก๋ํ ๋ ๋ธ๋ผ์ฐ์ ์ HTML ์ฒ๋ฆฌ๊ฐ ๋ฉ์ถ์ง ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ์ธ๋ถ ๋ชจ๋ ์คํฌ๋ฆฝํธ์ ๊ธฐํ ๋ฆฌ์์ค๋ฅผ ๋ณ๋ ฌ์ ์ผ๋ก ๋ถ๋ฌ์ต๋๋ค.
- ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ HTML ๋ฌธ์๊ฐ ์์ ํ ์ค๋น๋ ๋๊น์ง ๋๊ธฐ ์ํ์ ์๋ค๊ฐ HTML ๋ฌธ์๊ฐ ์์ ํ ๋ง๋ค์ด์ง ์ดํ์ ์คํ๋ฉ๋๋ค. ๋ชจ๋์ ํฌ๊ธฐ๊ฐ ์์ฃผ ์์์ HTML๋ณด๋ค ๋นจ๋ฆฌ ๋ถ๋ฌ์จ ๊ฒฝ์ฐ์๋ ๋ง์ด์ฃ .
- ์คํฌ๋ฆฝํธ์ ์๋์ ์์๊ฐ ์ ์ง๋ฉ๋๋ค. ๋ฌธ์์ ์์ชฝ์ ์คํฌ๋ฆฝํธ๋ถํฐ ์ฐจ๋ก๋ก ์คํ๋ฉ๋๋ค.
์ด๋ฐ ํน์ง ๋๋ฌธ์ ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ ํญ์ ์์ ํ HTML ํ์ด์ง๋ฅผ ‘๋ณผ ์’ ์๊ณ ๋ฌธ์ ๋ด ์์์๋ ์ ๊ทผํ ์ ์์ต๋๋ค.
์์:
<script type="module">
alert(typeof button); // ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ ์ง์ฐ ์คํ๋๊ธฐ ๋๋ฌธ์ ํ์ด์ง๊ฐ ๋ชจ๋ ๋ก๋๋๊ณ ๋ ๋ค์์ alert ํจ์๊ฐ ์คํ๋๋ฏ๋ก
// ์ผ๋ฟ์ฐฝ์ object๊ฐ ์ ์์ ์ผ๋ก ์ถ๋ ฅ๋ฉ๋๋ค. ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ ์๋์ชฝ์ button ์์๋ฅผ '๋ณผ ์' ์์ฃ .
</script>
ํ๋จ์ ์ผ๋ฐ ์คํฌ๋ฆฝํธ์ ๋น๊ตํด ๋ด
์๋ค.
<script>
alert(typeof button); // ์ผ๋ฐ ์คํฌ๋ฆฝํธ๋ ํ์ด์ง๊ฐ ์์ ํ ๊ตฌ์ฑ๋๊ธฐ ์ ์ด๋ผ๋ ๋ฐ๋ก ์คํ๋ฉ๋๋ค.
// ๋ฒํผ ์์๊ฐ ํ์ด์ง์ ๋ง๋ค์ด์ง๊ธฐ ์ ์ ์ ๊ทผํ์๊ธฐ ๋๋ฌธ์ undefined๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
</script>
<button id="button">Button</button>
์ ์์์์ ์ผ๋ฐ ์คํฌ๋ฆฝํธ๋ ์ฒซ ๋ฒ์งธ ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ณด๋ค ๋จผ์ ์คํ๋๋ค๋ ์ ์ ์ฃผ์ํ์๊ธฐ ๋ฐ๋๋๋ค. undefined๊ฐ ๋จผ์ , object๋ ๋์ค์ ์ถ๋ ฅ๋ฉ๋๋ค.
๋ชจ๋ ์คํฌ๋ฆฝํธ๋ ์ง์ฐ ์คํ๋๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ์ ์ฒด๊ฐ ์ฒ๋ฆฌ๋๊ธฐ ์ ๊น์ง ์คํ๋์ง ์๊ณ , ์ผ๋ฐ ์คํฌ๋ฆฝํธ๋ ๋ฐ๋ก ์คํ๋๋ฏ๋ก ์์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋ํ๋ฌ์ต๋๋ค.
๋ชจ๋์ ์ฌ์ฉํ ๋ HTML ํ์ด์ง๊ฐ ์์ ํ ๋ํ๋ ์ดํ์ ๋ชจ๋์ด ์คํ๋๋ค๋ ์ ์ ํญ์ ์ ์(defer์ ๋์ผํ ํน์ง)ํด์ผ ํฉ๋๋ค. ํ์ด์ง ๋ด ํน์ ๊ธฐ๋ฅ์ด ๋ชจ๋ ์คํฌ๋ฆฝํธ์ ์์กด์ ์ธ ๊ฒฝ์ฐ, ๋ชจ๋์ด ์์ ํ ๋ก๋ฉ๋๊ธฐ ์ ์ ํ์ด์ง๊ฐ ๋จผ์ ์ฌ์ฉ์์๊ฒ ๋
ธ์ถ๋๋ฉด ์ฌ์ฉ์๊ฐ ํผ๋์ ๋๋ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ๋ฌ์ค๋ ๋์(์๋ฅผ ๋ค์๋ฉด ์ปดํฌ๋ํธ ํ์ผ ๋ถ๋ฌ์ค๋ ๋์)์ ํฌ๋ช
์ค๋ฒ๋ ์ด๋ '๋ก๋ฉ ์ธ๋์ผ์ดํฐ(loading indicator)'๋ฅผ ๋ณด์ฌ์ฃผ์ด ์ฌ์ฉ์์ ํผ๋์ ์๋ฐฉํด ์ฃผ๋๋ก ํฉ์๋ค.
์ธ๋ผ์ธ ์คํฌ๋ฆฝํธ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ(async)
๋ชจ๋์ด ์๋ ์ผ๋ฐ ์คํฌ๋ฆฝํธ์์ `async` ์์ฑ์ ์ธ๋ถ ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ๋ฌ์ฌ ๋๋ง ์ ํจํฉ๋๋ค.(์์์ ์ธ๊ธํ๋ ๋ด์ฉ์.) `async` ์์ฑ์ด ๋ถ์ ์คํฌ๋ฆฝํธ๋ ๋ก๋ฉ์ด ๋๋๋ฉด ๋ค๋ฅธ ์คํฌ๋ฆฝํธ๋ HTML ๋ฌธ์๊ฐ ์ฒ๋ฆฌ๋๊ธธ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฐ๋ก ์คํ๋ฉ๋๋ค.
๋ฐ๋ฉด, ๋ชจ๋ ์คํฌ๋ฆฝํธ์์ async ์์ฑ์ ์ธ๋ผ์ธ ์คํฌ๋ฆฝํธ์๋ ์ ์ฉํ ์ ์์ต๋๋ค.(์ธ๋ผ์ธ ์คํฌ๋ฆฝํธ๊ฐ ์๋ ๊ฒฝ์ฐ, ์ฆ, src ์์ฑ๊ฐ์ ํตํด ์ธ๋ถ ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ๋ฌ์ค๋ ๊ฒฝ์ฐ์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ๋น์ฐ ๊ฐ๋ฅ)
์๋ ์ธ๋ผ์ธ ์คํฌ๋ฆฝํธ์ async ์์ฑ์ด ๋ถ์๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ์คํฌ๋ฆฝํธ๋ HTML์ด ์ฒ๋ฆฌ๋๊ธธ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฐ๋ก ์คํ๋ฉ๋๋ค.
๊ฐ์ ธ์ค๊ธฐ(`./analytics.js`) ์์
์ด ๋๋๋ฉด HTML ํ์ฑ์ด ๋๋์ง ์์๊ฑฐ๋ ๋ค๋ฅธ ์คํฌ๋ฆฝํธ๊ฐ ๋๊ธฐ ์ํ์ ์๋๋ผ๋ ๋ชจ๋์ด ๋ฐ๋ก ์คํ๋ฉ๋๋ค. โถ `import`, `export` ๋ฅผ ์ฌ์ฉํ ์ ์๋ async script๊ฐ ๋์ด๋ฒ๋ฆผ.
์ด๋ฐ ํน์ง์ ๊ด๊ณ ๋ ๋ฌธ์ ๋ ๋ฒจ ์ด๋ฒคํธ ๋ฆฌ์ค๋, ์นด์ดํฐ ๊ฐ์ด ์ด๋์๋ ์ข
์๋์ง ์๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
<!-- ํ์ํ ๋ชจ๋(analytics.js)์ ๋ก๋๊ฐ ๋๋๋ฉด -->
<!-- ๋ฌธ์๋ ๋ค๋ฅธ <script>๊ฐ ๋ก๋๋๊ธธ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฐ๋ก ์คํ๋ฉ๋๋ค.-->
<script async type="module">
import {counter} from './analytics.js';
counter.count();
</script>
๊ทธ๋๋ import ํด์ค๋ ๊ณณ(์ถ์ฒ ๋ชจ๋)์ ๋ก๋๋ ๊ธฐ๋ค๋ฆฐ๋ค๋ ์ ์ ์ ์ ์์ต๋๋ค.
์ธ๋ถ ์คํฌ๋ฆฝํธ
`type="module"`์ด ๋ถ์ ์ธ๋ถ ๋ชจ๋ ์คํฌ๋ฆฝํธ์ ๋ ๊ฐ์ง ํฐ ํน์ง์ด ์์ต๋๋ค.
1. `src` ์์ฑ๊ฐ์ด ๋์ผํ ์ธ๋ถ ์คํฌ๋ฆฝํธ๋ ํ ๋ฒ๋ง ์คํ๋ฉ๋๋ค.
<!-- my.js๋ ํ ๋ฒ๋ง ๋ก๋ ๋ฐ ์คํ๋ฉ๋๋ค. -->
<script type="module" src="my.js"></script>
<script type="module" src="my.js"></script>
2. ์ธ๋ถ ์ฌ์ดํธ๊ฐ์ด ๋ค๋ฅธ ์ค๋ฆฌ์ง์์ ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ๋ฌ์ค๋ ค๋ฉด CORS ์ฑํฐ์์ ์ค๋ช ํ ๋ฐ์ ๊ฐ์ด CORS ํค๋๊ฐ ํ์ํฉ๋๋ค. ๋ชจ๋์ด ์ ์ฅ๋์ด์๋ ์๊ฒฉ ์๋ฒ๊ฐ Access-Control-Allow-Origin: * ํค๋๋ฅผ ์ ๊ณตํด์ผ๋ง ์ธ๋ถ ๋ชจ๋์ ๋ถ๋ฌ์ฌ ์ ์์ต๋๋ค. ์ฐธ๊ณ ๋ก * ๋์ ํ์น(fetch)๋ฅผ ํ์ฉํ ๋๋ฉ์ธ์ ๋ช ์ํ ์๋ ์์ต๋๋ค.
<!-- another-site.com์ด Access-Control-Allow-Origin์ ์ง์ํด์ผ๋ง ์ธ๋ถ ๋ชจ๋์ ๋ถ๋ฌ์ฌ ์ ์์ต๋๋ค.-->
<!-- ๊ทธ๋ ์ง ์์ผ๋ฉด ์คํฌ๋ฆฝํธ๋ ์คํ๋์ง ์์ต๋๋ค.-->
<script type="module" src="http://another-site.com/their.js"></script>
์ด ํน์ง์ ๋ณด์์ ๊ฐํํด ์ค๋๋ค.
๊ฒฝ๋ก๊ฐ ์๋ ๋ชจ๋์ ๊ธ์ง
๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ `import`๋ ๋ฐ๋์ ์๋ ํน์ ์ ๋ URL ์์ ์์ผ ํฉ๋๋ค. ‘๊ฒฝ๋ก๊ฐ ์๋’ ๋ชจ๋์ ํ์ฉ๋์ง ์์ต๋๋ค.
์๋ ์์ ์์ `import`๋ ๋ฌดํจํฉ๋๋ค.
import {sayHi} from 'sayHi'; // Error!
// './sayHi.js'์ ๊ฐ์ด ๊ฒฝ๋ก ์ ๋ณด๋ฅผ ์ง์ ํด ์ฃผ์ด์ผ ํฉ๋๋ค.
Node.js๋ ๋ฒ๋ค๋ง ํด์ ๊ฒฝ๋ก๊ฐ ์์ด๋ ํด๋น ๋ชจ๋์ ์ฐพ์ ์ ์๋ ๋ฐฉ๋ฒ์ ์๊ธฐ ๋๋ฌธ์ ๊ฒฝ๋ก๊ฐ ์๋ ๋ชจ๋์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํ์ง๋ง ๋ธ๋ผ์ฐ์ ๋ ๊ฒฝ๋ก ์๋ ๋ชจ๋์ ์ง์ํ์ง ์์ต๋๋ค.
๋น๋ ํด
๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ๋ชจ๋์ '๋จ๋
’์ผ๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ํ์น ์์ต๋๋ค. ๋๊ฐ ์นํฉ(Webpack)๊ณผ ๊ฐ์ ํน๋ณํ ํด์ ์ฌ์ฉํด ๋ชจ๋์ ํ ๋ฐ ๋ฌถ์ด(๋ฒ๋ค๋ง) ํ๋ก๋์
์๋ฒ์ ์ฌ๋ฆฌ๋ ๋ฐฉ์์ ์ฌ์ฉํฉ๋๋ค.
๋ฒ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ๋ถํด๋ฅผ ํต์ ํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์ ๋ํ์ฌ ๊ฒฝ๋ก๊ฐ ์๋ ๋ชจ๋์ด๋ CSS, HTML ํฌ๋งท์ ๋ชจ๋์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
๋น๋ ํด์ ์ญํ ์ ์๋์ ๊ฐ์ต๋๋ค.
- HTML์ `<script type="module">`์ ๋ฃ์ ‘์ฃผ์(main)’ ๋ชจ๋(‘์ง์ ์ ’ ์ญํ ์ ํ๋ ๋ชจ๋)์ ์ ํํฉ๋๋ค.
- ‘์ฃผ์’ ๋ชจ๋์ ์์กดํ๊ณ ์๋ ๋ชจ๋ ๋ถ์์ ์์์ผ๋ก ๋ชจ๋ ๊ฐ์ ์์กด ๊ด๊ณ๋ฅผ ํ์ ํฉ๋๋ค.
- ๋ชจ๋ ์ ์ฒด๋ฅผ ํ๋ฐ ๋ชจ์ ํ๋์ ํฐ ํ์ผ์ ๋ง๋ญ๋๋ค(์ค์ ์ ๋ฐ๋ผ ์ฌ๋ฌ ๊ฐ์ ํ์ผ์ ๋ง๋๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค). ์ด ๊ณผ์ ์์ import๋ฌธ์ด ๋ฒ๋ค๋ฌ ๋ด ํจ์๋ก ๋์ฒด๋๋ฏ๋ก ๊ธฐ์กด ๊ธฐ๋ฅ์ ๊ทธ๋๋ก ์ ์ง๋ฉ๋๋ค.
- ์ด๋ฐ ๊ณผ์ ์ค์ ๋ณํ์ด๋ ์ต์ ํ๋ ํจ๊ป ์ํ๋ฉ๋๋ค.
- ๋๋ฌ ๊ฐ๋ฅํ์ง ์์ ์ฝ๋๋ ์ญ์ ๋ฉ๋๋ค.
- ๋ด๋ณด๋ด์ง ๋ชจ๋ ์ค ์ฐ์์ฒ๊ฐ ์๋ ๋ชจ๋์ ์ญ์ ํฉ๋๋ค(๊ฐ์ง์น๊ธฐ(tree-shaking)).
- `console`, `debugger` ๊ฐ์ ๊ฐ๋ฐ ๊ด๋ จ ์ฝ๋๋ฅผ ์ญ์ ํฉ๋๋ค.
- ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ด ์ฌ์ฉ๋ ๊ฒฝ์ฐ ๋ฐ๋ฒจ(Babel)์ ์ฌ์ฉํด ๋์ผํ ๊ธฐ๋ฅ์ ํ๋ ๋ฎ์ ๋ฒ์ ์ ์คํฌ๋ฆฝํธ๋ก ๋ณํํฉ๋๋ค.
- ๊ณต๋ฐฑ ์ ๊ฑฐ, ๋ณ์ ์ด๋ฆ ์ค์ด๊ธฐ ๋ฑ์ผ๋ก ์ฐ์ถ๋ฌผ์ ํฌ๊ธฐ๋ฅผ ์ค์ ๋๋ค.
๋ฒ๋ค๋ง ํด์ ์ฌ์ฉํ๋ฉด ์คํฌ๋ฆฝํธ๋ค์ ํ๋ ํน์ ์ฌ๋ฌ ๊ฐ์ ํ์ผ๋ก ๋ฒ๋ค๋ง ๋ฉ๋๋ค. ์ด๋ ๋ฒ๋ค๋ง ์ ์คํฌ๋ฆฝํธ์ ์๋ `import`, `export`๋ฌธ์ ํน๋ณํ ๋ฒ๋ค๋ฌ ํจ์๋ก ๋์ฒด๋ฉ๋๋ค. ๋ฒ๋ค๋ง ๊ณผ์ ์ด ๋๋๋ฉด ๊ธฐ์กด ์คํฌ๋ฆฝํธ์์ `import`, `export`๊ฐ ์ฌ๋ผ์ง๊ธฐ ๋๋ฌธ์ `type="module"`์ด ํ์ ์์ด์ง๋๋ค. ๋ฐ๋ผ์ ์๋์ ๊ฐ์ด ๋ฒ๋ค๋ง ๊ณผ์ ์ ๊ฑฐ์น ์คํฌ๋ฆฝํธ๋ ์ผ๋ฐ ์คํฌ๋ฆฝํธ์ฒ๋ผ ์ทจ๊ธํ ์ ์์ต๋๋ค.
<!-- ์นํฉ๊ณผ ๊ฐ์ ํด๋ก ๋ฒ๋ค๋ง ๊ณผ์ ์ ๊ฑฐ์น ์คํฌ๋ฆฝํธ์ธ bundle.js -->
<script src="bundle.js"></script>
๋ฒ๋ค๋ง ๊ณผ์ ์ ๊ฑฐ์น๋ฉด ๋ชจ๋์ด ์ผ๋ฐ ์คํฌ๋ฆฝํธ๊ฐ ๋์ด๋ฒ๋ฆฌ๊ธด ํ์ง๋ง ๋ค์ดํฐ๋ธ ๋ชจ๋๋ ๋น์ฐํ ์ฌ์ฉ ๊ฐ๋ฅํ๋ฏ๋ก ์ด ํํ ๋ฆฌ์ผ์์ ์นํฉ์์ด ๋ด์ฉ์ ์ ๊ฐํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์์ฝ
์ง๊ธ๊น์ง ๋ฐฐ์ด ๋ด์ฉ์ ์์ฝํด๋ด
์๋ค.
- ๋ชจ๋์ ํ๋์ ํ์ผ์
๋๋ค. ๋ธ๋ผ์ฐ์ ์์ `import` ,`export` ์ง์์๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด `<script type="module">`๊ฐ์ ์์ฑ์ด ํ์ํฉ๋๋ค. ๋ชจ๋์ ์๋์ ๊ฐ์ ํน์ง์ ์ง๋๋๋ค.
- ์ง์ฐ ์คํ๋ฉ๋๋ค.(defer)
- ์ธ๋ถ ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ๋ฌ์ฌ ๋๋ง ์ ํจํ ์ผ๋ฐ ์คํฌ๋ฆฝํธ์ async ์คํฌ๋ฆฝํธ์๋ ๋ค๋ฅด๊ฒ module script๋ ์ธ๋ผ์ธ ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
`<script async type="module" src="./happy.js"></script>`(์ธ๋ถ ์คํฌ๋ฆฝํธ async ์ฒ๋ฆฌ) ํน์
`<script async type="module">import {counter} from './happy.js';...</script>`(์ธ๋ผ์ธ ๋ชจ๋ ์คํฌ๋ฆฝํธ async ์ฒ๋ฆฌ) ๋ ๋ค ๊ฐ๋ฅ. - ์ธ๋ถ ์ค๋ฆฌ์ง(๋๋ฉ์ธ์ด๋ ํ๋กํ ์ฝ, ํฌํธ๊ฐ ๋ค๋ฅธ ์ค๋ฆฌ์ง)์์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ๋ฌ์ค๋ ค๋ฉด CORS ํค๋๊ฐ ์์ด์ผ ํฉ๋๋ค.
- ์ค๋ณต๋ ์ธ๋ถ ์คํฌ๋ฆฝํธ๋ ๋ฌด์๋ฉ๋๋ค.
- ๋ชจ๋์ ์์ ๋ง์ ์ค์ฝํ๋ฅผ ๊ฐ์ต๋๋ค. ๋ชจ๋ ๊ฐ ๊ธฐ๋ฅ ๊ณต์ ๋ `import`, `export`๋ก ํ ์ ์์ต๋๋ค.
- ํญ์ ์๊ฒฉ ๋ชจ๋๋ก ์คํ(`use strict`)๋ฉ๋๋ค.
- ๋ชจ๋ ๋ด ์ฝ๋๋ ๋จ ํ ๋ฒ๋ง ์คํ(=ํ๊ฐ)๋ฉ๋๋ค. ๋ชจ๋์ ๋ด๋ณด๋ด๋ฉด ์ด ๋ชจ๋์ ๊ฐ์ ธ์ค๊ธฐ ํ๋ ๋ชจ๋ ๋ชจ๋๊ฐ ๋ด๋ณด๋ด์ง ๋ชจ๋์ ๊ณต์ ํฉ๋๋ค.
๋ชจ๋ ๋ด ํจ์๋ ๊ฐ์ฒด ๋ฑ์ `export` ํค์๋๋ก ๋ด๋ณด๋ผ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ๋ด๋ณด๋ด์ง ๊ธฐ๋ฅ์ `import` ํค์๋๋ฅผ ์ฌ์ฉํด ๊ฐ์ ธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ์๋์ผ๋ก ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ๋ฌ์ค๊ณ ํ๊ฐํฉ๋๋ค.
์ค์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ถ์ํ ๋ ์ฑ๋ฅ ๊ฐ์ ๋ฑ์ ์ด์ ๋๋ฌธ์ ์นํฉ๊ณผ ๊ฐ์ ๋ฒ๋ค๋ฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ถ๋ก
1. credentials by default (crossorigin attribute) ๐ฏ๐
๋๋ถ๋ถ์ CORS-based API๋ค์ request๊ฐ ๋์ผ ์ถ์ฒ(Same Origin)๋ผ๋ฉด credentials( cookies ๋ฑ)์ ๋ณด๋ผ ๊ฒ์ ๋๋ค. `fetch()`์ ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ CORS-based API์ ๋์ผํ๊ฒ ๋์ํฉ๋๋ค! ๊ทธ๋ฌ๋ ์ต์ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ ์ธํ๊ณ ์์ ๋ธ๋ผ์ฐ์ ์์๋ ์๊ธฐ์น ๋ชปํ ์กฐ๊ธ ๋ค์ํ ์ํฉ์ ๋ง์ถ์ง ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์๋ฉด:
- same-origin์ ๋ํด ๊ธฐ๋ณธ์ ์ผ๋ก credentials๋ฅผ ๋ณด๋ด๋ ๊ทธ ๋น์์ spec์ ๋ฐ๋ฅธ ์ค๋๋ ๋ฒ์ ์ ๋ธ๋ผ์ฐ์ ๋ค
- same-origin์ด์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก credentials๋ฅผ ๋ณด๋ด์ง ์๋ ๊ทธ ๋น์์ spec์ ๋ฐ๋ฅธ ์ค๋๋ ๋ฒ์ ์ ๋ธ๋ผ์ฐ์ ๋ค
- same-origin์ ๋ํด ๊ธฐ๋ณธ์ ์ผ๋ก credentials๋ฅผ ๋ณด๋ด๋ ์๋ก์ด ์คํ์ ๋ฐ๋ฅด๋ ์ต์ ๋ฒ์ ์ ๋ธ๋ผ์ฐ์ ๋ค
์ด๋ฌํ ๋ฌธ์ ๋ค์ `crossorigin` ์์ฑ์ผ๋ก ํด๊ฒฐํ ์ ์์ต๋๋ค.
module์์ `cross-origin`์ ๊ธฐ๋ณธ์ ์ผ๋ก Same-Origin์ ๋ํด์๋ credentials๋ฅผ ๋ณด๋ด๋๋ก ์ค์ ํด์ฃผ๋ ์ต์ ์ ๋๋ค. `cross-origin`์ ์ค์ ํ๋๋ฐ Cross-Origin์ด๋ผ๋ฉด ์์์ credentials๋ฅผ ๋ณด๋ด์ง ์์ผ๋ ๊ฑฑ์ ํ์ง ์์๋ ๋ฉ๋๋ค. ์ด๋ฏธ SORS์ ๋ํด credential์ ๋ณด๋ด๋๋ก ๋์ด์๋ ์ต์ ๋ธ๋ผ์ฐ์ ๋ค์ ์ด ์ต์ ์ ์ค์ ํด๋ ๋ฐ๋๋ ๊ธฐ๋ฅ์ด ์๋ค๋ ์ ์ ์์๋์ธ์.
ํ์ํ๋ค๋ฉด Cross-Origin์ ๋ํด์๋ credentials๋ฅผ ๋ณด๋ด๋๋ก ์ค์ ํ ์ ์์ต๋๋ค. `cross-origin`์ `use-credentials` ์์ฑ๊ฐ์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
<!-- ์ธ์ฆ ์ ๋ณด(์ฟ ํค ๋ฑ) ๋ณด๋ -->
<script src="1.js"></script>
<!-- ์ธ์ฆ ์ ๋ณด(์ฟ ํค ๋ฑ) ๋ณด๋ด์ง ์์ - ๋์ผ ์ถ์ฒ -->
<script type="module" src="1.js?"></script>
<!-- ์ธ์ฆ ์ ๋ณด(์ฟ ํค ๋ฑ) ๋ณด๋ - ๋์ผ ์ถ์ฒ -->
<script type="module" crossorigin src="1.js"></script>
<!-- ์ธ์ฆ ์ ๋ณด(์ฟ ํค ๋ฑ) ๋ณด๋ด์ง ์์ - ๋์ผ ์ถ์ฒ ์๋ -->
<script type="module" crossorigin src="http://๋ค๋ฅธ_ํธ์คํธ/1.js"></script>
<!-- ์ธ์ฆ ์ ๋ณด(์ฟ ํค ๋ฑ) ๋ณด๋ - ๋์ผ ์ถ์ฒ ์๋ -->
<script type="module" crossorigin="use-credentials" src="http://๋ค๋ฅธ_ํธ์คํธ/1.js"></script>
์์ ๊ฐ์ ์ด์ ๋ก module ์คํฌ๋ฆฝํธ์์ `crossorigin`์ ๊ทธ๋ฅ ๋ฌด์กฐ๊ฑด์ ์ผ๋ก ์ ์ด์ฃผ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๐๐
์, ๊ทธ๋ฆฌ๊ณ ๋์ผ์ถ์ฒ๊ฐ ์๋ ๊ณณ์์ credential๊ณผ ํจ๊ป CORS ์์ฒญ์ ํ ๋๋ ๋ธ๋ผ์ฐ์ ์์ `crossorigin="use-credential"`์ ์ค์ ํ๋ ๊ฒ ๋ฟ๋ง ์๋๋ผ CORS์ ๋ํด์ ์๊ฒฉ ์๋ฒ ์ชฝ์์๋ ๋น์ฐํ ์๋ฒ์ ์๋ตํค๋์ `Access-Control-Allow-Origin: *` ๋ฑ์ ์ค์ ์ผ๋ก [ํน์ ํน์ ์ ๋ถ]origin์ ์ด์ด๋๋ ์ต์ ์ ์ค์ ํด์ฃผ๊ณ , `Access-Control-Allow-Credentials: true`๊ฐ ํฌํจ๋์ด ์์ด์ผ ํฉ๋๋ค.
๐๋งํฌ1, ๋งํฌ2๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.
๋ค์ํ Browser(Safari, Chrome, Firefox, Edge ๋ฑ)์์ ์ง์ํ๋ ๋ชจ๋ ๋ฐฉ์์ ๋ํ ๋ ์์ธํ ๋ด์ฉ์ ๋ณด๊ณ ์ถ๋ค๋ฉด ๐์ฌ๊ธฐ(์๋ฌธ)๋ฅผ ์ฐธ๊ณ ํ๋ฉด ๋ฉ๋๋ค. (ํน์ ๐mdn ์ด๋ ๐react ๋ฌธ์)