1. package.json 생성
npm init -y
2. Babel 설치 및 적용
- Babel: ECMAScript 2015 이상 버전을 지원하지 않는 브라우저를 위해 상위 버전 코드를 각 브라우저에 호환이 되게 변환해주는 JavaScript 컴파일러
npm install --save-dev @babel/core @babel/cli @babel/preset-env
babel을 사용하여 코드를 트랜스파일링해도 브라우저가 지원하지 않는 코드가 남아있을 수 있다. 예를 들어 ES6에서 추가된 Promise, Object.assign, Array.from 등은 ES5 사양으로 트랜스파일링해도 ES5 사양에 대체할 기능이 없기 때문에 트랜스파일링되지 못하고 그대로 남는다. 이러한 이유로 구형 브라우저에서 앞서 말한 기능들을 사용하려면 @babel/polyfill을 사용해야 한다.
그러나 @babel/polyfill은 Babel 7.4.0부터 deprecated 되었고, 이제는 @babel/plugin-transform-runtime을 사용해야 한다. core-js를 사용할 수도 있지만 이는 전역 오염을 발생시킨다는 단점이 있다.
npm install --save-dev @babel/plugin-transform-runtime
npm install @babel/runtime-corejs3
babel.config.json
{
"presets": ["@babel/preset-env"],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 3,
"proposals": true
}
]
]
}
3. webpack 설치 및 적용
npm install --save-dev webpack webpack-cli webpack-dev-server
- webpack-dev-server: 자동으로 코드 변경을 감지하여 reload
babel-loader 설치
- webpack이 모듈을 번들링할 때 Babel을 사용하여 코드를 트랜스파일링
npm install --save-dev babel-loader
html-webpack-plugin 설치
- webpack 번들을 제공하는 HTML 파일 생성을 단순화
npm install --save-dev html-webpack-plugin
style loader 설치
- style 코드 전처리
npm install --save-dev style-loader css-loader
dotenv-webpack 설치
- 환경변수 사용
- dotenv 라이브러리를 이용한 방법도 있으나 dotenv-webpack의 사용법이 가장 간단하여 이 방법 선택
npm install --save-dev dotenv-webpack
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Dotenv = require('dotenv-webpack');
module.exports = (env, argv) => {
const IS_PRODUCTION = argv.mode === 'production';
return {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
publicPath: '/',
},
devServer: {
hot: true,
port: 8080,
open: true,
historyApiFallback: true,
compress: true,
static: {
directory: path.join(__dirname, 'public'),
},
},
devtool: IS_PRODUCTION ? 'source-map' : 'eval-cheap-module-source-map',
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
configFile: path.resolve(__dirname, 'babel.config.json'),
},
},
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader', 'postcss-loader'],
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
],
},
resolve: {
extensions: ['.js'],
alias: {
'@': path.resolve(__dirname, 'src/'),
'@apis': path.resolve(__dirname, 'src/apis'),
'@components': path.resolve(__dirname, 'src/components'),
'@constants': path.resolve(__dirname, 'src/constants'),
'@libs': path.resolve(__dirname, 'src/libs'),
'@pages': path.resolve(__dirname, 'src/pages'),
'@stores': path.resolve(__dirname, 'src/stores'),
'@styles': path.resolve(__dirname, 'src/styles'),
'@utils': path.resolve(__dirname, 'src/utils'),
},
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
favicon: './public/favicon.ico', // html에서 설정하지 않는다.
}),
new Dotenv(),
],
};
};
output.publicPath: publicPath를 설정하기 전에는 동적 라우팅 시 빌드 파일을 찾지 못 하여 아래와 같은 오류가 발생했다.
구글링을 통해 해결책으로 output의 publicPath를 "/"로 설정해주어 해결했다.
24.05.03) "/"로 설정하지 않으면 실제 서버 호스팅 후 배포 환경에서도 오류가 발생한다.
devServer: 개발 서버
- hot: webpack의 HMR 기능 활성화 (HMR: 브라우저 새로고침 없이 webpack으로 빌드한 결과물이 웹 애플리케이션에 실시간으로 반영될 수 있게 도와주는 설정)
- open: dev server 구동 후 브라우저 열기
- historyApiFallback: true로 설정하면 404 오류 시 index.html 렌더링하도록 함
- compress: gzip 압축 사용 여부
- static directory: 서버에 제공될 정적 파일 경로
devTool: sourcemap 설정. sourcemap이 있으면 debugging이 용이하다.
resolve.alias: 절대경로 설정
- webpack에서는 와일드카드(*)를 사용한 별칭 지정이 불가능하다.
+ jsconfig.json 추가
// jsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@*": ["./src/*"]
}
}
}
HtmlWebpackPlugin: 정의되어있는 기본 template을 기준으로 번들링 시에 새로운 html 파일을 생성해 준다. 파일을 생성할 때 번들링된 javascript 파일을 삽입해준다.
4. 테스트를 위해 jest 설치
npm install --save-dev jest @types/jest babel-jest
5. package.json script 추가
"scripts": {
"prod": "webpack serve --mode=production",
"dev": "webpack serve --mode=development",
"build": "webpack --mode=production",
"test": "jest"
},
6. ESLint 적용하기
npm init @eslint/config
style guide - airbnb
eslint를 초기화하면서 eslint-plugin-import를 설치하게 되었다. 그런데 이게 설치되면서 절대 경로 import에서 import/no-unresolved 오류가 발생했다. 나는 webpack, jsconfig.json을 통해 절대경로 설정을 하였기 때문에 eslint-import-resolver-webpack을 추가로 설치해주었다. 타입스크립트를 사용할 경우 eslint-import-resolver-typescript도 설치해주어야 한다.
npm install --save-dev eslint-import-resolver-webpack
.eslintrc에 추가
...
settings: {
'import/resolver': {
webpack: {
config: path.resolve(__dirname, 'webpack.config.js'),
},
},
},
...
.eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: ['airbnb-base', 'prettier', 'plugin:import/recommended'],
overrides: [
{
env: {
node: true,
},
files: ['.eslintrc.{js,cjs}'],
parserOptions: {
sourceType: 'script',
},
},
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
settings: {
'import/resolver': {
webpack: {
config: path.resolve(__dirname, 'webpack.config.js'),
},
},
},
rules: {},
};
7. Prettier 적용하기
npm install --save-dev prettier eslint-config-prettier
.prettierrc
{
"singleQuote": true,
"semi": true,
"useTabs": false,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 80,
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "auto"
}
setting.json 설정
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}
파일 구조
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>yummy</title>
<meta name="description" content="맛집 정보 공유 웹앱" />
</head>
<body
<div id="app"></div>
</body>
</html>
잘못된 부분이 있다면 알려주시면 감사하겠습니다!
references
https://webpack.kr/guides/getting-started
https://kdydesign.github.io/2017/11/04/webpack-tutorial/
https://github.com/mickpah/sentry/blob/master/webpack.config.ts
https://poiemaweb.com/babel-polyfill
'Develop > JavaScript' 카테고리의 다른 글
[JavaScript] Firestore 검색 구현하기 with Aloglia (0) | 2024.04.19 |
---|---|
[JavaScript] 카카오맵 API를 이용한 장소 검색 및 위치 추가 구현하기 (0) | 2024.03.19 |
[Jest] 자바스크립트 테스트 코드 작성해 보기 (0) | 2023.09.07 |
[JavaScript] localStorage 사용하기 (0) | 2023.02.22 |
[JavaScript] Destructuring Assignment (구조 분해 할당) (0) | 2023.02.03 |