webpack version : "^2.1.0-beta.15"
CommonsChunkPlugin
webpack.config.js
기본적은 webpack config 이다. 간단하게 설명하면, entry point 가 2개(login.jsx, main.jsx) 가 있고, webpack 은 이 파일을 시작으로 buildPath 에 app.bundle.login.js, app.bundle.main.js 를 만들 것이다.그런데 plugin 에 commonsPlugin 이 추가됐다. 이 pluin 이 있으면 여러 js 에 있는 녀석들중에 공통적으로 쓰이는 부분을 가져다고 common.js 를 만들게 된다.
var path = require('path');
var webpack = require('webpack');
var buildPath = 'build/'
var commonsPlugin =
new webpack.optimize.CommonsChunkPlugin('common');
module.exports = {
entry: {
'login': ['./src/js/login.jsx'],
'main': ['./src/js/main.jsx']
},
output: {
path: __dirname,
filename: buildPath + 'app.bundle.[name].js'
},
module: {
loaders: [
{
//tell webpack to use babel-loader for all *.jsx files
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
},
plugins: [commonsPlugin]
};
4가지 방법
ref. 1 을 보면 알 수 있다. CommonsChunkPlugin 를 사용하는 방법은 4가지가 있다.- 공통적인 부분을 묶어서 common.js 를 만드는 것.(참고)
- 공통적으로 쓰는 외부 라이브러리를 지정해서 vendor.js 를 만드는 것.(참고)
- code splitting (파일의 공통부분을 하나로 묶는 등의 작업과 on-demand 로 불러오게 하는 작업)이랑 연관해서 child chunk 를 만들 수 있는데, 이녀석들의 공통적인 부분을 빼서 parent 로 넣는 방법.(참고)
- 3번이랑 비슷하게 공통적인 부분을 빼서 async 하게 load 하는데, 이 공통적인 부분을 parent 안에 넣는 것이 아니라 그냥 다른 파일로 만들어서 load 하는 방법(참고)
3, 4 번은 사용해 보지 않아서 여기서 설명하지 않는다.
common
공통적인 부분을 빼서 .js 로 만드는 설정이다. 아래처럼 'common' 이라는 parameter 를 넘겨주면 된다. object {} 를 넘겨서 좀 더 자세한 설정을 할 수 있다.var commonsPlugin =
new webpack.optimize.CommonsChunkPlugin('common');
아래는 ref. 1 에 있는 예시를 가져왔다.
new CommonsChunkPlugin({ name: "commons", // (the commons chunk name) filename: "commons.js", // (the filename of the commons chunk) // minChunks: 3, // (Modules must be shared between 3 entries) // chunks: ["pageA", "pageB"], // (Only use these entries) })
그리고 당연한 이야기지만, 이렇게 common.js 가 만들어지면, 이녀석을 <script> tag 를 사용해서 html page 에서 load 해줘야 한다.
<script src="commons.js" charset="utf-8"></script> <script src="entry.bundle.js" charset="utf-8"></script>
vendor
이건 외부라이브러리만 따로 묶어서 .js 를 만드는 방법이다. 아래처럼 CommonsChunkPlugin 의 parameter 로 'vendor' 를 넘겨주고, entry 에 vendor 를 추가해 주면 된다. 참고로, 자신이 만든 utils library 등도 같이 포함시킬 수 있다.- output.libraryTarget : 만약 "Uncaught ReferenceError: xxx is not defined" 같은 error 가 보인다면, 'umd' 로 설정해주자. 기본 값이 'var' 이다.
var commonsPlugin =
new webpack.optimize.CommonsChunkPlugin('vendor');
//webpack.config.js ... var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('vendor'); module.exports = { entry: { 'login': ['./src/js/login.jsx'], 'main': ['./src/js/main.jsx'], 'vendor' : ['jquery', 'react', 'react-dom', './src/js/util.jsx'] }, output: { path: __dirname + buildPath,
filename: 'app.bundle.[name].js', libraryTarget: 'umd' }, module: { loaders: [ { //tell webpack to use babel-loader for all *.jsx files test: /.jsx?$/, loader: 'babel-loader', exclude: /node_modules/, query: { presets: ['es2015', 'react'] } } ] }, plugins: [commonsPlugin] };
vendor.js
'vendor' option 이 동작하지 않는 경우
new webpack.optimize.CommonsChunkPlugin('vendor');로 설정할 때 output.filename 이 제대로 적용되지 않았다. 그래서
new webpack.optimize.CommonsChunkPlugin({name: 'vendor'});를 사용하니 됐다.
그런데 여러모로 정상적으로 compile 이 되지 않았다. 결과적으로 이 현상은 node_modules 를 다 지우고 다시 설치해서 해결이 됐다.
정확한 이유는 알지못하지만, 필자가 package 의 버전을 바꾸기 위해 자꾸 package 를 변경했는데, 그 덕에 꼬인듯 하다.
기본적으로 name 만 설정하면 output.filename 의 설정을 같이 따른다. 만약에 file 이름을 다르게 가져가고 싶다면 CommonsChunkPlugin option 에 'filename' 을 추가할 수 있다.
new webpack.optimize.CommonsChunkPlugin({name: 'vendor', filename: 'vendor.js'});
참고로, 기본적으로 vendor.js 는 output.path 에 생성된다.
import
이것도 당연하게, script tag 로 load 를 해야 한다. 참고로 위의 예제에서는 app.bundle.[name].js 로 만들어지기 때문에 app.bundle.vendor.js 가 만들어진다.주의할 점은 이렇게 vendor script 를 include 한다고, 그냥 entry.[name].js 내에서 호출할 수 있는 건 아니다. 반드시 import 를 해줘야 한다. import 를 해줘야 webpack 에서 library 이름을 바꾸는데, 그 이름으로 대체(replacement) 해준다.
<script src="vendor.js" charset="utf-8"></script> <script src="entry.bundle.js" charset="utf-8"></script>
Reference
- CommonsChunkPlugin < list of plugins, webpack github.io
댓글 없음:
댓글 쓰기