[์๋ฐ์คํฌ๋ฆฝํธ] CommonJS vs ES Modules
๐ JS ๋ชจ๋์ ๋ด๋ณด๋ด๋ ๋ฐฉ์์ ๋๊ฐ์ง๊ฐ ์๋ค.
- ๐ ๋ชจ๋์ด๋? ์ฌ๋ฌ ๊ธฐ๋ฅ๋ค์ ๊ดํ ์ฝ๋๊ฐ ๋ชจ์ฌ์๋ ํ๋์ ํ์ผ
- ์ฒซ๋ฒ์งธ๋ module.exports๋ก ๋ชจ๋์ ๋ด๋ณด๋ด๊ณ require()๋ก ์ ๊ทผํ๋ CJS(CommonJS)
- ๋๋ฒ์งธ๋ export๋ก ๋ชจ๋์ ๋ด๋ณด๋ด๊ณ import๋ก ์ ๊ทผํ๋ ESM(ES Modules)๊ฐ ์๋ค.
//CJS
modules.exports = { ... } //๋ชจ๋ ๋ด๋ณด๋ผ๋
const utils = requires('utils'); //๋ชจ๋ ๊ฐ์ ธ์ฌ ๋
// ESM ๋ฐฉ๋ฒ
export.default = () => {... }; //๋ชจ๋์ ๋ด๋ณด๋ผ ๋
import utils from 'utils'; // ๋ชจ๋ ๊ฐ์ ธ์ฌ ๋
โจ์ฐจ์ด์
1. CJS ๋ฐฉ์
- require๋ก ๋ชจ๋์ ์ ๊ทผํ๊ณ module.exports๋ก ๋ชจ๋์ ๋ด๋ณด๋ด๋ ESM ๋ฐฉ์
- Node.js์์ ์ง์ํ๋ ๋ชจ๋ ๋ฐฉ์์ผ๋ก ์ด๊ธฐ Node ๋ฒ์ ๋ถํฐ ์ฌ์ฉ
- ๋ณ๋์ ์ค์ ์ด ์๋ค๋ฉด CJS๊ฐ ๊ธฐ๋ณธ๊ฐ
1) ๋ชจ๋์ ์ ๊ทผํ ๋ require()
- ์ธ๋ถ ๋ชจ๋์ ์ ๊ทผํ ๋๋ require()์ ์ฌ์ฉ
2) ๋ด๋ณด๋ผ ๋๋ module.exports
- named exports, default exports ๋๊ฐ์ง ๋ฐฉ์์ด ์์
- named export๋ export ๋์์ ๋ช ๋ช ํ์ฌ ๋ด๋ณด๋ด๋ ๋ฐฉ์
module.exports.add = (a, b) => a + b;
module.export.sub = (a, b) => a - b;
๋๋,
const calculator = require("./calculator.js");
const { add } = require("./calculator.js");
3) ํน์ง
- require()๋ ์ฆ์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ ๊ตฌ์กฐ
- top-level await์ด ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ๋๊ธฐ์ ์ผ๋ก ์๋
- ๋๊ธฐ๋ก ์๋ํ๋ฏ๋ก promise๋ฅผ ๋ฆฌํดํ์ง ์๊ณ , module.exports์ ์ค์ ๋ ๊ฐ๋ง์ ๋ฆฌํด
- import ์์์ ๋ฐ๋ผ ์คํฌ๋ฆฝํธ๋ฅผ ์คํ
๐ top-level await ์ด๋?
ES2022์์ ๋์จ ๊ธฐ๋ฅ์ผ๋ก, ๋ชจ๋์ ์ต์์ ์ค์ฝํ์์ ๋น๋๊ธฐ ๋์์ awaitํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
์ด์ ์๋ async ํค์๋๊ฐ ์๋ ์ค์ฝํ๋ด์์๋ง await๋ฅผ ํตํด ํด๋น ์ค์ฝํ์์ ๋น๋๊ธฐ ๋์์ด ์๋ฃ๋๊ธฐ๊น์ง ๋ธ๋กํนํ ์ ์์๋๋ฐ
๋ชจ๋ ๋จ์์์ await๋ฅผ ํตํด ํน์ ๋น๋๊ธฐ ํจ์์ ๋์์ด ์๋ฃ๋๊ธฐ๊น์ง ํ์ ๋ชจ๋์ ๋์์ ๋ง์ ์ ์๋ค.
๐ป ์์ ์ฝ๋
//a.js
import fetch from "node-fetch";
let users;
export default (async () => {
const resp = await fetch('https://jsonplaceholder.typicode.com/users');
users = resp.json();
})();
export { users };
//b.js
import promise, {users} from './a.js';
promise.then(() => {
console.log('All users:', users);
});
- a ๋ชจ๋์ b ๋ชจ๋์์ ์ฌ์ฉํ ๋ a ๋ชจ๋์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋ ํ ์ฌ์ฉ์ ๋ณด์ฅํ๊ธฐ ์ํด ์์ ๊ฐ์ด ์ฒ๋ฆฌํด์ผ ํ์
//a.js
const resp = await fetch('https://jsonplaceholder.typicode.com/users');
const users = resp.json();
export { users};
//b.js
import { users } from './a.js';
console.log(users);
console.log('In usingAwait module');
- ์ด๋ ๊ฒ ๊ฐ๊ฒฐํ๊ฒ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฐ๋ฅ
2. ESM
- import๋ก ๋ชจ๋์ ์ ๊ทผํ๊ณ export๋ก ๋ชจ๋์ ๋ด๋ณด๋ด๋ ESM ๋ฐฉ์
- ESMAScript์ ์ง์ํ๋ ๋ฐฉ์
- Node14์์๋ CJS, MJS(ES Modules)์ด ๊ณต์กดํ๋๋ฐ, ๋๊ฐ๋ฅผ ๋์์ ์ฌ์ฉํ๊ธฐ ์ํด ๋ณ๋์ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ค.
- ๋ชจ๋ ์์คํ ์ CJS(๊ธฐ๋ณธ๊ฐ)์์ ESM์ผ๋ก ๋ณ๊ฒฝํ ์, JS ์ผ๋ถ ๋์์ด ๋ณ๊ฒฝ๋๋ค.
1. ์ฌ์ฉ๋ฐฉ๋ฒ
- ESM ๋ฐฉ์์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ package.json์ 'type:'module'์ ์ค์ ํด์ผ ํ๋ค.
// package.json
{
"type": "module",
}
2. ๋ฌธ๋ฒ
- ๋ชจ๋ ์ ๊ทผํ ๋๋ import()
- ๋ชจ๋ ๋ด๋ณด๋ผ ๋๋ export()
3. ํน์ง
- top-level await๋ฅผ ์ง์ํ๋ฏ๋ก module loader๊ฐ ๋น๋๊ธฐ ํ๊ฒฝ์์ ์คํ๋๋ค.
- ๊ทธ๋ฌ๋ฏ๋ก CJS์ฒ๋ผ ์คํฌ๋ฆฝํธ๋ฅผ ๋ฐ๋ก ์คํํ์ง ์๊ณ import, export ๊ตฌ๋ฌธ์ ์ฐพ์ ์คํฌ๋ฆฝํธ๋ฅผ ํ์ฑํ๋ค.
- ํ์ฑ๋จ๊ณ์์ import, export ์๋ฌ๋ฅผ ๊ฐ์งํ ์ ์๋ค.
- ๋ชจ๋์ ๋ณ๋ ฌ๋ก ๋ค์ด๋ก๋ํ์ง๋ง, ์คํ์ ์์ฐจ์ ์ผ๋ก ํ๋ค.
- import, export๋ฅผ ์ง์ํ์ง ์๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์์ด ESM ์ฌ์ฉ์ ์ํด ๋ฒ๋ค๋ฌ๊ฐ ํ์ํ๋ค.