{"version":3,"sources":["webpack:///./content/pages/293-module.mdx"],"names":["_frontmatter","layoutProps","MDXLayout","DefaultLayout","MDXContent","components","props","mdxType","parentName","isMDXComponent"],"mappings":"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","file":"component---content-pages-293-module-mdx-3233e742dfdc5dfb21c1.js","sourcesContent":["import * as React from 'react'\n /* @jsx mdx */\nimport { mdx } from '@mdx-js/react';\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\n\nimport DefaultLayout from \"/opt/build/repo/node_modules/@primer/gatsby-theme-doctocat/src/components/layout.js\";\nexport const _frontmatter = {};\nconst layoutProps = {\n _frontmatter\n};\nconst MDXLayout = DefaultLayout;\nexport default function MDXContent({\n components,\n ...props\n}) {\n return \n\n\n

{`최근들어 프론트엔드 프로젝트의 규모가 커짐에 따라, JavaScript 코드를 `}{`여러 파일과 폴더에 나누어 작성`}{`하고 `}{`서로가 서로를 효율적으로 불러올 수 있도록`}{` 해주는 시스템의 필요성이 절실해졌습니다. 이에 따라 모듈 시스템이 ES2015에 추가되었습니다.`}

\n

{`ES2015 모듈은 최근에 (Chrome 61, FF 60, SF 10.1) 브라우저에서 사용할 수 있게 되었습니다. `}{`script`}{` 태그에 `}{`type=\"module\"`}{` 어트리뷰트를 추가해주면, 이 파일은 모듈로서 동작합니다. 파일 확장자로는 대개 `}{`mjs`}{`가 사용됩니다.`}

\n
{`\n`}
\n

{`다만 모듈은 이전까지의 JavaScript 파일의 동작방식과는 다른 동작방식을 가지고 있고, 모듈이 제대로 동작하려면 `}{`몇 가지 조건`}{`을 충족시켜야 해서 사용법이 복잡하며, 구형 브라우저는 모듈을 지원하지 않는다는 문제가 있어 아직은 브라우저에 내장된 모듈 기능을 사용하는 경우가 많지 않습니다. 대신 Webpack, Parcel 등의 모듈 번들러를 통해 변환과정을 거친 뒤, 브라우저에는 일반적인 JavaScript 파일로서 불러오는 방법이 널리 사용되고 있는 추세입니다.`}

\n

{`모듈이란?`}

\n

{`ES2015 모듈은 기본적으로 JavaScript 코드를 담고 있는 `}{`파일`}{`입니다. 다만 일반적인 JavaScript 파일과는 다른 여러가지 차이점을 갖고 있습니다.`}

\n \n

{`모듈 스코프`}

\n

{`모듈 내부의 가장 바깥 스코프에서 이름을 선언하더라도, 전역 스코프가 아니라 `}{`모듈 스코프`}{`에서 선언됩니다. 모듈 스코프에 선언된 이름은 (export 해주지 않는다면) 해당 모듈 내부에서만 접근할 수 있습니다.`}

\n
{`// variables.js\n\nconst foo = 'bar';\n\n// 이 파일이 모듈로서 사용되고 있다면, \\`undefined\\`가 출력됩니다.\nconsole.log(window.foo);\n`}
\n

{`따라서 여러 모듈의 가장 바깥쪽에서 같은 이름으로 변수, 함수, 클래스를 선언하더라도, 서로 다른 스코프에서 선언되기 때문에 이름의 충돌이 생길 일이 없습니다.`}

\n

{`export & import`}

\n

{`모듈 스코프에서 정의된 이름은 `}{`export`}{` 구문을 통해 다른 파일에서 사용할 수 있습니다. 이를 `}{`'이름이 지정된 export'`}{`라는 뜻에서 `}{`named export`}{`라 부릅니다.`}

\n
{`// variables.js\nconst foo = 'bar';\nconst spam = 'eggs';\n\n// foo, spam을 다른 파일에서 사용할 수 있도록 export 해주었습니다.\nexport { foo, spam };\n`}
\n

{`위에서 `}{`export`}{`된 이름을 다른 파일에서 `}{`import`}{` 구문을 통해 가져온 뒤 사용할 수 있습니다.`}

\n
{`// main.js\n\n// variables 모듈에 선언된 이름을 사용하기 위해 import 해주었습니다.\nimport { foo, spam } from './variables.js';\n\nconsole.log(foo);\nconsole.log(spam);\n`}
\n

{`단순히 값을 저장하고 있는 변수뿐만 아니라, 함수나 클래스도 `}{`export`}{`를 통해 여러 모듈에서 재사용할 수 있습니다.`}

\n
{`// functions.js\n\nfunction add(x, y) {\n  return x + y;\n}\n\nclass Person {\n  // ...\n}\n\nexport { add, Person };\n`}
\n

{`다른 모듈에 있는 이름을 사용하려면, 반드시 해당 모듈에서 `}{`이름`}{`을 `}{`export`}{` 해주어야 합니다. `}{`export`}{` 해주지 않은 이름을 다른 모듈에서 `}{`import`}{` 하면 의도대로 동작하지 않습니다. (모듈 실행 환경에 따라 에러가 날 수도 있고, 이름에 `}{`undefined`}{`가 들어있을 수도 있습니다.)`}

\n
{`// variables.js\n\nconst foo = 'bar'\n`}
\n
{`// main.js\nimport { foo } from './variables.js';\n\nconsole.log(foo); // 에러가 나거나, \\`undefined\\`가 출력됨\n`}
\n

{`선언과 동시에 export 하기`}

\n

{`이름을 선언하는 구문 앞에 `}{`export`}{`를 붙여주면, 선언과 `}{`export`}{`를 한꺼번에 할 수 있습니다.`}

\n
{`// common.js\nexport const foo = 'bar';\nexport const spam = 'eggs';\nexport function add(x, y) {\n  return x + y;\n}\nexport class Person {\n  // ...\n}\n`}
\n

{`default export`}

\n

{`export default`}{` 구문을 통해, 모듈을 대표하는 하나의 `}{`값`}{`을 지정하고 그 값을 다른 모듈에서 편하게 불러와서 사용할 수 있습니다. 이렇게 사용하는 값을 `}{`default export`}{`라고 부릅니다.`}

\n
{`// foo.js\n\nexport default 'bar';\n`}
\n

{`import`}{` 구문에서 이름을 적어주는 부분에 중괄호를 생략하면, 모듈의 default export를 가져옵니다.`}

\n
{`// main.js\n\nimport foo from './foo.js'\n\nconsole.log(foo); // bar\n`}
\n

{`export default`}{` 뒤에는 임의의 표현식이 올 수 있습니다. 즉, 함수 표현식이나 클래스 표현식도 올 수 있습니다.`}

\n
{`// add.js\n\nexport default function (x, y) {\n  return x + y;\n}\n`}
\n
{`import add from './add.js';\n\nconsole.log(add(1, 2)); // 3\n`}
\n

{`import`}{` 구문에서 default export와 일반적인 export를 동시에 가져올 수 있습니다.`}

\n
{`// \\`React\\`라는 이름의 default export와,\n// Component, Fragment라는 일반적인 export를 동시에 가져오기\nimport React, { Component, Fragment } from 'react';\n`}
\n

{`다른 이름으로 export & import 하기`}

\n

{`export`}{` 혹은 `}{`import`}{` 하는 이름의 뒤에 `}{`as`}{`를 붙여서, 다른 이름이 대신 사용되게 할 수 있습니다.`}

\n
{`const foo = 'bar';\n\nexport { foo as FOO }; // FOO 라는 이름으로 export 됩니다.\n`}
\n
{`import { Component as Comp } from 'react'; // Comp라는 이름으로 import 됩니다.\n`}
\n

{`모듈 사용 시 주의할 점`}

\n

{`이제까지 모듈 시스템의 문법을 배워봤습니다. 여기서 주의할 점이 한 가지 있습니다. `}{`import`}{` 구문과 `}{`export`}{` 구문은 모듈 간 의존 관계를 나타내는 것일 뿐, 코드를 실행시키라는 명령이 아니라는 것입니다.`}

\n \n

{`ES2015 이전의 모듈들`}

\n

{`사실 ES2015가 JavaScript 생태계에서 사용된 첫 모듈 시스템은 아닙니다. ES2015 모듈 이전에 CommonJS, AMD 등의 모듈 시스템이 있었고, 이 모듈 시스템들도 실제로 널리 사용되었던 시기가 있습니다. 다른 모듈 시스템의 특징과 역사가 궁금하시다면 `}{`이 글`}{`을 읽어보세요.`}

\n\n
;\n}\n;\nMDXContent.isMDXComponent = true;\n "],"sourceRoot":""}