1 集成要點
1.1 配置技巧
1.1.1 多入口配置
Multiple entry files are allowed. It is useful for a multi-page app.
// main1.js
document.write('<h1>Hello World</h1>');
// main2.js
document.write('<h2>Hello Webpack</h2>');
index.html
<html>
? <body>
????<script src="bundle1.js"></script>
? ? <script src="bundle2.js"></script>
? </body>
</html>
webpack.config.js
module.exports ={
?entry:{
???bundle1: './main1.js',
???bundle2: './main2.js'
? },
?output:{
???filename: '[name].js'
? }
};
1.1.2 CSS-loader
Demo04: CSS-loader(source)
????Webpack allows you torequire CSS in JS file, then preprocessed CSS file with CSS-loader.
main.js
require('./app.css');
app.css
body{
? background-color: blue;
}
index.html
<html>
? <head>
? ? <script type="text/javascript" src="bundle.js"></script>
? </head>
? <body>
? ? <h1>Hello World</h1>
? </body>
</html>
webpack.config.js
module.exports ={
?entry: './main.js',
?output:{
???filename: 'bundle.js'
? },
? module:{
???loaders:[
?????{ test: /\.css$/, loader: 'style-loader!css-loader'},
??? ]
? }
};
????????Attention, you have to use two loaders to transform CSS file. First is?CSS-loader?to read CSS file, and another is?Style-loader?to insert Style tag into HTML page. Different loaders are linked by exclamation mark(!).
????????After launching the server, index.html will have internal stylesheet.
<head>
? <script type="text/javascript" src="bundle.js"></script>
? <style type="text/css">
??? body{
? ? ? background-color: blue;
??? }
? </style>
</head>
1.1.3 Imageloader
Demo05: Imageloader (source)
????????Webpack could also requireimages in JS files.
main.js
var img1 = document.createElement("img");
img1.src = require("./small.png");
document.body.appendChild(img1);
var img2 = document.createElement("img");
img2.src = require("./big.png");
document.body.appendChild(img2);
index.html
<html>
? <body>
? ? <script type="text/javascript" src="bundle.js"></script>
? </body>
</html>
webpack.config.js
module.exports ={
?entry: './main.js',
?output:{
???filename: 'bundle.js'
? },
?module:{
???loaders:[
?????{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
??? ]
? }
};
? ??url-loader?transforms image files.If the image size is smaller than 8192 bytes, it will be transformed into DataURL; otherwise, it will be transformed into normal URL. As you see, question mark(?) is used to pass parameters into loaders.
????After launching the server, small.png and big.png will have the followingURLs.
<img src="data:image/png;base64,iVBOR...uQmCC">
<img src="4853ca667a2b8b8844eb2693ac1b2578.png">
1.1.4 代碼混淆插件UglifyJs Plugin
Demo07: UglifyJsPlugin (source)
????????Webpack has a plugin system to expand its functions. For example,?UglifyJs Plugin?will minify output(bundle.js) JS codes.
main.js
var longVariableName = 'Hello';
longVariableName += ' World';
document.write('<h1>'+ longVariableName +'</h1>');
index.html
<html>
? <body>
? ? <script src="bundle.js"></script>
? </body>
</html>
webpack.config.js
var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
module.exports ={
? entry: './main.js',
? output:{
? ? filename: 'bundle.js'
? },
? plugins:[
??? new uglifyJsPlugin({
? ? ? compress:{
? ? ? ? warnings: false
? ? ? }
? ? })
? ]
};
????????After launching the server, main.js will be minified into following.
var o="Hello"; o+=" World", document.write("<h1>" + o + "</h1>")
1.1.5 HTMLWebpack Plugin and Open Browser Webpack Plugin
Demo08: HTML Webpack Plugin and Open Browser Webpack Plugin (source)
????????This demo shows you how toload 3rd-party plugins.
????????html-webpack-plugin?could createindex.htmlforyou, and?open-browser-webpack-plugin?could open a new browser tab when Webpack loads.
main.js
document.write('<h1>Hello World</h1>');
webpack.config.js
var HtmlwebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');
module.exports ={
? entry: './main.js',
? output:{
? ? filename: 'bundle.js'
? },
? plugins:[
??? new HtmlwebpackPlugin({
? ? ? title: 'Webpack-demos',
? ? ? filename: 'index.html'
? ? }),
??? new OpenBrowserPlugin({
? ? ? url: 'http://localhost:8080'
? ? ?})
? ?]
};
Run webpack-dev-server.
$ webpack-dev-server
????????Now you don't need to write index.html by hand and don't have to open browser by yourself. Webpack did all these things for you.
1.1.6 環(huán)境標(biāo)記
Demo09: Environmentflags (source)
????????You can enable some codes only in development environment with environment flags.
main.js
document.write('<h1>Hello World</h1>');
if (__DEV__) {
? document.write(new Date());
}
index.html
<html>
? <body>
? ? <script src="bundle.js"></script>
? </body>
</html>
webpack.config.js
var webpack = require('webpack');
var devFlagPlugin = new webpack.DefinePlugin({
? __DEV__ : JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
});
module.exports ={
? entry: './main.js',
? output:{
? ? filename: 'bundle.js'
? },
? plugins:[devFlagPlugin]
};
Now pass environment variable into webpack.
# Linux & Mac
$ env DEBUG=true webpack-dev-server
# Windows
$ setDEBUG=true
$ webpack-dev-server
1.1.7 代碼分割Code splitting
Demo10: Codesplitting (source)
????????For big web apps it’s not efficient to put all code into a single file, Webpack allows you to split them into several chunks. Especially if some blocks of code are only required under some circumstances, these chunks could be loaded on demand.
????????At first, you use require.ensure to define a split point.(official?document)
// main.js
require.ensure(['./a'], function(require) {
? var content = require('./a');
? document.open();
? document.write('<h1>' +?content + '</h1>');
? document.close();
});
????????require.ensure tells Webpack that ./a.js should be separated from bundle.js and built into a single chunk file.
// a.js
module.exports = 'Hello World';
Now Webpack takes care of the dependencies, output files and runtime stuff. You don't have to put any redundancy into your index.html and webpack.config.js.
<html>
? <body>
? ? <script src="bundle.js"></script>
? </body>
</html>
webpack.config.js
module.exports ={
? entry : './main.js',
? output:{
? ? filename : 'bundle.js'
? }
};
????????Launch the server.
$ webpack-dev-server
????????On the surface, you won't feel any differences. However, Webpack actually builds main.js and a.js into different chunks(bundle.js and 1.bundle.js), and loads 1.bundle.js from bundle.js when on demand.
1.1.8 bundle-loader切割代碼Code splitting with bundle-loader
Demo11: Codesplitting with bundle-loader (source)
????????Another way of code splitting is using?bundle-loader.
// main.js
// Now a.js is requested, it will be bundled into another file
var load = require('bundle-loader!./a.js');
// To wait until a.js is available (and get the exports)
//?you need to async wait for it.
load(function(file) {
? document.open();
? document.write('<h1>' + file + '</h1>');
? document.close();
});
????????require('bundle-loader!./a.js') tells Webpack to load a.js from another chunk.
????????Now Webpack will build main.js into bundle.js, and a.js into 1.bundle.js.
1.1.9 用CommonsChunkPlugin提取通用代碼塊Common chunk
Demo12: Commonchunk (source)
????????When multi scripts have common chunks, you can extract the common part into a separate file withCommonsChunkPlugin.
// main1.jsx
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(<h1>Hello World</h1>, document.getElementById('a'));
// main2.jsx
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(<h2>Hello Webpack</h2>, document.getElementById('b'));
index.html
<html>
? <body>
? ? <div id="a"></div>
? ? <div id="b"></div>
? ? <script src="init.js"></script>
? ? <script src="bundle1.js"></script>
? ? <script src="bundle2.js"></script>
? </body>
</html>
webpack.config.js
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports ={
? entry:{
? ? bundle1: './main1.jsx',
? ? bundle2: './main2.jsx'
? },
? output:{
? ? filename: '[name].js'
? },
? module:{
? ? loaders:[
? ? {
???????test: /\.js[x]?$/,
???????exclude: /node_modules/,
???????loader: 'babel-loader',
???????query:{
?????????presets: ['es2015', 'react']
???????}
? ? },
??? ]
? },
?plugins:[
??? new CommonsChunkPlugin('init.js')
? ]
}
1.1.10 第三方庫代碼塊Vendorchunk
Demo13: Vendorchunk (source)
????????You can also extract the vendor libraries from a script into a separate file with CommonsChunkPlugin.
main.js
var $ = require('jquery');
$('h1').text('Hello World');
index.html
<html>
? <body>
? ? <h1></h1>
? ? <script src="vendor.js"></script>
? ? <script src="bundle.js"></script>
? </body>
</html>
webpack.config.js
var webpack = require('webpack');
module.exports ={
? entry:{
? ? app: './main.js',
? ? vendor: ['jquery'],
? },
? output:{
? ? filename: 'bundle.js'
??},
? plugins:[
??? new webpack.optimize.CommonsChunkPlugin(/* chunkName= */'vendor', /* filename= */'vendor.js')
? ]
};
????If you want a module available as variable in every module, such as making $ and jQuery available in every module without writing require("jquery"). You should use ProvidePlugin(Official doc).
// main.js
$('h1').text('Hello World');
// webpack.config.js
var webpack = require('webpack');
module.exports ={
? entry:{
??? app: './main.js'
? },
? output:{
? ? filename: 'bundle.js'
? },
? plugins:[
??? new webpack.ProvidePlugin({
????? $: "jquery",
????? jQuery: "jquery",
????? "window.jQuery": "jquery"
??? })
? ]
};
1.1.11 暴露全局變量
Demo14: Exposingglobal variables (source)
????????If you want to use some global variables, and don't want to include them in the Webpack bundle, you can enable externals field in webpack.config.js (official?document).
????????For example, we have a data.js.
var data = 'Hello World';
We can expose data as a global variable.
// webpack.config.js
module.exports ={
? entry: './main.jsx',
? output:{
? ? filename: 'bundle.js'
? },
?module:{
? ? loaders:[
? ? ?{
???????test: /\.js[x]?$/,
???????exclude: /node_modules/,
???????loader: 'babel-loader',
???????query:{
?????????presets: ['es2015', 'react']
???????}
? ? ?},
??? ]
? },
? externals:{
??? //require('data') is external and available
??? //? on the global var data
??? 'data': 'data'
? }
};
????????Now, you require data as a module variable in your script. but it actually is a global variable.
// main.jsx
var data = require('data');
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(<h1>{data}</h1>,
? document.body
);
1.1.12 熱更新HMR
Demo15: Hot ModuleReplacement (source)
? ??????Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running without a page reload.
????????You have?two ways?to enable Hot Module Replacement with the webpack-dev-server.
????(1) Specify --hot and --inline on the command line
$ webpack-dev-server --hot --inline
????????Meaning of the options:
????? --hot: adds the HotModuleReplacementPlugin and switch theserver to hot mode.
????? --inline: embed the webpack-dev-server runtime into the bundle.
????? --hot --inline: also adds the webpack/hot/dev-serverentry.
????(2) Modify webpack.config.js.
????? add new webpack.HotModuleReplacementPlugin() to the plugins field
????? add webpack/hot/dev-server and webpack-dev-server/client?http://localhost:8080 to the entry field
????????webpack.config.js looks like the following.
var webpack = require('webpack');
var path = require('path');
module.exports ={
? entry:[
??? 'webpack/hot/dev-server',
??? 'webpack-dev-server/client?http://localhost:8080',
??? './index.js'
? ],
? output:{
? ? filename: 'bundle.js',
? ? publicPath: '/static/'
? },
? plugins:[
??? new webpack.HotModuleReplacementPlugin()
? ],
?module:{
? ? loaders:[{
?????test: /\.jsx?$/,
?????exclude: /node_modules/,
?????loader: 'babel-loader',
?????query:{
???????presets: ['es2015', 'react']
?????},
?????include: path.join(__dirname, '.')
???}]
? }
};
????????Now launch the dev server.
$ webpack-dev-server
????????Visiting http://localhost:8080, you should see 'Hello World' in your browser.
????????Don't close the server. Open a new terminal to edit App.js, and modify 'Hello World' into 'Hello Webpack'. Save it, and see what happened in the browser.
App.js
import React, { Component } from 'react';
export default class App extends Component{
? render() {
??? return(<h1>Hello World</h1>);
? }
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
index.html
<html>
? <body>
? ? <div id='root'></div>
? ? <script src="/static/bundle.js"></script>
? </body>
</html>
2 參考鏈接
webpack入門級教程
http://www.tuicool.com/articles/bA3eym7
WebPack簡明學(xué)習(xí)教程
http://www.reibang.com/p/b95bbcfc590d
[新姿勢]前端革命掂林,革了再革:WebPack
https://segmentfault.com/a/1190000002507327
WebPack:更優(yōu)秀的模塊依賴管理工具砚嘴,及require.js的缺陷
http://www.kuqin.com/shuoit/20141221/344013.html
(Good)webpack解惑:多入口文件打包策略
http://www.cnblogs.com/lvdabao/p/5944420.html
webpack loader 列表
http://blog.csdn.net/keliyxyz/article/details/51649429
用Webpack打包你的一切
http://www.tuicool.com/articles/bIRBjmZ
使用 Webpack 模塊化 Angular 應(yīng)用程序
http://www.ibm.com/developerworks/cn/web/wa-modularize-angular-apps-with-webpack-trs/index.html
(Good)Angular中使用webpack基礎(chǔ)篇
http://www.tuicool.com/articles/qQJfEju
(Good)Webpack + Angular的組件化實踐
https://segmentfault.com/a/1190000003915443
AngularJS 進階(一) 按需加載controller js (轉(zhuǎn)帖)
https://my.oschina.net/sourcecoding/blog/304735
Code Splitting
https://webpack.js.org/guides/code-splitting/
(Good)webpack-demos
https://github.com/ruanyf/webpack-demos#demo12-common-chunk-source