Webpack
webpack.conifg.js 설정하기
🔎 webpack.conifg.js란
webpack 4버전 이후로는 따로 설정파일이 없더라도 webpack 이 src.index.js 파일을 dist/main.js 로 번들링 해주기 때문에 설정파일이 필수라고는 할 수 없다. 하지만 모든 프로젝트가 동일한 설정으로 번들링 된다는 것은 불가능하기 때문에 각 프로젝트에 맞는 설정값을 셋팅하는 것이 좋다. 이럴 때 webpack.config.js 파일에 설정값을 셋팅하면 webpack 은 해당 파일을 자동으로 읽고 설정에 맞게 번들링 해준다.
🔎 Entry
webpack 이 어떤 파일을 기준으로 번들링 할 지 그 시작점을 나타낸다. 기본값은 아래와 같이 src/index.js 이다.
module.exports = {
entry: './src/index.js'
};
naming
문자열 또는 문자열의 배열이 전달되면 main 으로 번들링 된다. 아래 예시와 같이 객체로 전달되면 각 key 가 이름이 되고 값이 엔트리 포인트가 되어 번들링 된다.
module.exports = {
...,
entry: {
home: './home.js',
about: './about.js',
contact: './contact.js',
},
...
};
endtry descriptor
엔트리에 객체를 전달할 경우 추가 옵션을 설정할 수 있는데 이를 descriptor 라 한다.
module.exports = {
...,
entry: {
home: './home.js',
shared: ['react', 'react-dom', 'redux', 'react-redux'],
catalog: {
import: './catalog.js', // 엔트리 파일
filename: 'pages/catalog.js', // 번들링 결과물의 경로와 이름
dependOn: 'shared', // 공유할 모듈 옵션
chunkLoading: false, // 요청 시 로드되는 청크를 비활성화하고 모든 것을 기본 청크에 넣습니다.
},
personal: {
import: './personal.js',
filename: 'pages/personal.js',
dependOn: 'shared',
chunkLoading: 'jsonp',
asyncChunks: true, // 요청 시 로드되는 비동기 청크 생성
layer: 'name of layer', // 엔트리 포인트에 대한 레이어 설정
},
},
...
};
🔎 Context
loader, entry 옵션의 기본디렉토리를 나타내는 옵션으로 절대경로로 설정한다.
const path = require('path');
module.exports = {
...,
context: path.resolve(__dirname, 'app'),
...
};
🔎 Output
webpack 으로 번들링한 결과물의 옵션을 나타낸다.
filename
번들링한 결과물의 이름을 지정한다. [name] 을 사용하면 entry 에서 전달한 key 값으로 파일명이 설정된다. (이 외에 [id], [hash] 등을 사용할 수도 있다.)
path
번들링한 결과물이 저장되는 경로를 지정한다.
publicPath
번들링된 경과물을 브라우저에서 접근할 때 사용하는 경로를 지정한다. 또한, loader 옵션에서 처리하는 파일 경로에 prefix 로 적용되는 경로이기도 하다.
module.exports = {
...,
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'public/assets'),
publicPath: '/assets/',
},
...
};
이 외에도 다양한 옵션이 있으며 이는 공식문서에서 확인 가능하다.
🔎 Module
해당 프로젝트에서 다른 유형의 모듈을 처리하기 위해 설정하는 옵션이다. 주로 loader 를 사용하며 기본적으로 javascript 밖에 처리할 수 없는 webpack 이 다양한 형식의 파일을 해석하기 위해 사용된다.
rules.test
loader 를 이요하여 변활하게 될 파일의 확장자를 나타낸다.
rules.use
어떠한 loader 를 사용할지를 정의하는 것으로 문자열의 배열을 통해 나타낼 수도 있고 객체를 통해 나타낼 수 있다.
(배열일 경우 오른쪽부터 왼쪽으로 loader 가 적용된다.)
rules.use.loader
적용할 loader 를 나타낸다.
rules.use.options
loader 에 적용될 옵션들을 나타낸다.
rules.exclude
loader 가 적용되지 않을 파일을 설정한다. (test 의 반대)
module.exports = {
...,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
{'targets': 'defaults'}
]
}
}
}
]
},
...
}
이 외에도 다양한 옵션이 있으며 이는 공식문서에서 확인 가능하다.
🔎 Plugins
webpack 이 번들링을 수행할 때 커스티마이징 하는데 사용되는 플러그인들을 배열로 지정한다. loader 는 파일을 해석하고 변환하는 과정에서 적용되는 것이라면 plugins 는 번들링한 결과물에 적용된다.
// html 을 동적으로 생성할 수 있도록 하는 plugin
import HtmlWebpackPlugin from 'html-webpack-plugin';
// 빌드 이전 결과물을 제거를 하는 plugin
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
module.exports = {
...,
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
new CleanWebpackPlugin(),
],
...
}
🔎 Resolve
webpack 이 해당 모듈을 해석하는 방식을 변경할 수 있다.
alias
import (혹은 require) 로 간단히 특정 모듈의 별칭을 지정한다.
// webpack.config.js
module.exports = {
...,
resolve: {
alias: {
Utilities: path.resolve(__dirname, 'src/utilities/'),
Templates: path.resolve(__dirname, 'src/templates/'),
},
},
...
};
// project
import Utility from '../../utilities/utility'; // before
import Utility from 'Utilities/utility'; // after
extentions
module 을 import 할 때 확장자를 적지 않아도 webpack 이 이를 해석할 수 있도록 하는 옵션이다. 문자열의 배열로 지정하며 오른쪽에서 왼쪽으로 적용한다.
module.exports = {
...,
resolve: {
extensions: ['.wasm', '.mjs', '.js', '.json'],
},
...
};
modules
module 을 해석할 때 검색할 디렉토리를 나타낸다. 절대경로와 상대경로 모두 허용된다.
module.exports = {
...,
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
},
...
};
plugins
추가로 해석할 플러그인들을 나타낸다.
module.exports = {
...,
resolve: {
plugins: [
// tsconfig 에서 path 로 설정한 내용을 webpack 해석하도록 하는 plugin
new TsconfigPathsPlugin({
configFile: tsConfigPath,
}),
],
},
...
};
🔎 Mode
webpack 에 내장된 최적화 기능을 사용하기 위한 옵션
development
DefinePlugin 의 process.env.NODE_ENV 를 development 로 설정한다.
production
DefinePlugin 의 process.env.NODE_ENV 를 production 로 설정한다. (기본값)
none
기본 최적화 옵션 적용 안함.
module.exports = {
mode: 'development',
...
};
🔎 Devtool
source map 생성 여부와 스타일을 설정하는 옵션이다. source map 은 원본 파일과 번들링한 파일을 매핑해주는 역활을 한다. source map 스타일에 대한 자세한 내용은 공식문서에서 확인 가능하다.
🔎 Target
번들링한 JavaScript 의 타겟 버전을 지정한다. node 와 web 을 지정할 수 있으며 각 옵션에 대한 버전 또한 지정할 수 있다.
module.exports = {
...,
target: ['web', 'es5'],
...
};
🔎 Externals
번들링할 때 제외할 파일들을 나타낸다. 번들링 단계에서 해당 모듈이 존재하지 않더라도 에러가 발생하지 않는다. CDN 으로 모듈을 사용할 경우 externals 를 사용할 수 있다.
<!-- index.html -->
<script
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous"
></script>
// webpack.config.js
module.exports = {
...,
externals: {
jquery: 'jQuery',
},
...
};
// project
import $ from 'jquery';
$('.my-element').animate(/* ... */);
참고
https://webpack.js.org/
https://jjnooys.medium.com/webpack-config-js-훑어보기-99fcfc649a04