[React]webpack 설정하기

Edit

[React]webpack 설정하기


최근에 뜨고 있는 Webpack은 프론트의 테스트크를 자동으로 수행해주는 아주 고마운 녀석이다. 기존의 Gulp, Grunt가 가지지 못한 여러 장점들이 많아 프론트 개발자들이 많이 쓰고 있지만, 명성에 비해 쓰레기같은 공식 문서를 가지고 있다.(프론트 개발자들은 공감할 것.) 이번 글에서는 Webpack의 알짜배기에 초첨을 맞추어 고급 기능을 다뤄보고자 한다.

프론트 기술은 눈 깜빡할 새에 새로운 녀석들이 나온다. 그만큼 트랜드가 계속 바뀌는게 프론트 세상인데, 프론트를 공부하는 사람들은 이러한 트랜드 속에서 살아 남기 위해서 끊임없이 공부를 해야한다. 공부 해야할 양이 많아 질수록 새로운 기술에 대한 핵심을 이해하고 있어야하는데 두 가지 질문을 항상 마음 속에 품고 있어야한다. 첫번째는 “이것이 왜 존재할까?"이고 두번째는 “이 기술이 어떤 문제점을 해결해줄까?"이다. 두 가지 질문에 대답 할 수 없는 기술이라면 굳이 배울 필요는 없을 것이다. 따라서 Webpack를 이러한 관점에 대해 알아보자.

Webpack이란게 왜 있는것일까? Webpack을 한 단어로 표현하자면 코드 Bundler이다. 코드를 가져 와서 변환하고 Bundle 한 다음 새로운 버전의 코드를 반환한다.

그럼 이번에는 Webpack이 어떤 문제점을 해결해줄까? SASS 또는 LESS와 같은 CSS 전처리기를 사용한 적이 있다면 SASS / Less 코드를 일반 CSS로 변환해야 한다는 것은 알고 있을 것이다. TypeScript 나 다른 자바 스크립트 언어를 사용 해본 적이 있다면 변환 단계가 있다는 것을 알고 있을 것이다. Webpack이 정말 좋은 점은 다양한 종류의 코드를 목표로하는 것으로 변환 시킬 수 있다는 것이다. 코드를 작성하여 해당 변경 사항을 실시간으로 출력 할 수도 있다.

이번 글에서는 Webpack 구성을 매우 가볍게 다룰 예정이지만, 향후 좀 더 고급 주제를 다루어 보도록 하자.

위에서 언급 한 프로세스에 대해 다시 생각해 보자. 코드를 가져 와서 변환하는 단계에서 3 가지 주요 단계와 3 가지 주요 사항이 있다.

  1. Webpack은 웹 어플리케이션의 시작 지점 또는 루트 JavaScript 파일을 바라보고 있어야 한다.
  2. Webpack은 코드를 어떤 것으로 변환을 할 것인지를 알아야 한다.
  3. Webpack은 새로게 변환한 코드를 저장할 위치를 알아야 한다.

사실 위의 3가지만 숙지하고 있다면 Webpack은 별게 아니다.

첫번째 해야할 일은 Webpack 구성을 포함 할 파일을 만드는 것이다. 이 파일의 이름은 Webpack이 인식 할 수 있도록 이름이 webpack.config.js로 정해져 있다. 이 파일은 프로젝트의 루트 리렉토리에 있어야 한다.

이제 webpack.config.js 파일을 만들었고, 이 파일이 Webpack의 구성을 나타낼 object를 제대로 내보내는지 확인해야합니다. 자바스크립트 모듈에 익숙하지 않다면 Preethi의 블로그 시리즈를 먼저 읽어보고 오자.

// In webpack.config.js
module.exports = {}

이제 위의 언급대로 코드로 변환해보자. 먼저, Webpack에 어플리케이션의 진입 지점을 알려주자.

// In webpack.config.js
module.exports = {
entry: [
'./app/index.js'
]
}

위에서 한 것은 객체에 entry 속성과 그 값을 정해준 것이다. 여기서 값이 왜 문자열이 아닌 배열인지 궁금할 수 있을 것이다. Webpack을 사용하면 어플리케이션에서 하나 이상의 entry 포인트를 가질 수 있기 때문에 더 많은 정보를 담기 위해서 배열을 사용했다. (물론 배열을 안 써도 되지만 습관을 위해 배열을 쓰자) 이렇게 하면 나중에 추가 시 쉽게 추가 할 수 있다.

여기까지는 Webpack에게 어디에서 시작해야 한다고 알려주었고, 이제 코드를 변형을 해야한다.이 변형에는 loader라는 것을 사용한다.

loader는 타켓 파일의 종류에 맞춰어서 준비하면 된다. TypeScript면 그거에 맞는 loader를 CoffeeScript면 그거에 맞는 loader를 사용하면 된다. 사용처에 맞게 loader를 설치할 것인데 npm을 사용하자. 이 글에서는 예제로 CoffeeScript를 변환 시킬 것이다. 터미널에서 다음과 같이 loader를 설치하자.

$ npm install --save-dev coffee-loader

이를 실행하면 coffee-loader가 package.json 파일의 dev 종속 파일로 저장된다. 그런 다음 webpack.config.js 파일을 반영시켜주자. 이를 위해 먼저 webpack.config.js에서 내보내는 객체에 모듈 속성을 추가한다.

// In webpack.config.js
module.exports = {
entry: [
'./app/index.js'
],
module: {
loaders: []
}
}

loader 배열 내부에는 원하는 모든 loader를 넣을 것이다.

각 loader는 세 가지로 구성되어야 한다. 첫 번째는 특정 변환을 실행할 파일 유형이다. 예를 들어, 자바스크립트 파일에서 자바스크립트로만 변환할 수 있도록 하는 것이다. 다음은 변환 할 디렉토리를 포함하거나 제외해야하는 항목이다. 여기서는 node_modules 폴더의 모든 항목에 대해 변환을 실행하지 않으므로 node_modules 경로를 제외 값으로 사용하자. 마지막으로 실행하고자하는 특정 loader이다. 예로 들면 아래와 같다.

// In webpack.config.js
module.exports = {
entry: [
'./app/index.js'
],
module: {
loaders: [
{test: /\.coffee$/, exclude: /node_modules/, loader: "coffee-loader"}
]
},
}

위에서 눈여겨봐야 할 것은 정규식이다. test에 있는 / \. coffee $ / 을 사용하게 되면 Webpack이 .coffee로 끝나는 모든 확장 프로그램에서 coffe-loader를 실행하게 된다.

다음으로, exclude는 변환에서 제외시킬 것을 나타낸다. 앞서 말했듯이 node_modules 폴더를 변형하고 싶지 않기 때문에 제외한다. 마지막으로는 loader로 Webpack에게 test의 정규식과 일치하고 exclude에 없는 모든 경로에서 실행될 변환을 지시한다.

만약 여러 loader를 추가할려면 npm으로 loader를 설치하고 loader 배열에 추가해주면 된다.

이제 마지막 단계로 새로운 변환 된 코드를 출력해야 하는 위치를 지정해주자.

// In webpack.config.js
module.exports = {
entry: [
'./app/index.js'
],
module: {
loaders: [
{test: /\.coffee$/, exclude: /node_modules/, loader: "coffee-loader"}
]
},
output: {
filename: "index_bundle.js",
path: __dirname + '/dist'
},
}

위의 코드를 보면 filename은 새로운 변환 된 코드가 포함 된 Webpack이 만들 파일의 이름이다. path는 새 파일 이름 (여기서는 index_bundle.js)이 배치 될 디렉토리이다. 참고로 __dirname는 현재 실행 중인 스크립트의 상위 디렉토리 이름이다.

이제 Webpack이 실행 시키면, 코드가 변형되어 ourApp / dist / index_bundle.js에서 참조할 수 있게 된다. 이제 HTML 파일이 index_bundle.js를 참조하도록 해보자. 일반 앱의 일반적으로 구조는 다음과 같을 것이다.

/app
- components
- containers
- config
- utils
index.js
index.html
/dist
index.html
index_bundle.js
package.json
webpack.config.js
.gitignore

보통 개발 중인 코드는 app 폴더에 두고 변형 후 배포에 사용할 코드는 dist 폴더에 있다. 여기서 한가지 문제점이 생기는데 app 폴더에있는 index.html을 변경할 때이다. 브라우저가 실제로 사용하게 될 index.html 파일은 dist 폴더 내의 파일이기 때문에 app 안의 html 파일을 옮겨주어야 한다.

이를 위해 두가지 방법이 있는데, 첫번째 방법은 두 개의 index.html 파일을 관리하는 것이다. app에 있는 파일을 변경할 때마다 dist에 있는 파일로 직접 복사하는 것이다. 하지만 이 방법은 너무 무식한 방법이다.

두 번째 옵션은 Webpack이 실행될 때마다 /app/index.html이 /dist/index.html에 복사되도록하는 방법이다. 첫번째 방법보다 훨씬 깔끔하고 손이 덜 가는 방법이다.

