webpack을 사용하는 이유
웹팩은 모듈 번들러이다.
코딩할 때 편의를 위해 여러 개의 모듈로 나눠서 작업하는 경우가 많은데,
브라우저에서 파일 단위 모듈 시스템을 이용하는 것은 많은 네트워크 비용 낭비를 유발한다.
이러한 문제를 해결하기 위해서 여러 개의 모듈을 하나의 파일로 묶어서 보낼 모듈 번들러가 웹팩이다.
웹팩에서는 자바스크립트, 스타일시트, 이미지 등 모든 것을 모듈로 취급한다.
(webpack을 이용하기 위해서는 node(자바스크립트 실행기)를 알아야한다.)
(실제 서비스할때는 webpack을 사용하지 않고, 개발시에만 사용한다.)
모듈 시스템과 웹팩 설정 (react 기본 설정)
1. package.json (실행 명령어 >> npm init)
package.json
package name: (ifn_webgame) ifn_webgame (원하는 이름)
author, license 를 제외한 나머지는 건너뛰어도 된다.
2. npm install 명령어로 필요한 라이브러리를 설치한다.
react, react-dom, webpack, webpack-cli 설치
(webpack은 개발환경에서만 사용되므로 npm install -D 로 표기하여 dependency를 나누어 준다.)
npm i -D @babel/core @babel/preset-env babel-loader (babel도 개발환경에서만 사용됨)
babel/core : 바벨의 기본적인 라이브러리
babel/preset-env :브라우저에 맞는 최신문법을 적용
babel-loader : babel과 webpack을 연결시켜줌
3. index.html
//index.html
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>가위바위보</title>
</head>
<body>
<div id="root"></div>
<script src="./dist/app.js"></script>
</body>
</html>
4. client.jsx
//client.jsx
const React = require('react');
const ReactDom = require('react-dom');
ReactDom.render('컴포넌트명', document.querySelector('#root'));
ReactDom.render('컴포넌트명', document.querySelector('#root'));
<div id = "root"></div> 안에 app.js를 통에 렌더링된 컴포넌트의 return값(jsx, html태그들)을 넣어준다.
5. webpack.config.js
//webpack.config.js
const path = require('path');
module.exports = {
//webpack 속성들을 기재
name: 'setting',
mode: 'development', //실서비스 :production
devtool: 'eval', //빠르게
resolve: {
extensions:['.js', '.jsx'] //entry에 포함되는 파일의 확장자를 확인해주기 때문에 app.js라면 app 만 넣어줘도 된다.
},
entry : {
app: ['./client.jsx', './RSP.jsx'], // 만약 client.jsx 에서 RSP.jsx를 rendering 하고 있으면 client.jsx 만 기재해도 된다.
}, //입력
module: {
rules : [{
test : /\.jsx?/, // .js 와 .jsx 에 적용하겠다는 정규식
loader : 'bable-loader',
options : {
presets : [
['@babel/preset-env', {
targets : {
browsers : ['last 2 chrome versions'],
},
}],
'@babel/preset-react',
],
plugins : [ '@babel/plugin-proposal-class-properties'],
},
}],
},
output :{
path : path.join(__dirname, 'dist'), // __dirname 현재폴더에 dist를 합쳐서 반환한다.
filename: 'app.js',
publicPath:'/dist/', //가상경로
}, //출력
devServer :{
publicPath:'/dist/',
hot : true,
},
};
html에서 <script src="./dist/app.js"></script> 하나만 넣을수 있도록 webpack.config.js 에서 설정해준다.
resolve 속성에 extensions에 적은 확장자를 적어두면,
entry 속성에 포함될 파일의 확장자를 확인해주기 때문에 app.js라면 app 만 넣어줘도 된다.
resolve 속성이 없을 경우 : app: ['./client.jsx', './RSP.jsx']
resolve extensions:['.js', '.jsx'] 로 정의할 경우 app:['client', 'RSP']
// 만약 client.jsx 에서 RSP.jsx를 rendering 하고 있으면 client.jsx 만 기재해도 된다.
module 속성은 babel을 적용시키기 위한 옵션을 나열한다.
create-react-app 을 이용하면 이와 같은 설정을 사용하지 않아도 된다.
/*
.js 와 .jsx 는 큰 차이가 없지만 파일안에 jsx 문법(만들어둔 컴포넌트 불러오기 ex <GuGuDan / >)을 사용할 경우
jsx 확장자를 사용하는 것이 좋다.
(jsx문법을 담고있다, 리액트전용 파일임을 파일명만 보고 인지할수 있어 편리하다.)
*/
webpack.config.js 를 이용하여 하나의 js 파일을 생성하려면,
npx webpack 을 실행하거나 package.json 파일에 webpack 실행 명령어를 생성해야한다.
("scripts": { "webpack" : webpack } )
webpack.config.js 빌드시 에러 내용 1
[webpack-li] Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.module should be an object:
object { defaultRules?, exprContextCritical?, exprContextRecursive?, exprContextRegExp?, exprContextRequest?, generator?, noParse?, parser?, rules?, strictExportextCritical?, wrappedContextRecursive?, wrappedContextRegExp? }
-> Options affecting the normal modules (`NormalModuleFactory`).
module: [{ rules 라고 적어서 발생한 에러이다. module: { rules 로 수정하면 정상적으로 빌드된다.
webpack.config.js 빌드시 에러 내용 2
[webpack-cli] Failed to load 'C:\Users\mslk\Documents\ifn_webgame\webpack.config.js' config
[webpack-cli] TypeError: webpack.LoaderOptionsPlugin is not a constructor
at Object.<anonymous> (C:\Users\mslk\Documents\ifn_webgame\webpack.config.js:33:9)
at Module._compile (C:\Users\mslk\Documents\ifn_webgame\node_modules\v8-compile-cache\v8-compile-cache.js:192:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (C:\Users\mslk\Documents\ifn_webgame\node_modules\v8-compile-cache\v8-compile-cache.js:159:20)
at WebpackCLI.tryRequireThenImport (C:\Users\mslk\Documents\ifn_webgame\node_modules\webpack-cli\lib\webpack-cli.js:32:22)
at loadConfig (C:\Users\mslk\Documents\ifn_webgame\node_modules\webpack-cli\lib\webpack-cli.js:1536:38)
at WebpackCLI.resolveConfig (C:\Users\mslk\Documents\ifn_webgame\node_modules\webpack-cli\lib\webpack-cli.js:1639:44)
LoaderOptionsPlugin이 웹팩 2에서 2로 웹팩 1에서 마이그레이션을 위해 사용된다.
webpack 공식문서 plugins 에서 v5 plugin 리스트에서는 확인되지 않아서 삭제된 줄 알았는데
new webpack.LoaderOptionsPlugin ({ debug : true })
대신
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
new LoaderOptionsPlugin ({ debug : true })
로 변경하면 정상적으로 빌드된다.
webpack-dev-server 와 핫 리로딩
npm install -D
react-refresh
@pmmmwh/react-refresh-webpack-plugin
webpack-dev-server
- webpack-dev-server 는 핫 리로딩 기능을 가지고 있어서 변경점을 감지할 수 있다.
따라서 소스코드의 변경이 생기면 감지 후 webpack.config.js 빌드 결과물 즉, app.js 를 수정해준다.
(핫리로딩을 하기 위해 설치한 플러그인 react-refresh, @pmmmwh/react-refresh-webpack-plugin )
(핫리로딩은 리로딩(새로고침)과 다르게 기존의 데이터를 유지하면서 리로딩해준다.)
출처 👇👇👇
강의정보 👇👇👇
플랫폼 : 인프런
강의 : 웹 게임을 만들며 배우는 React
강사 : 제로초(조현영)
개발환경 : vscode, react
'Programming > JavaScript' 카테고리의 다른 글
[React ] Redux와 useReducer의 차이, Context API 사용하기 (0) | 2021.08.01 |
---|---|
[React] 리액트 라이프사이클, Hooks 알아보기 (0) | 2021.07.25 |
[React / Node.js] 유튜브 사이트 클론코딩 - 에러 해결, React, ES6 문법 알아보기 (0) | 2021.07.18 |
[React / Node.js] react-router 리액트 라우터 알아보기 (0) | 2021.07.04 |
[인프런] 레츠기릿 자바스크립트 / 끝말잇기, 셀프체크 쿵쿵따 만들기 (0) | 2021.06.30 |