본 내용은 인프런 김정환님의 프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) 강의를 토대로 작성하였습니다.
1. 최적화
- 코드가 많아지면 번들링된 결과물이 메가바이트 단위로 커지게 되어, 브라우저 성능에 영향을 준다.
- 웹팩으로 번들 결과를 압축하거나 분리하여 최적화를 한다.
2. mode
- 웹팩의 mode 값을 설정
development mode
- development는 디버깅 편의를 위해 두 개의 플러그인을 사용
- NamedChunksPlugin
- NamedModulesPlugin
- DefinePlugin을 사용시, process.env.NODE_ENV 값이 development로 설정되어 전역 변수로 주입됨
production mode
- mode를 production으로 설정하면 JavaScript 결과물을 최소화하기 위해서 일곱 개 플러그인을 사용.
- FlagDependencyUsagePlugin
- FlagIncludeChunksPlugin
- ModuleConcatenationPlugin
- NoEmitOnErrorsPlugin
- OccurrenceOrderPlugin
- SideEffectsFlagPlugin
- TerserPlugin: 기본 설정으로, JavaScript 코드를 난독화하고 debugger 구문을 제거
- DefinePlugin을 사용시, process.env.NODE_ENV 값이 production로 설정되어 전역 변수로 주입됨
환경 변수에 따른 mode 설정
- webpack.config.js에서 mode라는 상수를 아래와 같이 정의할 수 있다.
- 환경변수에 따라서 모드를 설정 가능
const mode = process.env.NODE_ENV || 'development';
module.exports = {
mode,
}
- package.json에서 scripts를 설정
- build 시에는 production mode
- start 시에는 development mode
...
"scripts": {
"build": "NODE_ENV=production webpack --progress",
"start": "webpack-dev-server --progress"
},
...
3. optimazation으로 최적화
- 빌드 과정을 커스터마이징
optimize-css-assets-webpack-plugin
- css 파일 빈칸을 없애서 압축
- npm i -D optimize-css-assets-webpack-plugin 을 입력하여 설치
- webpack.config.js에 추가
...
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
// node의 모듈 시스템
module.exports = {
...
optimization: {
minimizer: mode === 'production' ? [
new OptimizeCSSAssetsPlugin()
] : []
},
...
}
terser-webpack-plugin
- production일 경우 사용되는 플러그인 중 하나
- 기본 설정으로 JavaScript 코드를 난독화 하고 debugger 구문을 제거
- console.log를 제거하는 옵션도 있다.
- npm i -D terser-webpack-plugin 을 입력하여 설치
- webpack.config.js에 추가
...
const TerserPlugin = require('terser-webpack-plugin');
// node의 모듈 시스템
module.exports = {
...
optimization: {
minimizer: mode === 'production' ? [
new OptimizeCSSAssetsPlugin(),
new TerserPlugin({
terserOptions: {
compress: {
// console.log를 제거하는 옵션
drop_console: true,
}
}
})
] : []
},
...
}
4. 코드 스플리팅
- 코드를 압축해도, 프로젝트가 커지면 브라우저 성능에 영향을 줄 수 있다.
- 결과물을 나누어 쪼개서 브라우저에서 다운로드 속도를 높인다.
- 큰 파일 하나를 다운받는 것 보다 작은 파일 여러개를 동시에 다운받는 것이 빠르다.
엔트리 분리
- 엔트리를 여러개로 나누어 다운로드 속도를 높인다.
- 중복되는 코드를 제거해야한다.
- optimization에 splitChunks를 추가
- 중복되는 코드들은 vendors-main-result.js파일에 들어간다.
...
// node의 모듈 시스템
module.exports = {
...
optimization: {
...
splitChunks: {
// 중복되는 코드를 제거
chunks: 'all'
}
},
...
}
Dynamic Import
- 엔트리 분리 대신 dynamic import를 사용하여 자동으로 변경할 수 있다.
- 웹펙이 파일을 처리할 때 청크로 분리한다.
// src/app.js
import axios from 'axios';
import './app.css';
document.addEventListener('DOMContentLoaded', async () => {
// 페이지가 로딩되었을 때 api요청을 날린다.
// 요청은 웹팩 개발서버로 날아감
const res = await axios.get('/api/users');
// 받은 응답을 html div안에 출력
document.body.innerHTML = (res.data || []).map(user => {
return `<div>${user.id}: ${user.name}</div>`
}).join('');
// result를 사용하는 부분
// webpackChunkName이라는 주석을 보고 웹팩이 해당 부분을 따로 번들링한다.
import(/* webpackChunkName: "result" */ './result.js').then(m => {
// m: result 모듈
const result = m.default;
const resultEl = document.createElement("div");
resultEl.innerHTML = await result.render();
document.body.appendChild(resultEl);
})
});
externals
- 번들하지말아야할 대상은 빌드 범위에서 빼는 것
- 패키지들은 보통 빌드된 파일이 있다.
- dist 폴더
- copy-webpack-plugin: 웹팩이 실행될 때 패키지 빌드 파일을 복사
- npm i -D copy-webpack-plugin을 입력하여 설치
- webpack.config.js의 플러그인 추가
...
const CopyPlugin = require('copy-webpack-plugin');
// node의 모듈 시스템
module.exports = {
...
// 플러그인을 넣는 배열
plugins: [
...
new CopyPlugin([{
// 어디에있는것을 복사하여 가져올지
from: './node_modules/axios/dist/axios.min.js',
to: './axios.min.js'
}])
],
externals: {
// 웹팩으로 빌드시 axios 사용하는 부분이 있으면 전역변수 axios 사용하는 것으로 간주
axios: 'axios'
}
}
- html 파일에 패키지를 로딩하는 script태그 추가
<!DOCTYPE html>
<html lang="en">
<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>Document<%= env %>
</title>
</head>
<body>
<!-- axios를 로딩 -->
<script type="text/javascript" src="axios.min.js"></script>
</body>
</html>
5. 총정리
Node.js/NPM
- 프로젝트를 생성하고 의존성을 해결
Webpack
- 번들링
- 모듈을 사용하기 위한 도구
- 모듈로 작성한 프론트엔드 코드를 하나의 결과(번들)로 만듦
- API를 개발서버에 연동
- 핫로딩 설정
- 번들 결과 최적화
Babel
- 최신 ECMAScript를 다루기 위한 도구
- 폴리필
- SASS/SCSS
ESLint/Prettier
- 코드의 품질, 포매팅
- 두 도구를 함께 사용
- Lint를 자동화하고 강제화하는 것은 유용
다룬 개발도구의 역할과 기본 개념을 확실히 기억하고 자세한 것은 메뉴얼을 찾아본다. 기본 개념을 잘 숙지한 상태에서 변화에 적응하는 적응력을 키워야만 빠르게 변화하는 프론트엔드 기술에 대처할 수 있다.
Reference
'programming study > Front-end' 카테고리의 다른 글
GraphQL 서버 만들어보기 (0) | 2021.09.05 |
---|---|
GraphQL, Apollo (0) | 2021.09.04 |
Webpack - 핫로딩 (0) | 2021.08.22 |
Webpack - 웹팩 개발 서버, API 서버 연동 (0) | 2021.08.22 |
ESLint & Prettier - 자동화 (0) | 2021.08.21 |