번들된 결과물을 처리
번들된 자바스크립트를 난독화 한다거나 특정 텍스트를 추출하는 용도로 사용됨
// my-webpack-plugin.js
// 플러그인은 class로 작성
class MyWebpackPlugin {
apply(compiler) {
compiler.plugin('emit', (compilation, callback) => {
// source() => 웹팩이 번들링한 결과물의 소스코드를 가져오는 함수
// compilation 객체를 이용해서 웹팩이 번들링한 결과물에 접근할수 있다
const source = compilation.assets['main.js'].source();
compilation.assets['main.js'].source = () => {
const banner = [
'/**',
' * 이것은 BannerPlugin이 처리한 결과이다.',
' * Build Date: 2019-10-10',
' */'
].join('\n');
return banner + '\n\n' + source;
}
callback();
})
}
}
module.exports = MyWebpackPlugin;
// webpack.config.js
const path = require('path');
const MyWebpackPlugin = require('./my-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
main: './src/app.js'
},
output: {
path: path.resolve('./dist'),
filename: '[name].js'
},
module: {},
// 플러그인 설정
plugins: [
// 플러그인은 클래스이므로 new 생성자로 인스턴스 생성
new MyWebpackPlugin()
]
}
번들링된 결과물 상단에 빌드 정보나 커밋 버전 등을 추가할 수 있다.
const path = require('path');
// 웹팩에서 직접 제공하는 플러그인으로 웹팩을 불러와야한다.
const webpack = require('webpack');
// 터미널 명령어를 실행할수 있는 모듈
const childProcess = require('child_process');
module.exports = {
mode: 'development',
entry: {
main: './src/app.js'
},
output: {
path: path.resolve('./dist'),
filename: '[name].js'
},
module: {},
plugins: [new webpack.BannerPlugin({
banner: `
Build Date: ${new Date().toLocaleString()}
Commit Version: ${childProcess.execSync('git rev-parse --short HEAD')}
Author: ${childProcess.execSync('git config user.name')}
`
})]
}
빌드타임에 결정되는 환경변수를 어플리케이션 단에 주입하기 위한 플러그인
const path = require('path');
// 마찬가지로 웹팩에서 직접 제공하는 플러그인으로 웹팩을 불러와야한다.
const webpack = require('webpack');
module.exports = {
mode: 'development', // 개발환경
entry: {
main: './src/app.js'
},
output: {
path: path.resolve('./dist'),
filename: '[name].js'
},
module: {},
plugins: [new webpack.DefinePlugin({
// 직접 환경변수 설정 가능
CODE_TWO: '1+1', // CODE
STRING_TWO: JSON.stringify('1+1'), // 문자열
'api.domain': JSON.stringify('http://dev.api.domain.com') // 객체타입
})]
}
// app.js
/*설정한 환경변수 접근 가능*/
console.log('process.env.NODE_ENV', process.env.NODE_ENV); // development
console.log('CODE_TWO', CODE_TWO); // 2
console.log('STRING_TWO', STRING_TWO); // 1+1
console.log('api.domain', api.domain); // http://dev.api.domain.com
빌드 타임에 HTML도 포함시키는 플러그인
$ npm install -D html-webpack-plugin // 설치 필요
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plguin');
module.exports = {
mode: 'development',
entry: {
main: './src/app.js'
},
output: {
path: path.resolve('./dist'),
filename: '[name].js'
},
module: {},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // 템플릿 경로
// 템플릿에 넣어줄 변수 값을 전달
templateParameters: {
env: process.env.NODE_ENV === 'development' ? '(개발용)' : ''
},
// html 압축 (개발 환경일 때만)
minify: process.env.NODE_ENV === 'production' ? {
collapseWhitespace: true, // 빈칸 제거
removeComments: true, // 주석 제거
} : false
})
]
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- EJS문법: env를 넣을수 있는 템플릿 문법 -->
<!-- Webpack에서 HtmlTemplatePlugin으로 env의 값을 넣어줄 수 있다. -->
<title>Document<%= env %></title>
</head>
<body>
</body>
</html>
NODE_ENV=development npm run build
오류: 'NODE_ENV'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치파일이 아닙니다.
$ npm install -g win-node-env // node-env를 글로벌로 설치해서 해결
빌드 이전 결과물을 제거하는 플러그인
$ npm install -D clean-webpack-plugin // 설치 필요
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plguin');
module.exports = {
mode: 'development',
entry: {
main: './src/app.js'
},
output: {
path: path.resolve('./dist'),
filename: '[name].js'
},
module: {},
plugins: [new CleanWebpackPlugin()]
}
번들된 자바스크립트 코드에서 CSS를 별도 파일로 뽑아내는 플러그인
$ npm install -D mini-css-extract-plugin // 설치 필요
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plguin');
module.exports = {
mode: 'development',
entry: {
main: './src/app.js'
},
output: {
path: path.resolve('./dist'),
filename: '[name].js'
},
module: {
rules: [
{
test: /\.css$/,
// MiniCSSExtractPlugin을 사용하려면 style-loader 대신에 자체 로더를 사용해야한다.
use: [
process.env.NODE_ENV === 'production'
? MiniCssExtractPlugin.loader
: 'style-loader',
'css-loader'
]
}
]
},
// 배포 환경일때만 설정
plugins: [...(process.env.NODE_ENV === 'production'
? [new MiniCssExtractPlugin({filename: '[name].css'})]
: []
)
}
'[name]' => 원본 파일이름으로 설정. 아니면 해시 값으로 설정됨