지금 유지보수하고 있는 모니터링 시스템은 운영중인 사이트와 다르게 vue.js (+webpack) 설정으로 구성되어 있다.
다른 사람이 설정해놓은 웹팩을 가져다 쓰기 보다는 이해하고 사용하고 싶어서, 하나씩 분석해보기로 했다.
(참고: webpack 은 3.x 버전이다)
우선, 각 환경별로 설정되어 있는 webpack config 에서 공통으로 사용하는 webpack.base.conf.js
'use strict';
const webpack = require('webpack');
const path = require('path');
const utils = require('./utils');
const config = require('../config');
const vueLoaderConfig = require('./vue-loader.conf');
module.exports = {
// 복잡한 상대경로를 쉽게 사용하도록 하는 option
context: path.resolve(__dirname, '../'),
// 번들 프로세스를 시작할 지점
entry: './src/main.js',
output: {
path: config.build.assetsRoot,
filename: '[name].js', // 청크 출력 이름을 별도로 지정 (df. [id].js)
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
// 동일한 이름의 다른 확장자를 가진 파일이라면 배열에 정의한 순서대로 해결하도록 하는 option (해결한 뒤 건너뜀)
extensions: ['.js', '.vue', '.json'],
// 특정 디렉토리를 특정 문자열로 치환해서 사용하기 위한 option
alias: {
'@': path.join(__dirname, '..', 'src'),
}
},
module: {
// 모듈이 생성될 때 요청에 일치하는 규칙 배열로 모듈이 생성되는 방식을 수정할 수 있는 option
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.join(__dirname, '..', 'src'),
path.join(__dirname, '..', 'test'),
path.join(__dirname, '..', 'node_modules/webpack-dev-server/client')
]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
setImmediate: false,
// @hajs webpack5 에서는 automatic node.js polifills 가 제거되어 필요없습니다.
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
},
plugins: [
// 웹팩으로 빌드한 결과물로 HTML 파일을 생성해주는 플러그인 (HTML 생성의 단순화)
new HtmlWebpackPlugin({
filename: 'index.html',
template: config.build.index,
inject: true,
minify: process.env.NODE_ENV === 'production' ? {
removeComments: true, // 주석 제거
collapseWhitespace: true, // 빈칸 제거
removeAttributeQuotes: true // 따옴표의 중복인 경우 따옴표 생략 (HTML 은 항상 따옴표를 사용하도록 권장하긴 함..)
} : false
}),
// 특정 폴더에 있는 자원들을 빌드할 때 내가 선언한 위치로 옮겨주는(복붙해주는) 플러그인
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory,
ignore: ['.*']
}
]),
// 환경별로 자원을 별도로 관리하도록 지원해주는 플러그인
new webpack.DefinePlugin({
'process.env': require(`../config/${process.env.NODE_ENV_SHORT}.env`)
}),
// 빌드 이전의 결과물을 제거하는 플러그인
new CleanWebpackPlugin(),
]
};
그 다음으로는 개발환경에서 사용할 webpack.dev.conf.js
'use strict';
const webpack = require('webpack');
const merge = require('webpack-merge');
const base = require('./webpack.base.conf');
const utils = require('./utils');
const config = require('../config');
const path = require('path');
const portfinder = require('portfinder');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
// webpack.base.conf.js 내용을 가져와서 병합하는 방식
const devWebpackConfig = merge(base, {
// @hajs mode 옵션은 webpack4+ 버전부터 지원합니다.
// mode: 'developement',
// 디버깅 프로세스를 향상시킬 소스 매핑 스타일 (cheap-module-eval-source-map : 고품질 운영 환경에 적합)
// todo @hajs webpack5 부터는 `eval-cheap-module-source-map` 를 사용해야 합니다.
devtool: config.dev.devtool,
plugins: [
// HMR 을 활성화 시키는 방법, devServer.hot 옵션까지 써줘야 브라우저가 자동으로 reload 해줌 (옵션을 안써주면 webpack 작업만 자동으로 실행됨)
new webpack.HotModuleReplacementPlugin(),
// 번들링된 웹팩 파일 로그에 상세 경로를 함께 출력해주는 플러그인
new webpack.NamedModulesPlugin(),
// 컴파일 도중 오류가 발생했을 때 오류가 발생한 리소스는 제외하고 번들링해주는 플러그인
new webpack.NoEmitOnErrorsPlugin(),
],
devServer: {
// inline 모드를 사용할 때 DevTools 콘솔에서 표시될 level (df.info)
// todo @hajs webpack6 이후부터는 제거될 옵션이라고 안내하고 있다.
clientLogLevel: 'warning',
// History API 또는 react-router 등을 사용하는 경우 새로고침시 404 에러를 해결해주는 option
historyApiFallback: true,
// HMR(핫 모듈 교체) 기능 활성화 여부
// HMR : 내용이 변경된 모듈을 페이지 새로고침 없이 런타임에서 업데이트하고, 업데이트에 실패할 경우 새로고침을 수행
hot: true,
// 번들링된 자원을 서비스할 위치를 지정, CopyWebpackPlugin 을 사용하기 떼문에 필요하지 않아서 비활성화 시킨다.
contentBase: false,
// 제공되는 모든 항목에 gzip 압축 사용여부
compress: true,
// 사용할 호스트 지정
host: process.env.HOST || config.dev.host,
// 요청을 수신할 포트 지정
port: (process.env.PORT && Number(process.env.PORT)) || config.dev.port,
// 서버가 시작되면 브라우저를 열도록 하는 옵션 (df.true)
open: config.dev.autoOpenBrowser,
// 컴파일러 오류 또는 경고가 있을 때 브라우저 전체 화면에 오버레이를 표시하는 옵션 (df.false)
overlay: {
warnings: true,
errors: true,
},
// devServer 에서는 번들된 결과물을 메모리에 저장하므로 별도의 선언이 필요하고, 보통 output 에 적어준 publicPath 와 동일하게 선언하면 된다.
publicPath: config.dev.assetsPublicPath,
// proxy 서버를 띄워서 브라우저->서버가 아닌 서버->서버로 요청을 보내는 option. CORS 에러를 피할 수 있다.
proxy: config.dev.proxyTable,
// 초기 시작 정보 외에 콘솔에 아무것도 기록하지 않는 옵션, FriendlyErrorsPlugin 를 사용하기 때문에 필요하지 않아서 비활성화 시킨다.
quiet: true,
// 웹팩은 파일 시스템을 사용해서 파일 변경 사항을 알리는데 NFS(Network File System) 을 사용하는 경우 작동하지 않아서 이런 경우 polling 을 사용한다.
watchOptions: {
poll: config.dev.poll,
}
},
});
// 실행 가능한 포트를 찾아서 devServer 에 연결
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port;
console.log("*** "+portfinder.basePort); // 8088
portfinder.getPort((err, port) => {
if (err) {
console.log("portFinder eror!");
reject(err);
} else {
console.log("portFinder success! port:"+port);
process.env.PORT = port;
devWebpackConfig.devServer.port = port;
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}));
resolve(devWebpackConfig);
}
})
});
module.exports = devWebpackConfig;
정리하면서..
- 환경 구성은 common, dev, prd 3개로 나눠서 관리하면 편하다.
- 웹팩은 기본적으로 javascript 만 알고 있기 때문에 css, html 을 읽고 합쳐주는 style-loader, css-loader 가 필요하다.
(vue 는 공식홈페이지에서 style-loader 와 css-loader 를 함께 사용하는 것을 권장했다.)
참고 사이트
https://webpack.js.org/configuration/entry-context/#context
https://github.com/jantimon/html-webpack-plugin
https://joshua1988.github.io/webpack-guide/devtools/source-map.html#%EC%86%8C%EC%8A%A4-%EB%A7%B5
반응형
'Frontend > Webpack' 카테고리의 다른 글
[Webpack] webpack plugins 정리 (0) | 2021.06.25 |
---|---|
[Webpack] devServer option 정리 (0) | 2021.06.25 |
[Webpack] webpack option 정리 (0) | 2021.06.25 |
댓글