- 이 글은 React webpack from the scratch의 영상과 제 나름의 조사를 통해 작성한 글입니다.
- 원본 소스는 버전이 바뀌면서 많이 다릅니다. 참조하실 분들은 저의 github에서 소스코드를 받으실 수 있습니다.
npm init
npm install react react-dom
yarn일 경우
yarn add react react-dom
npm install --save-dev @babel/core babel-loader @babel/preset-react @babel/preset-env
yarn일 경우
yarn add --dev @babel/core babel-loader @babel/preset-react @babel/preset-env
babel이 7로 업데이트 되면서 [scoped package](https://babeljs.io/docs/en/next/v7-migration#scoped-packages)로 전환했다. 간단히 이야기하면 기존의 비공식적인 package들과 네이밍 컨벤션에 문제가 있어서 바꾸게 되었다. 영상에서는 babel-core라고 되어있지만 install하게되면 7, 8이 설치되므로 (특히 babel-loader) package 설정에 유의해야 할 듯하다.
babel-core -> @babel/core
npm install --save-dev webpack webpack-dev-server webpack-cli html-webpack-plugin
--save-dev : 개발환경에서만 사용되는 라이브러리라는 것을 명시
style-loader
css를 dom에 추가sass-loader
SASS파일을 CSS로 컴파일babel-loader
babel로 javascript 코드를 transpile
예를들어 위의 그림을 설명하겠습니다. 먼저 원래의 동작 먼저 보겠습니다. css loader에 의해 css파일에서 css코드들을 부릅니다. 그리고 csso loader에 의해 최적화 작업과 text를 추출하는 plugin에 의해 style.css라는 파일에 원하는 css 코드를 담습니다
webpack 설정이 들어가면, text plugin에 의해 css 파일에서 css 코드를 추출하고 webpack 안의 csso plugin에 의해 중복되는 코드를 최적하여 style.css에 담게됩니다.
정리하면 최적화를 둘 다 하지만 webpack plugin이 조금 더 밀도있는 작업을 하는 것을 알 수 있습니다.
webpack.config.js
const path = require('path') // core nodejs 모듈 중 하나, 파일 경로 설정할 때 사용
const HtmlWebpackPlugin = require('html-webpack-plugin') // index.html 파일을 dist 폴더에 index_bundle.js 파일과 함께 자동으로 생성, 우리는 그냥 시작만 하고싶지 귀찮게 index.html 파일까지 만들고 싶지 않다.!!
module.exports = { // moduel export (옛날 방식..)
entry: './src/index.js', // 리액트 파일이 시작하는 곳
output: { // bundled compiled 파일
path: path.join(__dirname, '/dist'), //__dirname : 현재 디렉토리, dist 폴더에 모든 컴파일된 하나의 번들파일을 넣을 예정
filename: 'index_bundle.js'
},
module: { // javascript 모듈을 생성할 규칙을 지정 (node_module을 제외한.js 파일을 babel-loader로 불러와 모듈을 생성
rules: [
{
test: /\.js$/, // .js, .jsx로 끝나는 babel이 컴파일하게 할 모든 파일
exclude: /node_module/, // node module 폴더는 babel 컴파일에서 제외
use:{
loader: 'babel-loader' // babel loader가 파이프를 통해 js 코드를 불러옴
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html' // 생성한 템플릿 파일
})
]
}
위의 설정들을 크게 살펴보자
template에 지정된 index.html에 모든 static 파일들을 긁어모은 index_bundle.js 파일을 `<script src='index_bundle.js'></script>` 형식으로 연결해줍니다.
index.js
여기서는 htmlwebpackPlugin을 사용하여 index.html과 index_bundle.js에 연결해줍니다.
HTMLWebpackPlugin
이 index.html의 script 태그안에 컴파일된 bundle 파일을 심어줄 것입니다.webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
]
}
위의 코드는 다음과 같이 dist/index.html파일을 생성합니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html>
index_bundle.js가 webpack에 의해 컴파일, 번들화된 하나의 js 파일입니다.
다음은 웹페이지의 가장 기본이 될 index.html 파일을 src/index.html
경로로 아래와 같이 생성하겠습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>My React App</title>
</head>
<body>
<div id="app"></div> // 템플릿
</body>
</html>
babel-preset-env
와 babel-preset-react
와 같이 preset을 사용하고 싶으면 root폴더에 .babelrc
을 생성하여 사용하고자할 preset을 설정하면 됩니다. plugin
들을 각각의 npm dependency를 가지고 있습니다. 하지만 설치시 매번 .bablrc에 설정을 해야하므로 그 두가지를 모두 해결해줄 preset을 사용하면됩니다. preset을 설치하고 설정하므로서 preset이 가진 plugin들을 설정할 필요없이 사용할 수 있게 됩니다. {
"presets": [
"@babel/env",
"@babel/react"
]
}
@babel이 버전이 업데이트 되면서 더이상 babel-core 형태(-)의 dependency를 지원하지 않게되므로서 @babel/env 형태(/)를 사용해야 합니다.
import React from 'react';
import ReactDOM from 'react-dome';
import App from './component/App'
ReactDOM.render(<App/>, document.getElementById('app')) // dom에 render학 메인 app component, rendering 할 곳
import React from 'react'
export default class App extends React.Component {
render(){
return(
<div>
<h1>My React App</h1>
</div>
)
}
}
"scripts": {
"start":"webpack-dev-server --mode development --open --hot", // webpack-dev-server, --open : 자동으로 브라우저 열어줌, --hot : hot realod 저장했을 때 자동적으로 reload 해줌
"build":"webpack --mode production" // dist 폴더에 컴파일된 파일 다 넣어줌
},
이제 지금까지 작성한 프로젝트를 실행해보겠습니다. 아래의 코드를 터미널에서 실행합니다.
npm start
그렇다면 다음과 같은 화면이 보일 것입니다.
이번에는 프로젝트를 build 해보겠습니다.
npm run build
그러면 /dist 폴더가 생성되면서 index_bundle.js와 index.html이 생성됨을 알 수 있습니다.
index.html을 먼저 보면 <script type="text/javascript" src="index_bundle.js"></script>
script 태그가 body안에 생성되어 있는 것을 확인할 수 있습니다. 이는 webpack.config.js 파일의 plugins 에서 Htmlwebplugin의 도움으로 template: './src/index.html'
템플릿에 컴파일 된 번들 파일이 script 태그로 자동적으로 들어가게 되는 것입니다.
이번에 index_bundle.js 파일을 살펴보면 js, jsx 파일들이 es6에서 es5로 컴파일하여 알아서 순서대로 묶어서 하나의 파일로 넣어 줌을 알 수 있습니다. 이는 자바스크립트의 모듈 태그 순서에 따라서 문제를 손쉽게 해결 해줄 수 있습니다.
조금 더 자세한 내용은 ES6, babel 그리고 webpack을 어떻게 사용할까을 참조하시기 바랍니다.
이번에 회사에서 관리자 페이지 작업을 맡게 되면서 react로 한번 만들어보고 싶었습니다. 사실 리액트를 사용하긴 했지만
주로 create react app
키워드만 사용하여 백그라운드가 어떻게 돌아가는지도 모르고 막 사용했던 것 같습니다. 조금 더 궁금한 부분도 많지만 추후 계속 업데이트 해나가야 될 것 같습니다.
좋은 자료 감사합니다. 초기 세팅을 연습하는데 많은 도움이 됐습니다 : )
오타 하나가 있어서 남깁니다. 감사합니다!
import ReactDOM from 'react-dome';
react-dom 으로 수정되어야 할거같아요!
웹팩으로 개발설정을 하고 싶었는데요, 정말 자세히 설명해주셔서 도움이 많이 되었습니다. 감사합니다.