kohigowild
JavaScript ES6 ๋ชจ๋ ๋ณธ๋ฌธ
๐ง ๋ชจ๋์ด๋?
ํ๋ก๊ทธ๋๋ฐ์์ ๋ชจ๋์ด๋ ํ๋ก๊ทธ๋จ์ ๊ตฌ์ฑํ๋ ๊ตฌ์ฑ ์์์ ์ผ๋ถ์ด๋ค.
ํ๋ก๊ทธ๋จ์ ํฌ๊ธฐ๊ฐ ์ปค์ง๋ฉด ํ์ฅ์ฑ๊ณผ ์ ์ง ๋ณด์ ์ธก๋ฉด์์ ํ์ผ์ ์ฌ๋ฌ ๊ฐ๋ก ๋ถ๋ฆฌํ๋ ์์ ์ด ์ค๋๋ฐ, ์ด๋ ๋ถ๋ฆฌ๋ ํ์ผ ๊ฐ๊ฐ์ ‘๋ชจ๋’ ์ด๋ผ ๋ถ๋ฅด๊ณ , ๋ณดํต ํด๋์ค ํ๋ ํน์ ํน์ ํ ๋ชฉ์ ์ ๊ฐ์ง ๋ณต์์ ํจ์๋ก ๊ตฌ์ฑ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ๋๋ก ๊ตฌ์ฑ๋๋ค.
ํ๋ก๊ทธ๋จ์ ์๊ฒ ์ชผ๊ฐ์ด ๋ชจ๋ํํ๋ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ํ๋ก๊ทธ๋จ์ ํจ์จ์ ์ธ ๊ด๋ฆฌ ๋ฐ ์ฑ๋ฅ ํฅ์
- ์ ์ฒด์ ์ธ ์ํํธ์จ์ด ์ดํด์ ์ฉ์ด์ฑ ์ฆ๋ ๋ฐ ๋ณต์ก์ฑ ๊ฐ์
- ์ํํธ์จ์ด ๋๋ฒ๊น , ํ ์คํธ, ํตํฉ, ์์ ์ ์ฉ์ด
- ๊ธฐ๋ฅ์ ๋ถ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๊ณ ์ธํฐํ์ด์ค๊ฐ ๋จ์
- ์ค๋ฅ์ ํ๊ธ ํจ๊ณผ๋ฅผ ์ต์ํ
- ๋ชจ๋ ์ฌ์ฌ์ฉ์ผ๋ก ๊ฐ๋ฐ๊ณผ ์ ์ง ๋ณด์ ์ฉ์ด
๐ง ๋ชจ๋์ ์ข ๋ฅ
์๋ฐ์คํฌ๋ฆฝํธ๋ CommonJS, AMD, UMD, ESM๊ณผ ๊ฐ์ ๋ชจ๋ ์์คํ ์ ์ฌ์ฉํ ์ ์๋๋ฐ, ๊ฐ ๋ชจ๋ ์์คํ ์๋ ๋ค์๊ณผ ๊ฐ์ ํน์ง์ด ์๋ค.
- CommonJS
- ์๋ฒ ์ฌ์ด๋์์ ์ฌ์ฉํ๋ฉฐ, ๋๊ธฐ์ ์ผ๋ก ์๋
- require ๋ฌธ๋ฒ ์ฌ์ฉ
- AMD
- ์๋ฒ ์ฌ์ด๋์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ ์ฌ์ฉํ ์ ์์ง๋ง ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ฉฐ, ๋น๋๊ธฐ์ ์ผ๋ก ์๋
- define - require ๋ฌธ๋ฒ ์ฌ์ฉ
- UMD
- CommonJS์ AMD๋ฅผ ๋ชจ๋ ์ฌ์ฉํ๊ธฐ ์ํ ๊ตฌํ ํจํด
- ESM
- ์ธ์ด ์์ฒด์ ํ์ค์ผ๋ก ํ์ฌ๋ ๋ชจ๋ ์์คํ
- export - import ๋ฌธ๋ฒ ์ฌ์ฉ
example CommonJS
math.js ⇒
exports function sum(a, b) { return a + b; }
app.js ⇒
const math = require("./math.js")
math.sum(1, 2) // 3
exports ํค์๋๋ก ๋ชจ๋์ ๋ง๋ค๊ณ require() ํจ์๋ก ๋ถ๋ฌ๋ค์ด๋ ๋ฐฉ์์ด๋ค. ๋ชจ๋ํ๋ ์๋์ ๊ฐ์ด ์ธ ๋ถ๋ถ์ผ๋ก ์ด๋ฃจ์ด์ง๋ค.
- ์ค์ฝํ(Scope): ๋ชจ๋ ๋ชจ๋์ ์์ ๋ง์ ๋ ๋ฆฝ์ ์ธ ์คํ ์์ญ์ด ์์ด์ผ ํ๋ค.
- ์ ์(Definition): ๋ชจ๋ ์ ์๋ exports ๊ฐ์ฒด๋ฅผ ์ด์ฉํ๋ค.
- ์ฌ์ฉ(Usage): ๋ชจ๋ ์ฌ์ฉ์ require ํจ์๋ฅผ ์ด์ฉํ๋ค.
example AMD
html ⇒
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<!-- data-main="require๊ฐ ๋ก๋๋ ํ ์คํ๋ ํ์ผ" src="requireJS์์ ๋น๋๊ธฐ๋ก ์ฌ์ฉํ ํ์ผ" -->
<script data-main="index.js" src="require.js"></script>
</body>
</html>
index.js ⇒
require.config({
// ๊ธฐ๋ณธ ๊ฒฝ๋ก
baseUrl: '/',
// ๋ชจ๋์ ํด๋นํ๋ ๊ฒฝ๋ก
paths: {
searchModule: 'searchModule',
loaderModule: 'loaderModule',
}});
// ์ฒซ๋ฒ์งธ ์ธ์์ ํด๋นํ๋ ๋ชจ๋์ด ๋ก๋๋์์ ๊ฒฝ์ฐ a๋ก ๋ฐ์์ getWord() ํจ์๋ฅผ ํธ์ถํ๋ ์ฝ๋ฐฑํจ์ ์คํ
// ์์กด์ฑ ๋ชจ๋์ ์ง์ ํด์ฃผ๋ ๊ฒ
require(['searchModule'], (searchModule) => {
searchModule.getWord();
});
searchModule.js ⇒
define(() => {
return {
getWord: () => 'word'
}
});
example UMD
(function (root, factory) {
// AMD
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
// CommonJS
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
// Browser
} else {
// Browser globals (root is window)
root.returnExports = factory();
}}(typeof self !== 'undefined' ? self : this, function () {
// Just return a value to define the module export.
// This example returns an object, but the module
// can return a function as the exported value.
return {};
}));
๐ง ESM
ESM์ ES6๋ถํฐ ์ง์ํ๊ณ ์๋ ํ์ค ๋ชจ๋ ์์คํ ์ด๋ค. ES6 ์ด์ ๊น์ง๋ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ์ฌ์ฉํ ์ ์๋ ํ์ค ๋ชจ๋ ์์คํ ์ด ์์๊ธฐ ๋๋ฌธ์, ํ์ํ ํ์ผ์ ๋ง๋ค์ด์ ๊ฐ์ด ๋ฐฐํฌํ๊ณ , <script src=”script.js”>์ ํํ๋ก ํ์ผ์ ์ง์ ๋ถ๋ฌ์ค๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
export
export๋ ๊ธฐ๋ณธ์ ์ผ๋ก named export์ default export์ ๋ ๊ฐ์ง ๋ฐฉ์๊ณผ export์ from์ ์กฐํฉํด์ ์ฌ์ฉํ๋ ๋ฐฉ์์ด ์๋ค.
named export
named export๋ ์ ์ธ๋ ๋ณ์๋ช ์ ๊ทธ๋๋ก exportํ๋ ๋ฐฉ์์ด๋ค. named export๋ ๋ชจ๋ ๋ด์ ์ฌ๋ฌ ๊ฐ์ export๊ฐ ์กด์ฌํ ์ ์๊ณ , ๋ณ์๋ฅผ ์ ์ธํจ๊ณผ ๋์์ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ํ๊ฑฐ๋, ๋จผ์ ์ ์๋ ๋ณ์๋ฅผ ๋ชจ์์ ๋ด๋ณด๋ด๊ณ , ๋จผ์ ์ ์๋ ํจ์๋ฅผ ๋ณ์นญ์ผ๋ก ๋ฐ๊ฟ์ ๋ด๋ณด๋ผ ์๋ ์๋ค.
export let name1;
export const name2;
export var name3;
export function name4 () {/*...*/}
export class MyClass {/*...*/}
const var1;
let var2;
var var3;
export { var1, var2, var3 }
let var4;
export { var4 as var5 }
default export
default export๋ ๋ชจ๋์์ ํ๋๋ง ์กด์ฌํ ์ ์๊ณ , named export์ ๊ฐ์ด ๋ณ์๋ฅผ ์ง์ ๋ด๋ณด๋ผ ์๋ ์๋ค. default export๋ฅผ default export {const, let, var} ์ฒ๋ผ ๋ณ์๋ฅผ ์ง์ ๋ด๋ณด๋ด๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
export default expression;
export default function () { /*...*/ }
export default function myFunction() { /*...*/ }
export default class { /*...*/ }
export default class MyClass { /*...*/ }
export default function* () { /*...*/ }
const myModule = { /*...*/ }
const var1 = () => {}
export { myModule as default, var1 }
export default function () { /*...*/ }
export default MyClass () { /*...*/ }
Uncaught SyntaxError: Identifier '*default*' has already been declared
export default๋ฅผ ๋ ๋ฒ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. default๋ผ๋ ์๋ณ์๋ฅผ export ๋ฌธ์ด ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค.
export from
export from์ import์ export๋ฅผ ํ ๋ฒ์ ์ฒ๋ฆฌํ ์ ์๋ ๋ฌธ๋ฒ์ด๋ค. ์ฃผ๋ก ํจํค์ง์ ๋ค๋ฅธ ๋ชจ๋๋ค์ ํ ๋ฒ์ ๋ชจ์์ ์ผ๊ด๋ ํํ๋ก ๋ด๋ณด๋ด๊ฑฐ๋ ๊ด๋ฆฌํ๊ณ ์ถ์ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ค.
export from ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ฉด import์ export๋ฅผ ํ ๋ฒ์ ์ฒ๋ฆฌํ ์ ์๋ ์ฅ์ ์ด ์์ง๋ง, ๋คexport-from์ ์ฒ๋ฆฌํ๋ ํ์ผ ์ค์ฝํ์์๋ ์๋ณ์๊ฐ ๋ฐ์ธ๋ฉ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ฉ์๋๋ ๋ณ์์ ์ง์ ์ ๊ทผํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ์๋ฌ ๋ฐ์ ์ด์ ๋ ํด๋น ๋ฉ์๋๊ฐ ์ค์ฝํ ๋ด์ ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ.
๋ค์๊ณผ ๊ฐ์ด index.js math.js logger.js config.js ๋ชจ๋์ ํฌํจํ๋ src/utils ํจํค์ง๊ฐ ์๋ค๊ณ ๊ฐ์ ํ์ ๋,
export function add (a, b) { /*...*/ }
export function subtract (a, b) { /*...*/ }
export function multiply (a, b) { /*...*/ }
export function divide (a, b) { /*...*/ }
export default {
print() { /*...*/ }
}
export const DB_HOST = 'localhost';
export const DB_USER = 'scott';
export const DB_PASSWORD = 'tiger';
src/utils ํจํค์ง์ ์๋ src/utils/index.js์์๋ export-from ๋ฌธ๋ฒ์ ๋ค์์ฒ๋ผ ํ์ฉํ ์ ์๊ณ , src/utils/index.js์์ export๋ ๋ชจ๋์ src/index.js์์ import ๋ช ๋ น์ด๋ก ๋ถ๋ฌ์์ ์ฌ์ฉํ ์ ์๋ค.
// math ๋ชจ๋์์ ์ผ๋ถ๋ง import ํ ๋ค ๋ค์ export
export { add, subtract } from './math';
// config ๋ชจ๋์ (export๊ฐ ๊ฐ๋ฅํ) ๋ชจ๋ ๋ณ์๋ฅผ export
export * from './config';
// logger ๋ชจ๋์ default export๋ฅผ Logger๋ผ๋ ์ด๋ฆ์ผ๋ก export
export { default as Logger } from './logger';
// ๋๋ ํ ๋ฆฌ๋ฅผ importํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก index.js ํ์ผ์ ํ์ํจ
import * as utils from './utils';
// utils๋ผ๋ ๋ณ์นญ์ผ๋ก importํ ๋ฉ์๋, ๋ณ์ ์ฌ์ฉ
utils.add(1, 2) // 3
utils.DB_HOST // 'localhost'
utils.Logger.print('TEST') // 'TEST'
import
import๋ ๋ค๋ฅธ ํ์ผ์์ ๋ชจ๋์ ๋ถ๋ฌ์ค๋ ๋ช ๋ น์ด์ด๋ค. as ๋ช ๋ น์ด๋ฅผ ์ด์ฉํด์ ๋ณ์นญ์ผ๋ก ๋ถ๋ฌ์ค๊ฑฐ๋, *๋ฅผ ์ฌ์ฉํด์ named export์ ๋ชจ๋ ๋ณ์์ ๋ฉ์๋๋ฅผ ๋ถ๋ฌ์ฌ ์ ์๋ค.
import name from "module-name";
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
import defaultMember, * as alias from "module-name";
import defaultMember from "module-name";
import "module-name";
๐ง Module Type
<script> ํ๊ทธ์ type = “module” ์ ์ ์ธํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ๋ชจ๋๋ก ๋์ํ๊ฒ ๋๋ค. ESM์ ECMAScript์์ ์ง์ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ณต์ ๋ชจ๋ ์์คํ ์ด์ง๋ง, ๋ธ๋ผ์ฐ์ ์ ๋ฐ๋ผ์๋ ์์ง import์ export๋ฅผ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ๋ ์์ด์ ๊ฐ๋ฅํ๋ฉด webpack๊ณผ ๊ฐ์ ๋ฒ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
๐ง Webpack
์นํฉ์ ์คํ ์์ค ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋ ๋ฒ๋ค๋ฌ๋ก์จ ์ฌ๋ฌ ๊ฐ๋ก ๋๋์ด์ ธ ์๋ ํ์ผ๋ค์ ํ๋์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ์์ถํ๊ณ ์ต์ ํํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
๋ชจ๋ ๋ฒ๋ค๋ฌ๋ ๋ค์๊ณผ ๊ฐ์ ์ฅ์ ์ด ์๋ค.
- ์ฌ๋ฌ ํ์ผ์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์์ถํ์ฌ ์ต์ ํํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ก๋ฉ์ ๋ํ ๋คํธ์ํฌ ๋น์ฉ ๊ฐ์
- ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ ์ง์ํ์ง ์๋ ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉํ ์ ์๋ ์ฝ๋๋ก ์ฝ๊ฒ ๋ณํ
์นํฉ์ entry๋ก ์ค์ก๋ ์์์ ์์ ์์กด์ฑ์ ๊ฐ์ง ๋ชจ๋ ํ์ผ์ ์์ถํ์ฌ output ์ง์ ์ ํ๋์ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ๋ง๋ค์ด ์ค๋ค. ์ด๋, ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ์๋ ํ์ผ์ loaders๋ฅผ ์ด์ฉํ์ฌ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ด์ฉ ๊ฐ๋ฅํ ๋ชจ๋๋ก ๋ง๋ค์ด ์ฃผ๋ฉฐ, plugins๋ฅผ ์ด์ฉํ์ฌ ๋ฒ๋ค๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋๋ ํํ๊ฑฐ๋ ํน์ ํ ์คํธ๋ฅผ ์ถ์ถํ๋ ์ญํ ์ ํ๋ค. mode๋ ์นํฉ์ ์ฌ์ฉ ๋ชฉ์ ์ ๋ฐ๋ผ ์ค์ ์ ์ง์ ํ๋ ์ญํ ์ ํ๋ค.
๐ง Reference
https://medium.com/@woody_dev/js-webpack-1-์นํฉ์ด๋-๋ฌด์์ธ๊ฐ-f29ebca31da4
https://wormwlrm.github.io/2020/08/12/History-of-JavaScript-Modules-and-Bundlers.html
https://www.daleseo.com/js-module-import/
https://velog.io/@syoung125/๊ฐ๋ ๊ณต๋ถ-1.-Javascript
https://www.zerocho.com/category/JavaScript/post/5b67e7847bbbd3001b43fd73
https://www.youdad.kr/js-module-system/
https://okayoon.tistory.com/entry/์ํฐํด-ํ๋ก์ ํธ-059-๋ชจ๋-์์คํ -CommonJS-AMD-UMD-ES6
'JavaScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JavaScript fetch() (0) | 2022.11.27 |
---|---|
JavaScript ๋ฌธ์ ๊ฐ์ฒด ๋ชจ๋ธ(DOM) (0) | 2022.11.16 |
JavaScript ํ๋กํ ํ์ ๊ณผ ํ๋กํ ํ์ ์ฒด์ธ (0) | 2022.10.21 |
JavaScript ํ(Queue), ์คํ(Stack), ํธ๋ฆฌ(Tree) (0) | 2022.10.20 |
JavaScript ์ ๊ท ํํ์(Regular Expression) (0) | 2022.10.16 |