1. 빌드 환경 세팅과 빌드해보기
02번에서 만든 것은 HTML과 javascript로 만든 간단한 코드였다.
앞으로 제작해야 할 것들은 더 많은 파일들을 생산해야 하고, 이것을 브라우저로 보내기 위해서는 번들링과 같은 과정을 거쳐 빌드(build)해야 한다.
먼저 npm이 가능하도록 세팅한다.
npm init
npm install webpack-cli --save-dev
npm install webpack-dev-server babel-loader @babel/core @babel/preset-env @babel/preset-react
npm install html-webpack-plugin --save-dev
(npm install은 한꺼번에 여러 개도 가능하지만, 너무 길면 글에 드래그가 생겨서 명령어를 나눴다.)
가장 먼저 webpack의 설정(config)을 진행한다. 기본 뼈대는 아래와 같다.
// webpack.config.js
module.exports = {
mode: '',
entry: '',
output: {
},
module: {
},
plugins: [
]
}
mode는 배포용인지 개발용인지를 설정한다.
webpack은 크게 2가지 값을 세팅한다. 하나는 모듈(module), 다른 하나는 플러그인(plugins)이다.
webpack은 entry에 적혀있는 자바스크립트에서부터 시작해서 입력으로 읽어드린 다음에 변환 과정을 실행한다. 그 변환 과정에서 쓰일 소프트웨어 명칭들을 적는 것이다.
entry 자바스크립트 파일 → module (트랜스 파일 진행) → plugin에 넘겨서 번들링 마무리 → output 파일로 작성됨
모듈에는 트랜스 파일러를 설정한다. 예를 들어 ES6 파일을 ES5로 변환해주는 것이 있다.
번들링이라는 것은 N개의 파일을 받아서 하나의 파일로 만들어내는 과정이고, 출력 결과(하나의 파일)를 만들 때 그에 필요한 소프트웨어를 plugin이라고 한다.
// webpack.config.js
const HTMLWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'development',
entry: './app.js',
output: {
path: path.resolve(__dirname, 'dist'), // 어느 환경에서도 경로를 잘 잡을 수 있게 node가 제공하는 path 모듈 사용
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/, // 정규표현식. 자바스크립트 파일만 처리할 수 있게 필요없는 파일들은 지우자. (ex. CSS파일)
exclude: /node_modules/, // 자바스크립트 파일 중에서 node_modules에 있는 파일은 제외해야지 번들링에 포함되지 않는다.
use: {
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env", "@babel/preset-react"]
}
}
}
]
},
plugins: [
new HTMLWebpackPlugin({
title: '2.3 setup webpack & babel',
template: 'index.html'
}) // 인스턴스를 만들어줘야 한다.
]
}
Babel을 이용하기 위해서는 babel.config.json이라는 설정 파일이 추가로 필요하다.
해당 이름으로 파일을 하나 생성하자.
{
"presets": ["@babel/preset-env"]
}
두번째로 데브서버를 세팅해야 한다. 위의 webpack.config.js에서 dev server라는 키를 설정해주자.
// webpack.config.js
const HTMLWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'development',
entry: './app.js',
output: {
path: path.resolve(__dirname, 'dist'), // 어느 환경에서도 경로를 잘 잡을 수 있게 node가 제공하는 path 모듈 사용
filename: 'bundle.js'
},
devServer: {
compress: true, // 압축하라는 옵션을 세팅하는 것으로, 크게 의미없다.
port: 9999, // 포트번호
},
module: {
rules: [
{
test: /\.js$/, // 정규표현식. 자바스크립트 파일만 처리할 수 있게 필요없는 파일들은 지우자. (ex. CSS파일)
exclude: /node_modules/, // 자바스크립트 파일 중에서 node_modules에 있는 파일은 제외해야지 번들링에 포함되지 않는다.
use: {
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env", "@babel/preset-react"]
}
}
}
]
},
plugins: [
new HTMLWebpackPlugin({
title: '2.3 setup webpack & babel',
template: 'index.html'
}) // 인스턴스를 만들어줘야 한다.
]
}
그 후에 쉽게 번들링하기 위해서 package.json 파일의 scripts에다가 build 명령어를 추가한다.
(생략)
"scripts": {
"build": "webpack",
"dev": "webpack serve",
"test" "echo \"Error: no test specified\" && exit 1"
},
(생략)
여기서 build를 하면 번들링이 실행된다. (번들링만)
dev server를 띄우기 위해서 dev 명령어를 추가한다. (중간중간 결과를 확인 가능)
이후에 dev 명령어를 실행한다.
npm run dev
이렇게하면 localhost:9999로 확인할 수 있다.
npm run build
빌드를 하면 dist 폴더에 빌드된 최종 파일이 작성된다.
최종 파일에서는 app.js가 아닌 bundle.js가 들어가므로 HTML 파일에서 스크립트 부분을 삭제해준다.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>2.2 객체 to DOM Render</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
2. 소스코드 분리와 react.js 파일 만들기
프로젝트가 점점 커지면 config 설정이 거대해진다.
내가 작성하는 소스코드와 번들링(bundling) 파일 구분이 좀 더 명확하면 좋겠다.
그래서 개발할 때 쓰는 원본 app.js 코드는 다른 디렉토리로 분리를 해보도록 하자.
디렉토리를 별도로 만들고 react.js라는 파일을 생성한다.
// react.js
export function createDOM(node) { // export를 적어서 app.js에서 사용할 수 있도록 함
if (typeof node === 'string') {
return document.createTextNode(node);
}
const element = document.createElement(node.tag);
Object.entries(node.props) // 기존에는 props에 대한 처리가 안됐다. props에 대한 처리를 진행하자. Object.entries() 혹은 Object.keys()를 사용하자.
.forEach(([name, value]) => element.setAttribute(name, value));
node.children
.map(createDOM)
.forEach(element.appendChild.bind(element));
return element;
}
export function render(vdom, container) { // 새로 추가하고, 입력값을 container로 설정
container.appendChild(createDOM(vdom));
}
app.js에서는 따로 나눈 react.js를 불러와서 사용하자.
import { createDOM, render } from './react'; // react.js 파일 불러오기
const vdom = {
tag: 'p',
props: {},
children: [
{
tag: 'h1',
props: {},
children: ["React 만들기"],
},
{
tag: 'ul',
props: {},
children: [
{
tag: 'li',
props: {
style: "color:red",
},
children: ["첫 번째 아이템"]
},
{
tag: 'li',
props: {
style: "color:blue",
},
children: ["두 번째 아이템"]
},
{
tag: 'li',
props: {
style: "color:green",
},
children: ["세 번째 아이템"]
},
]
}
],
};
render(vdom, document.querySelector('#root')); // render에 vdom과 container값을 지정해서 전달해주자.
app.js가 src 디렉토리 하위로 들어갔기 때문에 webpack의 entry 경로를 변경시켜주어야 한다.
// webpack.config.js
const HTMLWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/app.js', // src 경로 추가함!
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
(생략)