FrontEnd
Webpack
JavaScript
Webpack
- html은 하나의 JavaScript 파일만 불러올 수 있는데 Webpack을 사용하면 자바스크립트, css, 이미지 등을 하나의 파일로 묶어서 내보낼 수 있다
- 자바스크립트, css, 이미지 등을 모듈이라고 부르며 Webpack은 이들을 묶는 모듈 번들러 (Module Bundler)이다
설치
- webpack - 모듈 번들러
- webpack-cli - 웹팩의 커맨드 라인 인터페이스
npm i -D webpack
npm i -D webpack-cli
실행
실행시 webpack이라고 적으면 명령어로 등록이 안되어있으므로 인식할 수 있게 해줘야 한다
-
- 명령어로 등록 한다
-
- scripts에 적어주고
npm run [script 명령어]
로 실행한다 -
npm run dev
로 실행//package.json "scripts": { "dev": "webpack", }
- scripts에 적어주고
-
npx webpack
으로 실행
webpack.config.js
- webpack.config.js가 변경되면 새로고침이 필수
zerocho 블로그 참고 zerocho 유투브 react 웹게임 참고 webpack 공식문서
mode
-
개발용은 development 배포용(실서비스용)은 production (배포용은 자동으로 최적화가 적용되어 최적화 플러그인들이 많이 호환되지 않음)
devtool
- 개발시엔 'eval', 배포용은 'hidden-source-map'을 많이 쓴다고 한다
- 'eval'은 빠르고 'hidden-source-map'은 소스 숨기기
devtool: 'eval',
resovle
- 확장자는 entry에 js, jsx, css, json 등 여러가지를 입력할 수 있는데 다 적기 귀찮다면 resolve에 entry 확장자들을 적어주어 자동으로 인식하게 하면 된다
resolve: {
inextensions: ['.js', '.jsx'],
},
entry: {
index: ['./a', './c'],
},
entry - 입력
- 웹팩이 파일을 읽어들이기 시작하는 파일 경로로 이 entry를 통해 모듈들을 로딩하고 하나의 파일로 묶는다
- entry의 키가 index.js면 index.js로 통합된다
entry: {
index: '파일 경로',
}
- entry의 키를 여러개 넣으면 여러 JS 파일로 결과물이 만들어진다. 보통 멀티페이지 웹사이트에서 사용한다고 한다
entry: {
index: ['./a.js', './b.js'],
}
- 만약 a.js에서 이미 b.js를 불러오고 있다면 b.js를 적을 필요가 없다
entry: {
index: ['./a.js'],
}
module
적용할 모듈을 명시
test: /\.jsx?/
- js와 jsx에 적용한다- loader - 적용할 rule
-
options - rule의 옵션
- presets와 plugins는 아래 예시처럼 나눠서 작성
module: {
rules: [{
test: /\.jsx?$/,
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
],
plugins: ['@babel/plugin-proposal-class-properties'],
}
}],
}
-
preset-env에 대한 옵션을 설정하고 싶다면 preset을 배열로 감싸고 클래스를 항목으로 추가해 옵션을 설정한다
- 브라우저 리스트에서 브라우저 옵션들을 확인할 수 있다
module: {
...
options: {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['> 5% in KR', 'last 2 chrome versions'],
},
debug: true,
}],
'@babel/preset-react'
],
...
}
plugins
웹팩의 확장 프로그램 (결과물의 형태를 변형)
- 실무에서 몇 가지 사용된다
- 아래 예시는 로더들에 모두 debug: true 옵션을 추가하는 기능
plugins: [
new webpack.LoaderOptionsPlugin({debug: true}),
],
output - 출력
entry로 찾은 모듈을 하나로 묶은 결과물을 반환하는 위치
- 만약 현재 폴더 안에 dist가 있고 거기에 출력을 하려한다면현재 폴더와 그 안에 들어있는 dist를 합치도록 하면 된다
output: {
path: path.join(__dirname, 'dist'),
filename: 'index.js',
},
//webpack.congif.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development'
resolve: {
extensions: ['jsx', 'js'],
},
entry: {
index: './pages/index',
}
module: {
rules: [{
test: /\.jsx?$/,
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['> 1% in KR'],
},
debug: true,
}],
'@babel/preset-react'
],
plugins: [],
}
}],
},
output: {
path: path.resolve(__dirname, 'dist/js'),
filename: 'index.js'
},
devtool: 'eval',
};
hot loader && webpack-dev-server
- hot loader 에서 react-refresh로 바뀌었다
-
react가 원래 reloading은 해준다 (변경되면 새로고침)
- hot reloading은 기존 데이터를 유지하면서 새로고침을 해준다는 것이 주요 특징
설치
npm i react-refresh @pmmmwh/react-refresh-webpack-plugin -D
npm i webpack-dev-server -D
명령어
npm run dev
로 실행
//package.json
"scripts": {
"dev": "webpack server --env development"
}
webpack.config.js
- react-refresh 플러그인을 불러와서 plugins에 설정
- module의 plugins에 react-refresh 명시
- devServer에 output의 publicPath를 넣고 hot: true로 설정
//webpack.config.js
const RefreshWebpackPlugin = requir('@pmmmwh/react-refresh-webpack-plugin');
...
module: {
rules: [{
...
options: {
presets: [
...
],
plugins: [
'react-refresh/babel',
],
}
}],
},
plugins: [
new RefreshWebpackPlugin()
],
output: {
path: path.resolve(__dirname, 'dist/js'),
filename: 'index.js'
publicPath: '/dist/',
},
devServer: {
publicPath: '/dist/',
hot: true,
},
예전 webpack-dev-server와 hot loader 설명 (&& publicPath vs path 설명)
- webpack-dev-server - 수정사항이 발견됐을 때 자동으로 프로그램을 재실행해주고 개발 서버를 제공하는 기능 (webpack.config.js를 읽어서 빌드하고 항상 서버로 유지시킨다 localhost:8080)
- react-hot-loader - 수정사항을 감지하는 기능
//webpack.config.js
plugins: [
'react-hot-loader/babel',
]
-
webpack-dev-server를 사용할 때는 dist/index.js처럼 경로를 쓰지 않고 바로 파일명만 명시해야한다
- path: 실제 경로
- publicPath: 가상의 경로 (NodeJS의 express.static과 유사)
<!-- index.html-->
<script src='./index.js'></script>
- 스크립트 경로를 바꿔도 된다
//webpack.config.js
output: {
...
publicPath: '/dist/',
}
<!-- index.html-->
<script src='./dist/index.js'></script>
- webpack.config.js가 변경되면 새로고침이 필수