두번째 일 Webpack tool에 이미 존재한다. 바로 html-webpack-plugin이다. npm으로 마찬가지로 설치해주자.

npm install --save-dev html-webpack-plugin

우선, HTMLWebpackPlugin의 새 인스턴스를 만든 후 세 가지를 지정해야 한다. 먼저, 새로 생성 된 파일이 어떻게 보이길 원하는지에 대한 템플릿을 제공해야한다. 두번째는, 파일 이름을 지정하거나, 생성한 새 파일을 호출합니다. 셋번째는 WebpackPluginConfig로 통해 변환 된 코드의 출력 파일 이름을 감지시키는 것이다, (여기서는 index_bundle.js). 그런 다음 또는 에 스크립트를 삽입해야한다. 새로 생성 된 index.html 파일에 injection으로, 스크립트를 head 또는 body에 삽입하면 된다.

정리하면 아래와 같다.

// In webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin')
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: [
'./app/index.js'
],
module: {
loaders: [
{test: /\.coffee$/, exclude: /node_modules/, loader: "coffee-loader"}
]
},
output: {
filename: "index_bundle.js",
path: __dirname + '/dist'
},
plugins: [HTMLWebpackPluginConfig]
};

파일의 맨 위에 HtmlWebpackPlugin의 새 인스턴스를 만들고 요놈은 세 가지 옵션을 제공한다. template은 앱 디렉토리에있는 일반 index.html 파일을 가리킨다. filename은 index.html으로 기존 파일 이름과 동일하게 지었다. inject는 loader의 출력 파일 (index_bundle.js)의 이름을 참조하는 스크립트를 삽입하여 새로 생성 된 html 파일의 본문에 삽입한다. 마지막으로 작성한 HTMLWebpackPluginConfig 변수를 webpack config의 플러그인 배열에 항목으로 추가한다.

이제 Webpack을 실행하면 dist 폴더 안에 두 개의 파일이 생긴다. index_bundle.jsindex.html가 생겼을 것이다. index_bundle.jsentry 코드를 가져 와서 loader를 통해 실행 한 결과이다. index.htmlHTMLWebpackPluginConfig를 거쳐 만들어진 파일이다.

dist의 내부에 새로 생성 된 index.html 파일이 어떻게 생겼는지, app 폴더 안의 index.html 와 비교해보자.

app/index.html


<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Apptitle>

<link rel="stylesheet" href="styles.css">
head>
<body>
<div id="app">div>
body>
html>

dist/index.html


<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Apptitle>

<link rel="stylesheet" href="styles.css">
head>
<body>
<div id="app">div>
<script src="index_bundle.js">script>
body>
html>

두 파일의 차이점은 dist (HTMLWebpackPlugin으로 생성된 파일)에 index_bundle.js를 가리키는 script 태그가 있다는 것이다. 다시 말하지만 HTMLWebpackConfig가 Webpack에서 새로 생성 된 파일의 출력 파일 이름을 감지하고 새로 만든 index.html 파일의 스크립트로 자동 추가한 것이다. 위의 index.html 파일에서 볼 수 있듯이 body에는 가 있다. Webpack 설정에서 출력을 test.js로 변경했다면 새로 생성 된 index.html 파일의 body 안에 가 생겼을 것이다.

이제 거의 다 끝났다 마지막으로는 Webpack에 실제로 실행하는 방법이다. Webpack이 설치되어 있지 않았다면 다음과 같이 설치해주자.

$ npm install -g webpack

Webpack을 설치를 하면 Webpack CLI에 접근 할 수 있다. (만약 local에 설치했다면 npm으로 실행시켜줘야 한다.)

어플리케이션의 루트 디렉토리 (여기서는 webpack.config.js의 위치)에서 Webpack을 터미널로 실행할 수 있다. 실행 시 Webpack 설정이 한 번 실행된다. 하지만 파일이 여러번 수정될 경우마다 Webpack을 매번 실행 시켜줘야하는데 그러기에는 너무 귀찮다. Webpack은 watch라는 기능을 제공하는데 파일이 변경 될 때마다 실시간으로 Webpack을 실행 시켜주는 기능이다.

$ webpack -w

배포 단계로 내놓을려면 다음을 실행 시 변환과 코드 축소가 실행된다.

$ webpack -p

사실 Webpack만 보고 왔다면 여기까지 해도 된다. 하지만 최종 목표는 React 관리를 Webpack으로 하는 것이기 때문에 Babal이라는 것을 loader로 추가해야 한다.

Babel.js는 자바스크립트를 컴파일 도구인데, Webpack을 사용하면 바벨이 특정 변환 자체 인 동안 코드에서 어떤 변환을 수행할지 지정할 수 있다. React의 관점에서 바벨은 JSX 를 실제 JavaScript로 변형 할 수 있게 한다. Babel이 좋은 점은 JSX -> JS 변형 외에도 많은 용도로 사용할 수 있다는 것이다. Javascript도 놀랍게도 버전들이 존재하는데 최신 Javascript랑 우리가 알고 있는 Javascript랑은 차이점이 매우 많다. 이에 따라 브라우저가 최신 Javascript를 못 따라오는 현상이 발생했는데 이를 Babel이라는 놈이 바로 잡아주는 것이다. 최신 JavaScript (ES2015, 2016 등)을 브라우저가 알고 있는 Javascript로 변환 시켜 브라우저가 이해할 수 있도록 해준다.

babel 설치도 npm으로 해주면 된다. babel은 여러 모듈로 구성되어 있기 때문에 설치 전에 몇 가지를 설치해야 한다.

$ npm install --save-dev babel-core babel-loader babel-preset-react

babel-core는 babel 자체이고, babel-loader는 사용할 Webpack loader이며, babel-preset-react는 JSX -> JS 변형을 도와준다.

위의 세가지 모듈을 Webpack에 추가해줘도 되지만 굳이 그럴 필요가 없다. babel 설정을 위해 별도의 파일로 관리하면 된다.

먼저 webpack.config.js 파일이 있는 루트 디렉토리에 .babelrc 파일을 만들어주자.

{
"presets": [
"react"
]
}

여기서는 babel 변환이 실제로 만들어 내는 babel loader에 지시하는 것이다. 좀 전에 babel-preset-react를 설치해줬기 때문에 react로 설정해주면 된다.

이제 babel-loaderwebpack.config.js의 loader에 추가해주면 된다.

// In webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin')
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: [
'./app/index.js'
],
output: {
path: __dirname + '/dist',
filename: "index_bundle.js"
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"}
]
},
plugins: [HTMLWebpackPluginConfig]
};
%23%23%23%5BReact%5Dwebpack%20%uC124%uC815%uD558%uAE30%0A@%28React%29%5Breact%7Cwebpack%5D%0A%uCD5C%uADFC%uC5D0%20%uB728%uACE0%20%uC788%uB294%20Webpack%uC740%20%uD504%uB860%uD2B8%uC758%20%uD14C%uC2A4%uD2B8%uD06C%uB97C%20%uC790%uB3D9%uC73C%uB85C%20%uC218%uD589%uD574%uC8FC%uB294%20%uC544%uC8FC%20%uACE0%uB9C8%uC6B4%20%uB140%uC11D%uC774%uB2E4.%20%uAE30%uC874%uC758%20Gulp%2C%20Grunt%uAC00%20%uAC00%uC9C0%uC9C0%20%uBABB%uD55C%20%uC5EC%uB7EC%20%uC7A5%uC810%uB4E4%uC774%20%uB9CE%uC544%20%uD504%uB860%uD2B8%20%uAC1C%uBC1C%uC790%uB4E4%uC774%20%uB9CE%uC774%20%uC4F0%uACE0%20%uC788%uC9C0%uB9CC%2C%20%uBA85%uC131%uC5D0%20%uBE44%uD574%20%uC4F0%uB808%uAE30%uAC19%uC740%20%uACF5%uC2DD%20%uBB38%uC11C%uB97C%20%uAC00%uC9C0%uACE0%20%uC788%uB2E4.%28%uD504%uB860%uD2B8%20%uAC1C%uBC1C%uC790%uB4E4%uC740%20%uACF5%uAC10%uD560%20%uAC83.%29%20%uC774%uBC88%20%uAE00%uC5D0%uC11C%uB294%20Webpack%uC758%20%uC54C%uC9DC%uBC30%uAE30%uC5D0%20%uCD08%uCCA8%uC744%20%uB9DE%uCD94%uC5B4%20%uACE0%uAE09%20%uAE30%uB2A5%uC744%20%uB2E4%uB904%uBCF4%uACE0%uC790%20%uD55C%uB2E4.%0A%0A%uD504%uB860%uD2B8%20%uAE30%uC220%uC740%20%uB208%20%uAE5C%uBE61%uD560%20%uC0C8%uC5D0%20%uC0C8%uB85C%uC6B4%20%uB140%uC11D%uB4E4%uC774%20%uB098%uC628%uB2E4.%20%uADF8%uB9CC%uD07C%20%uD2B8%uB79C%uB4DC%uAC00%20%uACC4%uC18D%20%uBC14%uB00C%uB294%uAC8C%20%uD504%uB860%uD2B8%20%uC138%uC0C1%uC778%uB370%2C%20%uD504%uB860%uD2B8%uB97C%20%uACF5%uBD80%uD558%uB294%20%uC0AC%uB78C%uB4E4%uC740%20%uC774%uB7EC%uD55C%20%uD2B8%uB79C%uB4DC%20%uC18D%uC5D0%uC11C%20%uC0B4%uC544%20%uB0A8%uAE30%20%uC704%uD574%uC11C%20%uB04A%uC784%uC5C6%uC774%20%uACF5%uBD80%uB97C%20%uD574%uC57C%uD55C%uB2E4.%20%uACF5%uBD80%20%uD574%uC57C%uD560%20%uC591%uC774%20%uB9CE%uC544%20%uC9C8%uC218%uB85D%20%uC0C8%uB85C%uC6B4%20%uAE30%uC220%uC5D0%20%uB300%uD55C%20%uD575%uC2EC%uC744%20%uC774%uD574%uD558%uACE0%20%uC788%uC5B4%uC57C%uD558%uB294%uB370%20%uB450%20%uAC00%uC9C0%20%uC9C8%uBB38%uC744%20%uD56D%uC0C1%20%uB9C8%uC74C%20%uC18D%uC5D0%20%uD488%uACE0%20%uC788%uC5B4%uC57C%uD55C%uB2E4.%20%uCCAB%uBC88%uC9F8%uB294%20%22%uC774%uAC83%uC774%20%uC65C%20%uC874%uC7AC%uD560%uAE4C%3F%22%uC774%uACE0%20%uB450%uBC88%uC9F8%uB294%20%22%uC774%20%uAE30%uC220%uC774%20%uC5B4%uB5A4%20%uBB38%uC81C%uC810%uC744%20%uD574%uACB0%uD574%uC904%uAE4C%3F%22%uC774%uB2E4.%20%20%uB450%20%uAC00%uC9C0%20%uC9C8%uBB38%uC5D0%20%uB300%uB2F5%20%uD560%20%uC218%20%uC5C6%uB294%20%uAE30%uC220%uC774%uB77C%uBA74%20%uAD73%uC774%20%uBC30%uC6B8%20%uD544%uC694%uB294%20%uC5C6%uC744%20%uAC83%uC774%uB2E4.%20%uB530%uB77C%uC11C%20Webpack%uB97C%20%uC774%uB7EC%uD55C%20%uAD00%uC810%uC5D0%20%uB300%uD574%20%uC54C%uC544%uBCF4%uC790.%0A%0AWebpack%uC774%uB780%uAC8C%20%uC65C%20%uC788%uB294%uAC83%uC77C%uAE4C%3F%20Webpack%uC744%20%uD55C%20%uB2E8%uC5B4%uB85C%20%uD45C%uD604%uD558%uC790%uBA74%20%uCF54%uB4DC%20%60Bundler%60%uC774%uB2E4.%20%uCF54%uB4DC%uB97C%20%uAC00%uC838%20%uC640%uC11C%20%uBCC0%uD658%uD558%uACE0%20Bundle%20%uD55C%20%uB2E4%uC74C%20%uC0C8%uB85C%uC6B4%20%uBC84%uC804%uC758%20%uCF54%uB4DC%uB97C%20%uBC18%uD658%uD55C%uB2E4.%0A%0A%uADF8%uB7FC%20%uC774%uBC88%uC5D0%uB294%20Webpack%uC774%20%uC5B4%uB5A4%20%uBB38%uC81C%uC810%uC744%20%uD574%uACB0%uD574%uC904%uAE4C%3F%20SASS%20%uB610%uB294%20LESS%uC640%20%uAC19%uC740%20CSS%20%uC804%uCC98%uB9AC%uAE30%uB97C%20%uC0AC%uC6A9%uD55C%20%uC801%uC774%20%uC788%uB2E4%uBA74%20SASS%20/%20Less%20%uCF54%uB4DC%uB97C%20%uC77C%uBC18%20CSS%uB85C%20%uBCC0%uD658%uD574%uC57C%20%uD55C%uB2E4%uB294%20%uAC83%uC740%20%uC54C%uACE0%20%uC788%uC744%20%uAC83%uC774%uB2E4.%20TypeScript%20%uB098%20%uB2E4%uB978%20%uC790%uBC14%20%uC2A4%uD06C%uB9BD%uD2B8%20%uC5B8%uC5B4%uB97C%20%uC0AC%uC6A9%20%uD574%uBCF8%20%uC801%uC774%20%uC788%uB2E4%uBA74%20%uBCC0%uD658%20%uB2E8%uACC4%uAC00%20%uC788%uB2E4%uB294%20%uAC83%uC744%20%uC54C%uACE0%20%uC788%uC744%20%uAC83%uC774%uB2E4.%20Webpack%uC774%20%uC815%uB9D0%20%uC88B%uC740%20%uC810%uC740%20%uB2E4%uC591%uD55C%20%uC885%uB958%uC758%20%uCF54%uB4DC%uB97C%20%uBAA9%uD45C%uB85C%uD558%uB294%20%uAC83%uC73C%uB85C%20%uBCC0%uD658%20%uC2DC%uD0AC%20%uC218%20%uC788%uB2E4%uB294%20%uAC83%uC774%uB2E4.%20%uCF54%uB4DC%uB97C%20%uC791%uC131%uD558%uC5EC%20%uD574%uB2F9%20%uBCC0%uACBD%20%uC0AC%uD56D%uC744%20%uC2E4%uC2DC%uAC04%uC73C%uB85C%20%uCD9C%uB825%20%uD560%20%uC218%uB3C4%20%uC788%uB2E4.%0A%0A%uC774%uBC88%20%uAE00%uC5D0%uC11C%uB294%20Webpack%20%uAD6C%uC131%uC744%20%uB9E4%uC6B0%20%uAC00%uBCCD%uAC8C%20%uB2E4%uB8F0%20%uC608%uC815%uC774%uC9C0%uB9CC%2C%20%uD5A5%uD6C4%20%uC880%20%uB354%20%uACE0%uAE09%20%uC8FC%uC81C%uB97C%20%uB2E4%uB8E8%uC5B4%20%uBCF4%uB3C4%uB85D%20%uD558%uC790.%0A%0A%uC704%uC5D0%uC11C%20%uC5B8%uAE09%20%uD55C%20%uD504%uB85C%uC138%uC2A4%uC5D0%20%uB300%uD574%20%uB2E4%uC2DC%20%uC0DD%uAC01%uD574%20%uBCF4%uC790.%20%uCF54%uB4DC%uB97C%20%uAC00%uC838%20%uC640%uC11C%20%uBCC0%uD658%uD558%uB294%20%uB2E8%uACC4%uC5D0%uC11C%203%20%uAC00%uC9C0%20%uC8FC%uC694%20%uB2E8%uACC4%uC640%203%20%uAC00%uC9C0%20%uC8FC%uC694%20%uC0AC%uD56D%uC774%20%uC788%uB2E4.%0A%0A%3E%201.%20Webpack%uC740%20%uC6F9%20%uC5B4%uD50C%uB9AC%uCF00%uC774%uC158%uC758%20%uC2DC%uC791%20%uC9C0%uC810%20%uB610%uB294%20%uB8E8%uD2B8%20JavaScript%20%uD30C%uC77C%uC744%20%uBC14%uB77C%uBCF4%uACE0%20%uC788%uC5B4%uC57C%20%uD55C%uB2E4.%0A%3E%202.%20Webpack%uC740%20%uCF54%uB4DC%uB97C%20%uC5B4%uB5A4%20%uAC83%uC73C%uB85C%20%uBCC0%uD658%uC744%20%uD560%20%uAC83%uC778%uC9C0%uB97C%20%uC54C%uC544%uC57C%20%uD55C%uB2E4.%0A%3E%203.%20Webpack%uC740%20%uC0C8%uB85C%uAC8C%20%uBCC0%uD658%uD55C%20%uCF54%uB4DC%uB97C%20%uC800%uC7A5%uD560%20%uC704%uCE58%uB97C%20%uC54C%uC544%uC57C%20%uD55C%uB2E4.%0A%0A%uC0AC%uC2E4%20%uC704%uC758%203%uAC00%uC9C0%uB9CC%20%uC219%uC9C0%uD558%uACE0%20%uC788%uB2E4%uBA74%20Webpack%uC740%20%uBCC4%uAC8C%20%uC544%uB2C8%uB2E4.%0A%0A%uCCAB%uBC88%uC9F8%20%uD574%uC57C%uD560%20%uC77C%uC740%20**Webpack%20%uAD6C%uC131%uC744%20%uD3EC%uD568%20%uD560%20%uD30C%uC77C%uC744%20%uB9CC%uB4DC%uB294%20%uAC83%uC774%uB2E4.%20**%20%uC774%20%uD30C%uC77C%uC758%20%uC774%uB984%uC740%20Webpack%uC774%20%uC778%uC2DD%20%uD560%20%uC218%20%uC788%uB3C4%uB85D%20%uC774%uB984%uC774%20%60webpack.config.js%60%uB85C%20%uC815%uD574%uC838%20%uC788%uB2E4.%20%uC774%20%uD30C%uC77C%uC740%20%uD504%uB85C%uC81D%uD2B8%uC758%20%uB8E8%uD2B8%20%uB9AC%uB809%uD1A0%uB9AC%uC5D0%20%uC788%uC5B4%uC57C%20%uD55C%uB2E4.%20%0A%0A%uC774%uC81C%20%60webpack.config.js%60%20%uD30C%uC77C%uC744%20%uB9CC%uB4E4%uC5C8%uACE0%2C%20%20%uC774%20%uD30C%uC77C%uC774%20Webpack%uC758%20%uAD6C%uC131%uC744%20%uB098%uD0C0%uB0BC%20object%uB97C%20%uC81C%uB300%uB85C%20%uB0B4%uBCF4%uB0B4%uB294%uC9C0%20%uD655%uC778%uD574%uC57C%uD569%uB2C8%uB2E4.%20%uC790%uBC14%uC2A4%uD06C%uB9BD%uD2B8%20%uBAA8%uB4C8%uC5D0%20%uC775%uC219%uD558%uC9C0%20%uC54A%uB2E4%uBA74%20%5BPreethi%uC758%20%uBE14%uB85C%uADF8%20%uC2DC%uB9AC%uC988%5D%28https%3A//medium.freecodecamp.com/javascript-modules-a-beginner-s-guide-783f7d7a5fcc%23.q991f5q8e%29%uB97C%20%uBA3C%uC800%20%uC77D%uC5B4%uBCF4%uACE0%20%uC624%uC790.%0A%0A%60%60%60javascript%0A//%20In%20webpack.config.js%0Amodule.exports%20%3D%20%7B%7D%0A%60%60%60%0A%uC774%uC81C%20%uC704%uC758%20%uC5B8%uAE09%uB300%uB85C%20%uCF54%uB4DC%uB85C%20%uBCC0%uD658%uD574%uBCF4%uC790.%20%uBA3C%uC800%2C%20Webpack%uC5D0%20%uC5B4%uD50C%uB9AC%uCF00%uC774%uC158%uC758%20%uC9C4%uC785%20%uC9C0%uC810%uC744%20%uC54C%uB824%uC8FC%uC790.%0A%0A%60%60%60javascript%0A//%20In%20webpack.config.js%0Amodule.exports%20%3D%20%7B%0A%20%20entry%3A%20%5B%0A%20%20%20%20%27./app/index.js%27%0A%20%20%5D%0A%7D%0A%60%60%60%0A%0A%uC704%uC5D0%uC11C%20%uD55C%20%uAC83%uC740%20%uAC1D%uCCB4%uC5D0%20**entry%20%uC18D%uC131**%uACFC%20%uADF8%20%uAC12%uC744%20%uC815%uD574%uC900%20%uAC83%uC774%uB2E4.%20%uC5EC%uAE30%uC11C%20%uAC12%uC774%20%uC65C%20%uBB38%uC790%uC5F4%uC774%20%uC544%uB2CC%20%uBC30%uC5F4%uC778%uC9C0%20%uAD81%uAE08%uD560%20%uC218%20%uC788%uC744%20%uAC83%uC774%uB2E4.%20Webpack%uC744%20%uC0AC%uC6A9%uD558%uBA74%20%uC5B4%uD50C%uB9AC%uCF00%uC774%uC158%uC5D0%uC11C%20%uD558%uB098%20%uC774%uC0C1%uC758%20entry%20%uD3EC%uC778%uD2B8%uB97C%20%uAC00%uC9C8%20%uC218%20%uC788%uAE30%20%uB54C%uBB38%uC5D0%20%uB354%20%uB9CE%uC740%20%uC815%uBCF4%uB97C%20%uB2F4%uAE30%20%uC704%uD574%uC11C%20%uBC30%uC5F4%uC744%20%uC0AC%uC6A9%uD588%uB2E4.%20%28%uBB3C%uB860%20%uBC30%uC5F4%uC744%20%uC548%20%uC368%uB3C4%20%uB418%uC9C0%uB9CC%20%uC2B5%uAD00%uC744%20%uC704%uD574%20%uBC30%uC5F4%uC744%20%uC4F0%uC790%29%20%uC774%uB807%uAC8C%20%uD558%uBA74%20%uB098%uC911%uC5D0%20%uCD94%uAC00%20%uC2DC%20%uC27D%uAC8C%20%uCD94%uAC00%20%uD560%20%uC218%20%uC788%uB2E4.%0A%0A%uC5EC%uAE30%uAE4C%uC9C0%uB294%20Webpack%uC5D0%uAC8C%20%uC5B4%uB514%uC5D0%uC11C%20%uC2DC%uC791%uD574%uC57C%20%uD55C%uB2E4%uACE0%20%uC54C%uB824%uC8FC%uC5C8%uACE0%2C%20**%uC774%uC81C%20%uCF54%uB4DC%uB97C%20%uBCC0%uD615%uC744%20%uD574%uC57C%uD55C%uB2E4.**%uC774%20%uBCC0%uD615%uC5D0%uB294%20%60loader%60%uB77C%uB294%20%uAC83%uC744%20%uC0AC%uC6A9%uD55C%uB2E4.%0A%0Aloader%uB294%20%uD0C0%uCF13%20%uD30C%uC77C%uC758%20%uC885%uB958%uC5D0%20%uB9DE%uCDB0%uC5B4%uC11C%20%uC900%uBE44%uD558%uBA74%20%uB41C%uB2E4.%20TypeScript%uBA74%20%uADF8%uAC70%uC5D0%20%uB9DE%uB294%20loader%uB97C%20CoffeeScript%uBA74%20%uADF8%uAC70%uC5D0%20%uB9DE%uB294%20loader%uB97C%20%uC0AC%uC6A9%uD558%uBA74%20%uB41C%uB2E4.%20%uC0AC%uC6A9%uCC98%uC5D0%20%uB9DE%uAC8C%20loader%uB97C%20%uC124%uCE58%uD560%20%uAC83%uC778%uB370%20%60npm%60%uC744%20%uC0AC%uC6A9%uD558%uC790.%20%uC774%20%uAE00%uC5D0%uC11C%uB294%20%uC608%uC81C%uB85C%20CoffeeScript%uB97C%20%uBCC0%uD658%20%uC2DC%uD0AC%20%uAC83%uC774%uB2E4.%20%uD130%uBBF8%uB110%uC5D0%uC11C%20%uB2E4%uC74C%uACFC%20%uAC19%uC774%20loader%uB97C%20%uC124%uCE58%uD558%uC790.%0A%0A%60%60%60bash%0A%24%20npm%20install%20--save-dev%20coffee-loader%0A%60%60%60%0A%0A%uC774%uB97C%20%uC2E4%uD589%uD558%uBA74%20coffee-loader%uAC00%20%60package.json%60%20%uD30C%uC77C%uC758%20dev%20%uC885%uC18D%20%uD30C%uC77C%uB85C%20%uC800%uC7A5%uB41C%uB2E4.%20%uADF8%uB7F0%20%uB2E4%uC74C%20webpack.config.js%20%uD30C%uC77C%uC744%20%uBC18%uC601%uC2DC%uCF1C%uC8FC%uC790.%20%uC774%uB97C%20%uC704%uD574%20%uBA3C%uC800%20%60webpack.config.js%60%uC5D0%uC11C%20%uB0B4%uBCF4%uB0B4%uB294%20%uAC1D%uCCB4%uC5D0%20%uBAA8%uB4C8%20%uC18D%uC131%uC744%20%uCD94%uAC00%uD55C%uB2E4.%0A%0A%60%60%60javascript%0A//%20In%20webpack.config.js%0Amodule.exports%20%3D%20%7B%0A%20%20entry%3A%20%5B%0A%20%20%20%20%27./app/index.js%27%0A%20%20%5D%2C%0A%20%20module%3A%20%7B%0A%20%20%20%20loaders%3A%20%5B%5D%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A**loader**%20%uBC30%uC5F4%20%uB0B4%uBD80%uC5D0%uB294%20%uC6D0%uD558%uB294%20%uBAA8%uB4E0%20loader%uB97C%20%uB123%uC744%20%uAC83%uC774%uB2E4.%0A%0A%uAC01%20loader%uB294%20%uC138%20%uAC00%uC9C0%uB85C%20%uAD6C%uC131%uB418%uC5B4%uC57C%20%uD55C%uB2E4.%20%uCCAB%20%uBC88%uC9F8%uB294%20**%uD2B9%uC815%20%uBCC0%uD658%uC744%20%uC2E4%uD589%uD560%20%uD30C%uC77C%20%uC720%uD615%uC774%uB2E4.**%20%uC608%uB97C%20%uB4E4%uC5B4%2C%20%uC790%uBC14%uC2A4%uD06C%uB9BD%uD2B8%20%uD30C%uC77C%uC5D0%uC11C%20%uC790%uBC14%uC2A4%uD06C%uB9BD%uD2B8%uB85C%uB9CC%20%uBCC0%uD658%uD560%20%uC218%20%uC788%uB3C4%uB85D%20%uD558%uB294%20%uAC83%uC774%uB2E4.%20%uB2E4%uC74C%uC740%20**%uBCC0%uD658%20%uD560%20%uB514%uB809%uD1A0%uB9AC%uB97C%20%uD3EC%uD568%uD558%uAC70%uB098%20%uC81C%uC678%uD574%uC57C%uD558%uB294%20%uD56D%uBAA9%uC774%uB2E4.**%20%uC5EC%uAE30%uC11C%uB294%20node_modules%20%uD3F4%uB354%uC758%20%uBAA8%uB4E0%20%uD56D%uBAA9%uC5D0%20%uB300%uD574%20%uBCC0%uD658%uC744%20%uC2E4%uD589%uD558%uC9C0%20%uC54A%uC73C%uBBC0%uB85C%20node_modules%20%uACBD%uB85C%uB97C%20%uC81C%uC678%20%uAC12%uC73C%uB85C%20%uC0AC%uC6A9%uD558%uC790.%20%uB9C8%uC9C0%uB9C9%uC73C%uB85C%20**%uC2E4%uD589%uD558%uACE0%uC790%uD558%uB294%20%uD2B9%uC815%20loader%uC774%uB2E4.**%20%uC608%uB85C%20%uB4E4%uBA74%20%uC544%uB798%uC640%20%uAC19%uB2E4.%0A%0A%60%60%60javascript%0A//%20In%20webpack.config.js%0Amodule.exports%20%3D%20%7B%0A%20%20entry%3A%20%5B%0A%20%20%20%20%27./app/index.js%27%0A%20%20%5D%2C%0A%20%20module%3A%20%7B%0A%20%20%20%20loaders%3A%20%5B%0A%20%20%20%20%20%20%7Btest%3A%20/%5C.coffee%24/%2C%20exclude%3A%20/node_modules/%2C%20loader%3A%20%22coffee-loader%22%7D%0A%20%20%20%20%5D%0A%20%20%7D%2C%0A%7D%0A%60%60%60%0A%0A%uC704%uC5D0%uC11C%20%uB208%uC5EC%uACA8%uBD10%uC57C%20%uD560%20%uAC83%uC740%20%uC815%uADDC%uC2DD%uC774%uB2E4.%20**test**%uC5D0%20%uC788%uB294%20**%60/%20%5C.%20coffee%20%24%20/%60**%20%uC744%20%uC0AC%uC6A9%uD558%uAC8C%20%uB418%uBA74%20Webpack%uC774%20.coffee%uB85C%20%uB05D%uB098%uB294%20%uBAA8%uB4E0%20%uD655%uC7A5%20%uD504%uB85C%uADF8%uB7A8%uC5D0%uC11C%20coffe-loader%uB97C%20%uC2E4%uD589%uD558%uAC8C%20%uB41C%uB2E4.%0A%0A%uB2E4%uC74C%uC73C%uB85C%2C%20**exclude**%uB294%20%uBCC0%uD658%uC5D0%uC11C%20%uC81C%uC678%uC2DC%uD0AC%20%uAC83%uC744%20%uB098%uD0C0%uB0B8%uB2E4.%20%uC55E%uC11C%20%uB9D0%uD588%uB4EF%uC774%20node_modules%20%uD3F4%uB354%uB97C%20%uBCC0%uD615%uD558%uACE0%20%uC2F6%uC9C0%20%uC54A%uAE30%20%uB54C%uBB38%uC5D0%20%uC81C%uC678%uD55C%uB2E4.%20%uB9C8%uC9C0%uB9C9%uC73C%uB85C%uB294%20**loader**%uB85C%20Webpack%uC5D0%uAC8C%20**test**%uC758%20%uC815%uADDC%uC2DD%uACFC%20%uC77C%uCE58%uD558%uACE0%20**exclude**%uC5D0%20%uC5C6%uB294%20%uBAA8%uB4E0%20%uACBD%uB85C%uC5D0%uC11C%20%uC2E4%uD589%uB420%20%uBCC0%uD658%uC744%20%uC9C0%uC2DC%uD55C%uB2E4.%0A%0A%uB9CC%uC57D%20%uC5EC%uB7EC%20loader%uB97C%20%uCD94%uAC00%uD560%uB824%uBA74%20%60npm%60%uC73C%uB85C%20loader%uB97C%20%uC124%uCE58%uD558%uACE0%20loader%20%uBC30%uC5F4%uC5D0%20%uCD94%uAC00%uD574%uC8FC%uBA74%20%uB41C%uB2E4.%0A%0A%uC774%uC81C%20%uB9C8%uC9C0%uB9C9%20%uB2E8%uACC4%uB85C%20**%uC0C8%uB85C%uC6B4%20%uBCC0%uD658%20%uB41C%20%uCF54%uB4DC%uB97C%20%uCD9C%uB825%uD574%uC57C%20%uD558%uB294%20%uC704%uCE58**%uB97C%20%uC9C0%uC815%uD574%uC8FC%uC790.%0A%0A%60%60%60javascript%0A//%20In%20webpack.config.js%0Amodule.exports%20%3D%20%7B%0A%20%20entry%3A%20%5B%0A%20%20%20%20%27./app/index.js%27%0A%20%20%5D%2C%0A%20%20module%3A%20%7B%0A%20%20%20%20loaders%3A%20%5B%0A%20%20%20%20%20%20%7Btest%3A%20/%5C.coffee%24/%2C%20exclude%3A%20/node_modules/%2C%20loader%3A%20%22coffee-loader%22%7D%0A%20%20%20%20%5D%0A%20%20%7D%2C%0A%20%20output%3A%20%7B%0A%20%20%20%20filename%3A%20%22index_bundle.js%22%2C%0A%20%20%20%20path%3A%20__dirname%20+%20%27/dist%27%0A%20%20%7D%2C%0A%7D%0A%60%60%60%0A%0A%uC704%uC758%20%uCF54%uB4DC%uB97C%20%uBCF4%uBA74%20**filename**%uC740%20%uC0C8%uB85C%uC6B4%20%uBCC0%uD658%20%uB41C%20%uCF54%uB4DC%uAC00%20%uD3EC%uD568%20%uB41C%20Webpack%uC774%20%uB9CC%uB4E4%20%uD30C%uC77C%uC758%20%uC774%uB984%uC774%uB2E4.%20**path**%uB294%20%uC0C8%20%uD30C%uC77C%20%uC774%uB984%20%28%uC5EC%uAE30%uC11C%uB294%20index_bundle.js%29%uC774%20%uBC30%uCE58%20%uB420%20%uB514%uB809%uD1A0%uB9AC%uC774%uB2E4.%20%uCC38%uACE0%uB85C%20%60__dirname%60%uB294%20%uD604%uC7AC%20%uC2E4%uD589%20%uC911%uC778%20%uC2A4%uD06C%uB9BD%uD2B8%uC758%20%uC0C1%uC704%20%uB514%uB809%uD1A0%uB9AC%20%uC774%uB984%uC774%uB2E4.%0A%0A%uC774%uC81C%20Webpack%uC774%20%uC2E4%uD589%20%uC2DC%uD0A4%uBA74%2C%20%20%uCF54%uB4DC%uAC00%20%uBCC0%uD615%uB418%uC5B4%20ourApp%20/%20dist%20/%20index_bundle.js%uC5D0%uC11C%20%uCC38%uC870%uD560%20%uC218%20%uC788%uAC8C%20%uB41C%uB2E4.%20%uC774%uC81C%20HTML%20%uD30C%uC77C%uC774%20%60index_bundle.js%60%uB97C%20%uCC38%uC870%uD558%uB3C4%uB85D%20%uD574%uBCF4%uC790.%20%uC77C%uBC18%20%uC571%uC758%20%uC77C%uBC18%uC801%uC73C%uB85C%20%uAD6C%uC870%uB294%20%uB2E4%uC74C%uACFC%20%uAC19%uC744%20%uAC83%uC774%uB2E4.%0A%0A%60%60%60%0A/app%0A%20%20-%20components%0A%20%20-%20containers%0A%20%20-%20config%0A%20%20-%20utils%0A%20%20index.js%0A%20%20index.html%0A/dist%0A%20%20index.html%0A%20%20index_bundle.js%0Apackage.json%0Awebpack.config.js%0A.gitignore%0A%60%60%60%0A%uBCF4%uD1B5%20%uAC1C%uBC1C%20%uC911%uC778%20%uCF54%uB4DC%uB294%20app%20%uD3F4%uB354%uC5D0%20%uB450%uACE0%20%uBCC0%uD615%20%uD6C4%20%uBC30%uD3EC%uC5D0%20%uC0AC%uC6A9%uD560%20%uCF54%uB4DC%uB294%20dist%20%uD3F4%uB354%uC5D0%20%uC788%uB2E4.%20%uC5EC%uAE30%uC11C%20%uD55C%uAC00%uC9C0%20%uBB38%uC81C%uC810%uC774%20%uC0DD%uAE30%uB294%uB370%20app%20%uD3F4%uB354%uC5D0%uC788%uB294%20index.html%uC744%20%uBCC0%uACBD%uD560%20%uB54C%uC774%uB2E4.%20%uBE0C%uB77C%uC6B0%uC800%uAC00%20%uC2E4%uC81C%uB85C%20%uC0AC%uC6A9%uD558%uAC8C%20%uB420%20index.html%20%uD30C%uC77C%uC740%20dist%20%uD3F4%uB354%20%uB0B4%uC758%20%uD30C%uC77C%uC774%uAE30%20%uB54C%uBB38%uC5D0%20app%20%uC548%uC758%20html%20%uD30C%uC77C%uC744%20%uC62E%uACA8%uC8FC%uC5B4%uC57C%20%uD55C%uB2E4.%0A%0A%uC774%uB97C%20%uC704%uD574%20%uB450%uAC00%uC9C0%20%uBC29%uBC95%uC774%20%uC788%uB294%uB370%2C%20%uCCAB%uBC88%uC9F8%20%uBC29%uBC95%uC740%20**%uB450%20%uAC1C%uC758%20index.html%20%uD30C%uC77C%uC744%20%uAD00%uB9AC%uD558%uB294%20%uAC83%uC774%uB2E4.**%20%20app%uC5D0%20%uC788%uB294%20%uD30C%uC77C%uC744%20%uBCC0%uACBD%uD560%20%uB54C%uB9C8%uB2E4%20dist%uC5D0%20%uC788%uB294%20%uD30C%uC77C%uB85C%20%uC9C1%uC811%20%uBCF5%uC0AC%uD558%uB294%20%uAC83%uC774%uB2E4.%20%uD558%uC9C0%uB9CC%20%uC774%20%uBC29%uBC95%uC740%20%uB108%uBB34%20%uBB34%uC2DD%uD55C%20%uBC29%uBC95%uC774%uB2E4.%0A%0A%uB450%20%uBC88%uC9F8%20%uC635%uC158%uC740%20**Webpack%uC774%20%uC2E4%uD589%uB420%20%uB54C%uB9C8%uB2E4%20/app/index.html%uC774%20/dist/index.html%uC5D0%20%uBCF5%uC0AC**%uB418%uB3C4%uB85D%uD558%uB294%20%uBC29%uBC95%uC774%uB2E4.%20%uCCAB%uBC88%uC9F8%20%uBC29%uBC95%uBCF4%uB2E4%20%uD6E8%uC52C%20%uAE54%uB054%uD558%uACE0%20%uC190%uC774%20%uB35C%20%uAC00%uB294%20%uBC29%uBC95%uC774%uB2E4.%0A%0A%uB450%uBC88%uC9F8%20%uC77C%20Webpack%20tool%uC5D0%20%uC774%uBBF8%20%uC874%uC7AC%uD55C%uB2E4.%20%uBC14%uB85C%20%60html-webpack-plugin%60%uC774%uB2E4.%20npm%uC73C%uB85C%20%uB9C8%uCC2C%uAC00%uC9C0%uB85C%20%uC124%uCE58%uD574%uC8FC%uC790.%20%0A%0A%60%60%60bash%0Anpm%20install%20--save-dev%20html-webpack-plugin%0A%60%60%60%0A%0A%uC6B0%uC120%2C%20%60HTMLWebpackPlugin%60%uC758%20%uC0C8%20%uC778%uC2A4%uD134%uC2A4%uB97C%20%uB9CC%uB4E0%20%uD6C4%20%uC138%20%uAC00%uC9C0%uB97C%20%uC9C0%uC815%uD574%uC57C%20%uD55C%uB2E4.%20%uBA3C%uC800%2C%20%uC0C8%uB85C%20%uC0DD%uC131%20%uB41C%20%uD30C%uC77C%uC774%20%uC5B4%uB5BB%uAC8C%20%uBCF4%uC774%uAE38%20%uC6D0%uD558%uB294%uC9C0%uC5D0%20%uB300%uD55C%20%uD15C%uD50C%uB9BF%uC744%20%uC81C%uACF5%uD574%uC57C%uD55C%uB2E4.%20%uB450%uBC88%uC9F8%uB294%2C%20%uD30C%uC77C%20%uC774%uB984%uC744%20%uC9C0%uC815%uD558%uAC70%uB098%2C%20%uC0DD%uC131%uD55C%20%uC0C8%20%uD30C%uC77C%uC744%20%uD638%uCD9C%uD569%uB2C8%uB2E4.%20%uC14B%uBC88%uC9F8%uB294%20%60WebpackPluginConfig%60%uB85C%20%uD1B5%uD574%20%uBCC0%uD658%20%uB41C%20%uCF54%uB4DC%uC758%20%uCD9C%uB825%20%uD30C%uC77C%20%uC774%uB984%uC744%20%uAC10%uC9C0%uC2DC%uD0A4%uB294%20%uAC83%uC774%uB2E4%2C%20%28%uC5EC%uAE30%uC11C%uB294%20%60index_bundle.js%60%29.%20%uADF8%uB7F0%20%uB2E4%uC74C%20%3Chead%3E%20%uB610%uB294%20%3Cbody%3E%uC5D0%20%uC2A4%uD06C%uB9BD%uD2B8%uB97C%20%uC0BD%uC785%uD574%uC57C%uD55C%uB2E4.%20%uC0C8%uB85C%20%uC0DD%uC131%20%uB41C%20index.html%20%uD30C%uC77C%uC5D0%20**injection**%uC73C%uB85C%2C%20%uC2A4%uD06C%uB9BD%uD2B8%uB97C%20%60head%60%20%uB610%uB294%20%60body%60%uC5D0%20%uC0BD%uC785%uD558%uBA74%20%uB41C%uB2E4.%0A%0A%uC815%uB9AC%uD558%uBA74%20%uC544%uB798%uC640%20%uAC19%uB2E4.%0A%0A%60%60%60javascript%0A//%20In%20webpack.config.js%0Avar%20HtmlWebpackPlugin%20%3D%20require%28%27html-webpack-plugin%27%29%0Avar%20HTMLWebpackPluginConfig%20%3D%20new%20HtmlWebpackPlugin%28%7B%0A%20%20template%3A%20__dirname%20+%20%27/app/index.html%27%2C%0A%20%20filename%3A%20%27index.html%27%2C%0A%20%20inject%3A%20%27body%27%0A%7D%29%3B%0Amodule.exports%20%3D%20%7B%0A%20%20entry%3A%20%5B%0A%20%20%20%20%27./app/index.js%27%0A%20%20%5D%2C%0A%20%20module%3A%20%7B%0A%20%20%20%20loaders%3A%20%5B%0A%20%20%20%20%20%20%7Btest%3A%20/%5C.coffee%24/%2C%20exclude%3A%20/node_modules/%2C%20loader%3A%20%22coffee-loader%22%7D%0A%20%20%20%20%5D%0A%20%20%7D%2C%0A%20%20output%3A%20%7B%0A%20%20%20%20filename%3A%20%22index_bundle.js%22%2C%0A%20%20%20%20path%3A%20__dirname%20+%20%27/dist%27%0A%20%20%7D%2C%0A%20%20plugins%3A%20%5BHTMLWebpackPluginConfig%5D%0A%7D%3B%0A%60%60%60%0A%0A%uD30C%uC77C%uC758%20%uB9E8%20%uC704%uC5D0%20**HtmlWebpackPlugin**%uC758%20%uC0C8%20%uC778%uC2A4%uD134%uC2A4%uB97C%20%uB9CC%uB4E4%uACE0%20%uC694%uB188%uC740%20%uC138%20%uAC00%uC9C0%20%uC635%uC158%uC744%20%uC81C%uACF5%uD55C%uB2E4.%20**template**%uC740%20%uC571%20%uB514%uB809%uD1A0%uB9AC%uC5D0%uC788%uB294%20%uC77C%uBC18%20index.html%20%uD30C%uC77C%uC744%20%uAC00%uB9AC%uD0A8%uB2E4.%20**filename**%uC740%20index.html%uC73C%uB85C%20%uAE30%uC874%20%uD30C%uC77C%20%uC774%uB984%uACFC%20%uB3D9%uC77C%uD558%uAC8C%20%uC9C0%uC5C8%uB2E4.%20**inject**%uB294%20loader%uC758%20%uCD9C%uB825%20%uD30C%uC77C%20%28index_bundle.js%29%uC758%20%uC774%uB984%uC744%20%uCC38%uC870%uD558%uB294%20%uC2A4%uD06C%uB9BD%uD2B8%uB97C%20%uC0BD%uC785%uD558%uC5EC%20%uC0C8%uB85C%20%uC0DD%uC131%20%uB41C%20html%20%uD30C%uC77C%uC758%20%uBCF8%uBB38%uC5D0%20%uC0BD%uC785%uD55C%uB2E4.%20%uB9C8%uC9C0%uB9C9%uC73C%uB85C%20%uC791%uC131%uD55C%20**HTMLWebpackPluginConfig**%20%uBCC0%uC218%uB97C%20webpack%20config%uC758%20%uD50C%uB7EC%uADF8%uC778%20%uBC30%uC5F4%uC5D0%20%uD56D%uBAA9%uC73C%uB85C%20%uCD94%uAC00%uD55C%uB2E4.%0A%0A%uC774%uC81C%20Webpack%uC744%20%uC2E4%uD589%uD558%uBA74%20dist%20%uD3F4%uB354%20%uC548%uC5D0%20%uB450%20%uAC1C%uC758%20%uD30C%uC77C%uC774%20%uC0DD%uAE34%uB2E4.%20%60index_bundle.js%60%20%uC640%20%60index.html%60%uAC00%20%uC0DD%uACBC%uC744%20%uAC83%uC774%uB2E4.%20%60index_bundle.js%60%uB294%20**%60entry%60**%20%uCF54%uB4DC%uB97C%20%uAC00%uC838%20%uC640%uC11C%20loader%uB97C%20%uD1B5%uD574%20%uC2E4%uD589%20%uD55C%20%uACB0%uACFC%uC774%uB2E4.%20%60index.html%60%uC740%20**HTMLWebpackPluginConfig**%uB97C%20%uAC70%uCCD0%20%uB9CC%uB4E4%uC5B4%uC9C4%20%uD30C%uC77C%uC774%uB2E4.%0A%0Adist%uC758%20%uB0B4%uBD80%uC5D0%20%uC0C8%uB85C%20%uC0DD%uC131%20%uB41C%20%60index.html%60%20%uD30C%uC77C%uC774%20%uC5B4%uB5BB%uAC8C%20%uC0DD%uACBC%uB294%uC9C0%2C%20app%20%uD3F4%uB354%20%uC548%uC758%20%60index.html%60%20%uC640%20%uBE44%uAD50%uD574%uBCF4%uC790.%0A%0A***app/index.html***%0A%60%60%60vbscript-html%0A%3C%21DOCTYPE%20html%3E%0A%3Chtml%20lang%3D%22en%22%3E%0A%3Chead%3E%0A%20%20%3Cmeta%20charset%3D%22UTF-8%22%3E%0A%20%20%3Ctitle%3EMy%20App%3C/title%3E%0A%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22styles.css%22%3E%0A%3C/head%3E%0A%3Cbody%3E%0A%20%20%3Cdiv%20id%3D%22app%22%3E%3C/div%3E%0A%3C/body%3E%0A%3C/html%3E%0A%60%60%60%0A%0A***dist/index.html***%0A%60%60%60vbscript-html%0A%3C%21DOCTYPE%20html%3E%0A%3Chtml%20lang%3D%22en%22%3E%0A%3Chead%3E%0A%20%20%3Cmeta%20charset%3D%22UTF-8%22%3E%0A%20%20%3Ctitle%3EMy%20App%3C/title%3E%0A%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22styles.css%22%3E%0A%3C/head%3E%0A%3Cbody%3E%0A%20%20%3Cdiv%20id%3D%22app%22%3E%3C/div%3E%0A%20%20%3Cscript%20src%3D%22index_bundle.js%22%3E%3C/script%3E%0A%3C/body%3E%0A%3C/html%3E%0A%60%60%60%0A%0A%uB450%20%uD30C%uC77C%uC758%20%uCC28%uC774%uC810%uC740%20**dist**%20%28**HTMLWebpackPlugin**%uC73C%uB85C%20%uC0DD%uC131%uB41C%20%uD30C%uC77C%29%uC5D0%20%60index_bundle.js%60%uB97C%20%uAC00%uB9AC%uD0A4%uB294%20script%20%uD0DC%uADF8%uAC00%20%uC788%uB2E4%uB294%20%uAC83%uC774%uB2E4.%20%uB2E4%uC2DC%20%uB9D0%uD558%uC9C0%uB9CC%20**HTMLWebpackConfig**%uAC00%20Webpack%uC5D0%uC11C%20%uC0C8%uB85C%20%uC0DD%uC131%20%uB41C%20%uD30C%uC77C%uC758%20%uCD9C%uB825%20%uD30C%uC77C%20%uC774%uB984%uC744%20%uAC10%uC9C0%uD558%uACE0%20%uC0C8%uB85C%20%uB9CC%uB4E0%20%60index.html%60%20%uD30C%uC77C%uC758%20%uC2A4%uD06C%uB9BD%uD2B8%uB85C%20%uC790%uB3D9%20%uCD94%uAC00%uD55C%20%uAC83%uC774%uB2E4.%20%uC704%uC758%20%60index.html%60%20%uD30C%uC77C%uC5D0%uC11C%20%uBCFC%20%uC218%20%uC788%uB4EF%uC774%20%60body%60%uC5D0%uB294%20%60%3Cscript%20src%3D%22index_bundle.js%22%3E%3C/script%3E%60%uAC00%20%uC788%uB2E4.%20Webpack%20%uC124%uC815%uC5D0%uC11C%20%uCD9C%uB825%uC744%20%60test.js%60%uB85C%20%uBCC0%uACBD%uD588%uB2E4%uBA74%20%uC0C8%uB85C%20%uC0DD%uC131%20%uB41C%20%60index.html%60%20%uD30C%uC77C%uC758%20%60body%60%20%uC548%uC5D0%20%60%3Cscript%20src%3D%22test.js%22%3E%3C/script%3E%60%uAC00%20%uC0DD%uACBC%uC744%20%uAC83%uC774%uB2E4.%0A%0A%uC774%uC81C%20%uAC70%uC758%20%uB2E4%20%uB05D%uB0AC%uB2E4%20%uB9C8%uC9C0%uB9C9%uC73C%uB85C%uB294%20Webpack%uC5D0%20%uC2E4%uC81C%uB85C%20%uC2E4%uD589%uD558%uB294%20%uBC29%uBC95%uC774%uB2E4.%20Webpack%uC774%20%uC124%uCE58%uB418%uC5B4%20%uC788%uC9C0%20%uC54A%uC558%uB2E4%uBA74%20%uB2E4%uC74C%uACFC%20%uAC19%uC774%20%uC124%uCE58%uD574%uC8FC%uC790.%0A%0A%60%60%60bash%0A%24%20npm%20install%20-g%20webpack%0A%60%60%60%0A%0AWebpack%uC744%20%uC124%uCE58%uB97C%20%uD558%uBA74%20Webpack%20CLI%uC5D0%20%uC811%uADFC%20%uD560%20%uC218%20%uC788%uB2E4.%20%28%uB9CC%uC57D%20local%uC5D0%20%uC124%uCE58%uD588%uB2E4%uBA74%20npm%uC73C%uB85C%20%uC2E4%uD589%uC2DC%uCF1C%uC918%uC57C%20%uD55C%uB2E4.%29%0A%0A%uC5B4%uD50C%uB9AC%uCF00%uC774%uC158%uC758%20%uB8E8%uD2B8%20%uB514%uB809%uD1A0%uB9AC%20%28%uC5EC%uAE30%uC11C%uB294%20%60webpack.config.js%60%uC758%20%uC704%uCE58%29%uC5D0%uC11C%20Webpack%uC744%20%uD130%uBBF8%uB110%uB85C%20%uC2E4%uD589%uD560%20%uC218%20%uC788%uB2E4.%20%uC2E4%uD589%20%uC2DC%20Webpack%20%uC124%uC815%uC774%20%uD55C%20%uBC88%20%uC2E4%uD589%uB41C%uB2E4.%20%uD558%uC9C0%uB9CC%20%uD30C%uC77C%uC774%20%uC5EC%uB7EC%uBC88%20%uC218%uC815%uB420%20%uACBD%uC6B0%uB9C8%uB2E4%20Webpack%uC744%20%uB9E4%uBC88%20%uC2E4%uD589%20%uC2DC%uCF1C%uC918%uC57C%uD558%uB294%uB370%20%uADF8%uB7EC%uAE30%uC5D0%uB294%20%uB108%uBB34%20%uADC0%uCC2E%uB2E4.%20Webpack%uC740%20watch%uB77C%uB294%20%uAE30%uB2A5%uC744%20%uC81C%uACF5%uD558%uB294%uB370%20%uD30C%uC77C%uC774%20%uBCC0%uACBD%20%uB420%20%uB54C%uB9C8%uB2E4%20%uC2E4%uC2DC%uAC04%uC73C%uB85C%20Webpack%uC744%20%uC2E4%uD589%20%uC2DC%uCF1C%uC8FC%uB294%20%uAE30%uB2A5%uC774%uB2E4.%20%0A%0A%60%60%60bash%0A%24%20webpack%20-w%0A%60%60%60%0A%0A%uBC30%uD3EC%20%uB2E8%uACC4%uB85C%20%uB0B4%uB193%uC744%uB824%uBA74%20%uB2E4%uC74C%uC744%20%uC2E4%uD589%20%uC2DC%20%uBCC0%uD658%uACFC%20%uCF54%uB4DC%20%uCD95%uC18C%uAC00%20%uC2E4%uD589%uB41C%uB2E4.%0A%0A%60%60%60bash%0A%24%20webpack%20-p%0A%60%60%60%0A%0A%uC0AC%uC2E4%20Webpack%uB9CC%20%uBCF4%uACE0%20%uC654%uB2E4%uBA74%20%uC5EC%uAE30%uAE4C%uC9C0%20%uD574%uB3C4%20%uB41C%uB2E4.%20%uD558%uC9C0%uB9CC%20%uCD5C%uC885%20%uBAA9%uD45C%uB294%20%60React%60%20%uAD00%uB9AC%uB97C%20Webpack%uC73C%uB85C%20%uD558%uB294%20%uAC83%uC774%uAE30%20%uB54C%uBB38%uC5D0%20%60Babal%60%uC774%uB77C%uB294%20%uAC83%uC744%20loader%uB85C%20%uCD94%uAC00%uD574%uC57C%20%uD55C%uB2E4.%0A%0A%0A%60Babel.js%60%uB294%20%uC790%uBC14%uC2A4%uD06C%uB9BD%uD2B8%uB97C%20%uCEF4%uD30C%uC77C%20%uB3C4%uAD6C%uC778%uB370%2C%20Webpack%uC744%20%uC0AC%uC6A9%uD558%uBA74%20%uBC14%uBCA8%uC774%20%uD2B9%uC815%20%uBCC0%uD658%20%uC790%uCCB4%20%uC778%20%uB3D9%uC548%20%uCF54%uB4DC%uC5D0%uC11C%20%uC5B4%uB5A4%20%uBCC0%uD658%uC744%20%uC218%uD589%uD560%uC9C0%20%uC9C0%uC815%uD560%20%uC218%20%uC788%uB2E4.%20React%uC758%20%uAD00%uC810%uC5D0%uC11C%20%uBC14%uBCA8%uC740%20JSX%20%uB97C%20%uC2E4%uC81C%20JavaScript%uB85C%20%uBCC0%uD615%20%uD560%20%uC218%20%uC788%uAC8C%20%uD55C%uB2E4.%20**Babel**%uC774%20%uC88B%uC740%20%uC810%uC740%20JSX%20-%3E%20JS%20%uBCC0%uD615%20%uC678%uC5D0%uB3C4%20%uB9CE%uC740%20%uC6A9%uB3C4%uB85C%20%uC0AC%uC6A9%uD560%20%uC218%20%uC788%uB2E4%uB294%20%uAC83%uC774%uB2E4.%20Javascript%uB3C4%20%uB180%uB78D%uAC8C%uB3C4%20%uBC84%uC804%uB4E4%uC774%20%uC874%uC7AC%uD558%uB294%uB370%20%uCD5C%uC2E0%20Javascript%uB791%20%uC6B0%uB9AC%uAC00%20%uC54C%uACE0%20%uC788%uB294%20Javascript%uB791%uC740%20%uCC28%uC774%uC810%uC774%20%uB9E4%uC6B0%20%uB9CE%uB2E4.%20%uC774%uC5D0%20%uB530%uB77C%20%uBE0C%uB77C%uC6B0%uC800%uAC00%20%uCD5C%uC2E0%20Javascript%uB97C%20%uBABB%20%uB530%uB77C%uC624%uB294%20%uD604%uC0C1%uC774%20%uBC1C%uC0DD%uD588%uB294%uB370%20%uC774%uB97C%20%60Babel%60%uC774%uB77C%uB294%20%uB188%uC774%20%uBC14%uB85C%20%uC7A1%uC544%uC8FC%uB294%20%uAC83%uC774%uB2E4.%20%uCD5C%uC2E0%20JavaScript%20%28ES2015%2C%202016%20%uB4F1%29%uC744%20%uBE0C%uB77C%uC6B0%uC800%uAC00%20%uC54C%uACE0%20%uC788%uB294%20Javascript%uB85C%20%uBCC0%uD658%20%uC2DC%uCF1C%20%uBE0C%uB77C%uC6B0%uC800%uAC00%20%uC774%uD574%uD560%20%uC218%20%uC788%uB3C4%uB85D%20%uD574%uC900%uB2E4.%0A%0A**babel**%20%uC124%uCE58%uB3C4%20%60npm%60%uC73C%uB85C%20%uD574%uC8FC%uBA74%20%uB41C%uB2E4.%20**babel**%uC740%20%uC5EC%uB7EC%20%uBAA8%uB4C8%uB85C%20%uAD6C%uC131%uB418%uC5B4%20%uC788%uAE30%20%uB54C%uBB38%uC5D0%20%uC124%uCE58%20%uC804%uC5D0%20%20%uBA87%20%uAC00%uC9C0%uB97C%20%uC124%uCE58%uD574%uC57C%20%uD55C%uB2E4.%20%0A%0A%60%60%60bash%0A%24%20npm%20install%20--save-dev%20babel-core%20babel-loader%20babel-preset-react%0A%60%60%60%0A%0A%60babel-core%60%uB294%20babel%20%uC790%uCCB4%uC774%uACE0%2C%20%60babel-loader%60%uB294%20%uC0AC%uC6A9%uD560%20%20Webpack%20loader%uC774%uBA70%2C%20%60babel-preset-react%60%uB294%20JSX%20-%3E%20JS%20%uBCC0%uD615%uC744%20%uB3C4%uC640%uC900%uB2E4.%0A%0A%uC704%uC758%20%uC138%uAC00%uC9C0%20%uBAA8%uB4C8%uC744%20Webpack%uC5D0%20%uCD94%uAC00%uD574%uC918%uB3C4%20%uB418%uC9C0%uB9CC%20%uAD73%uC774%20%uADF8%uB7F4%20%uD544%uC694%uAC00%20%uC5C6%uB2E4.%20**babel**%20%uC124%uC815%uC744%20%uC704%uD574%20%uBCC4%uB3C4%uC758%20%uD30C%uC77C%uB85C%20%uAD00%uB9AC%uD558%uBA74%20%uB41C%uB2E4.%20%0A%0A%uBA3C%uC800%20%60webpack.config.js%60%20%uD30C%uC77C%uC774%20%uC788%uB294%20%uB8E8%uD2B8%20%uB514%uB809%uD1A0%uB9AC%uC5D0%20%60.babelrc%60%20%uD30C%uC77C%uC744%20%uB9CC%uB4E4%uC5B4%uC8FC%uC790.%0A%0A%60%60%60%0A%7B%0A%20%20%22presets%22%3A%20%5B%0A%20%20%20%20%22react%22%0A%20%20%5D%0A%7D%0A%60%60%60%0A%0A%uC5EC%uAE30%uC11C%uB294%20**babel**%20%uBCC0%uD658%uC774%20%uC2E4%uC81C%uB85C%20%uB9CC%uB4E4%uC5B4%20%uB0B4%uB294%20***babel%20loader***%uC5D0%20%uC9C0%uC2DC%uD558%uB294%20%uAC83%uC774%uB2E4.%20%uC880%20%uC804%uC5D0%20%60babel-preset-react%60%uB97C%20%uC124%uCE58%uD574%uC92C%uAE30%20%uB54C%uBB38%uC5D0%20**react**%uB85C%20%uC124%uC815%uD574%uC8FC%uBA74%20%uB41C%uB2E4.%0A%0A%uC774%uC81C%20***babel-loader***%uB97C%20%60webpack.config.js%60%uC758%20loader%uC5D0%20%uCD94%uAC00%uD574%uC8FC%uBA74%20%uB41C%uB2E4.%0A%0A%60%60%60javascript%0A//%20In%20webpack.config.js%0Avar%20HtmlWebpackPlugin%20%3D%20require%28%27html-webpack-plugin%27%29%0Avar%20HTMLWebpackPluginConfig%20%3D%20new%20HtmlWebpackPlugin%28%7B%0A%20%20template%3A%20__dirname%20+%20%27/app/index.html%27%2C%0A%20%20filename%3A%20%27index.html%27%2C%0A%20%20inject%3A%20%27body%27%0A%7D%29%3B%0Amodule.exports%20%3D%20%7B%0A%20%20entry%3A%20%5B%0A%20%20%20%20%27./app/index.js%27%0A%20%20%5D%2C%0A%20%20output%3A%20%7B%0A%20%20%20%20path%3A%20__dirname%20+%20%27/dist%27%2C%0A%20%20%20%20filename%3A%20%22index_bundle.js%22%0A%20%20%7D%2C%0A%20%20module%3A%20%7B%0A%20%20%20%20loaders%3A%20%5B%0A%20%20%20%20%20%20%7Btest%3A%20/%5C.js%24/%2C%20exclude%3A%20/node_modules/%2C%20loader%3A%20%22babel-loader%22%7D%0A%20%20%20%20%5D%0A%20%20%7D%2C%0A%20%20plugins%3A%20%5BHTMLWebpackPluginConfig%5D%0A%7D%3B%0A%60%60%60