## 簡單的文件打包
### 1.創建文件目錄

dist:目標生成文件夾;src:源文件夾;src下的script和style:js和css源文件夾。
**index.html**
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpackDemo2</title>
</head>
<body>
<script type="text/javascript" src="bundle.js">
</script>
</body>
</html>
~~~
**main.js**
~~~
function main(){
return{}
}
~~~
**webpack.config.js**
~~~javascript
var path = require('path'); // webpack2.0 以后,路徑需要引用這個模塊
module.exports = {
entry: './src/script/main.js',
output:{
path: path.resolve(__dirname,'./dist/js'),
filename: 'bundle.js'
}
}
~~~
### 2.執行webpack命令打包

如入口與輸出一節類似,我們會看到dist下面多了個js文件夾,并且js文件夾里面多了個bundle.js,:

**bundle.js自動生成第一個chunk為0**
~~~javascript
/* 0 */
/***/ (function(module, exports) {
function main(){
return{}
}
/***/ })
/******/ ]);
~~~
### 3.兩個js文件打包成一個js
**修改webpack.config.js**
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
module.exports = {
entry: ['./src/script/main.js', './src/script/another.js'], //將entry修改成js文件的數組
output:{
path: path.resolve(__dirname,'./dist/js'),
filename: 'bundle.js'
}
}
~~~

**新的bundle.js**
~~~javascript
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(1);
module.exports = __webpack_require__(2);
/***/ }),
/* 1 */
/***/ (function(module, exports) {
function main(){
return{}
}
/***/ }),
/* 2 */
/***/ (function(module, exports) {
function another(){
alert('another');
}
/***/ })
/******/ ]);
~~~
新生成的3個chunks,其中chunk0是將兩個不相干的模塊`_webpack_require(1)`與`webpackrequire__(2)`聯系起來。
### 4.兩個文件打包完分別輸出各自的打包文件
**修改webpack.config.js**
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
module.exports = {
entry: { //將entry修改成對象形式
main: './src/script/main.js',
another: './src/script/another.js'
},
output:{
path: path.resolve(__dirname,'./dist/js'),
filename: 'bundle.js'
}
}
~~~
這個時候會出現報錯:

因為兩個文件分開輸出到各自的打包文件,但是我們輸出出口都是bundle.js,所以是錯誤的。
**再修改webpack.config.js**
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
module.exports = {
entry: {
main: './src/script/main.js',
another: './src/script/another.js'
},
output:{
path: path.resolve(__dirname,'./dist/js'),
filename: '[name]-[chunkhash]-bundle.js'
}
}
~~~
可以在filename中使用[占位符(substitutions)](https://doc.webpack-china.org/configuration/output/#output-filename)來確保每個文件具有唯一的名稱。
重新打包生成

在dist/js下生成了兩個js文件

**main-df5c09aabd3c2b72c8f4-bundle.js**
~~~javascript
/* 0 */
/***/ (function(module, exports) {
function main(){
return{}
}
/***/ })
/******/ ]);
~~~
**another-d6deaccdba4ac37ddc27-bundle.js**
~~~javascript
/* 0 */,
/* 1 */
/***/ (function(module, exports) {
function another(){
alert('another');
}
/***/ })
/******/ ]);
~~~
## 使用plugin,這里介紹[插件html-webpack-plugin](https://www.npmjs.com/package/html-webpack-plugin)
### 1.安裝插件
~~~javascript
npm install html-webpack-plugin --save-dev
~~~
### 2.修改webpack.config
~~~
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
main: './src/script/main.js',
another: './src/script/another.js'
},
output:{
path: path.resolve(__dirname,'./dist/js'),
filename: '[name]-[chunkhash]-bundle.js'
},
plugins:[
new htmlWebpackPlugin()
]
}
~~~
### 3.打包生成

發現dist/js下除了新生成的js還有一個index.html文件
~~~html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<script type="text/javascript" src="main-df5c09aabd3c2b72c8f4-bundle.js"></script><script type="text/javascript" src="another-d6deaccdba4ac37ddc27-bundle.js"></script></body>
</html>
~~~
發現生成的index.html自動引入打包后的`another-chunkhash-bundle.js`和`mian-chunkhash-bundle.js`,然而這樣生成的html是固定的,研究一下這個插件,我們應該可以利用模板生成自定義的html。
### 4.利用插件按模板生成html
**修改模板index.html**
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改后模板中的title</title>
</head>
<body>
<script type="text/javascript" src="bundle.js">
</script>
</body>
</html>
~~~
**再次打包生成**

**新生成的dist/js下的index.html**
發現title與我們的模板中修改的一樣
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改后模板中的title</title>
</head>
<body>
<script type="text/javascript" src="bundle.js">
</script>
<script type="text/javascript" src="main-df5c09aabd3c2b72c8f4-bundle.js"></script><script type="text/javascript" src="another-d6deaccdba4ac37ddc27-bundle.js"></script></body>
</html>
~~~
### 5.分開生成的文件
**修改webpack.config**
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
main: './src/script/main.js',
another: './src/script/another.js'
},
output:{
path: path.resolve(__dirname,'./dist'),
filename: 'js/[name]-[chunkhash]-bundle.js' //將相對路徑分配到filename中
},
plugins:[
new htmlWebpackPlugin({
template: 'index.html'
})
]
}
~~~

**新的文件目錄**

### 6.plugin的[其他options參數](https://www.npmjs.com/package/html-webpack-plugin)
**修改webpack.config**
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
main: './src/script/main.js',
another: './src/script/another.js'
},
output:{
path: path.resolve(__dirname,'./dist'),
filename: 'js/[name]-[chunkhash]-bundle.js'
},
plugins:[
new htmlWebpackPlugin({
template: 'index.html',
filename: 'index-[hash].html',
inject: 'body', //打包生成的js,css和其他東西注入的位置
title: 'This is my plugin title',
minify:{ //壓縮代碼,下面意思是省去空格、移除注釋,更多的查看插件官網
collapseWhitespace: true,
removeComments: true,
}
})
]
}
~~~
**dist下新生成的index-f8cd6c5d985e6b29bd44.html**
發現空格和注釋都沒了
~~~
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>修改后模板中的title</title></head><body><script type="text/javascript" src="bundle.js"></script><script type="text/javascript" src="js/main-ce4b1548dce5dea612ac-bundle.js"></script><script type="text/javascript" src="js/another-f16463e116d027221d92-bundle.js"></script></body></html>
~~~
### 7.plugin模板產生交互
例如我們想讓根目錄index.html下面的模板調取webpack.config.js里面plugins的title,我們就需要在根目錄index.html用EJS
**修改模板index.html**
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></option></title>
</head>
<body>
<script type="text/javascript" src="bundle.js">
</script>
<!-- 這里是注釋 -->
</body>
</html>
~~~
**dist下新生成的index(注意title)**
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>This is my plugin title</title>
</head>
<body>
<script type="text/javascript" src="bundle.js">
</script>
<script type="text/javascript" src="js/main-ce4b1548dce5dea612ac-bundle.js"></script><script type="text/javascript" src="js/another-f16463e116d027221d92-bundle.js"></script></body>
</html>
~~~
### 8.獲取plugin更多的options
**修改webpack.config**
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
main: './src/script/main.js',
another: './src/script/another.js'
},
output:{
path: path.resolve(__dirname,'./dist'),
filename: 'js/[name]-[chunkhash]-bundle.js'
},
plugins:[
new htmlWebpackPlugin({
template: 'index.html',
filename: 'index-[hash].html',
inject: 'head', //打包生成的js,css和其他東西注入的位置
title: 'This is my plugin title',
date: new Date(),
minify:{ //壓縮代碼,下面意思是省去空格、移除注釋,更多的查看插件官網
collapseWhitespace: false,
removeComments: true,
}
})
]
}
~~~
**修改模板index.html**
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<script type="text/javascript" src="bundle.js"></script>
<!-- 這里是注釋 -->
<%= htmlWebpackPlugin.options.date %>
<% for (key in htmlWebpackPlugin.files) {%>
<%= key%> : <%= JSON.stringify(htmlWebpackPlugin.files[key]) %>
<% } %>
<% for (key in htmlWebpackPlugin.options) {%>
<%= key%> : <%= JSON.stringify(htmlWebpackPlugin.options[key]) %>
<% } %>
</body>
</html>
~~~
**dist下新生成的index.html**
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>This is my plugin title</title>
<script type="text/javascript" src="js/main-ce4b1548dce5dea612ac-bundle.js"></script><script type="text/javascript" src="js/another-f16463e116d027221d92-bundle.js"></script></head>
<body>
<script type="text/javascript" src="bundle.js"></script>
Mon Jul 17 2017 10:46:53 GMT+0800 (中國標準時間)
publicPath : ""
chunks : {"main":{"size":33,"entry":"js/main-ce4b1548dce5dea612ac-bundle.js","hash":"ce4b1548dce5dea612ac","css":[]},"another":{"size":45,"entry":"js/another-f16463e116d027221d92-bundle.js","hash":"f16463e116d027221d92","css":[]}}
js : ["js/main-ce4b1548dce5dea612ac-bundle.js","js/another-f16463e116d027221d92-bundle.js"]
css : []
manifest :
template : "E:\\learnFront\\webpack\\webpackDemo3\\node_modules\\html-webpack-plugin\\lib\\loader.js!E:\\learnFront\\webpack\\webpackDemo3\\index.html"
filename : "index-[hash].html"
hash : false
inject : "head"
compile : true
favicon : false
minify : {"collapseWhitespace":false,"removeComments":true}
cache : true
showErrors : true
chunks : "all"
excludeChunks : []
title : "This is my plugin title"
xhtml : false
date : "2017-07-17T02:46:53.124Z"
</body>
</html>
~~~
關注到`htmlWebpackPlugin.files.chunks.模塊名.entry`是打包生成的chunks路徑,我們可以直接在模板index引用
**修改webpack.config(修改inject)**
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
main: './src/script/main.js',
another: './src/script/another.js'
},
output:{
path: path.resolve(__dirname,'./dist'),
filename: 'js/[name]-[hash]-bundle.js'
},
plugins:[
new htmlWebpackPlugin({
template: 'index.html',
filename: 'index-[hash].html',
inject: false, //打包生成的js,css和其他東西注入的位置
title: 'This is my plugin title',
})
]
}
~~~
**修改模板index.html**
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
<script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks.main.entry %>"></script>
<script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks.another.entry %>"></script>
</head>
<body>
</body>
</html>
~~~
**dist下新生成的index.html**
意料之中,直接將生成的js插入了head標簽中。
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>This is my plugin title</title>
<script type="text/javascript" src="js/main-f2dac2790752190964a8-bundle.js"></script>
<script type="text/javascript" src="js/another-f2dac2790752190964a8-bundle.js"></script>
</head>
<body>
</body>
</html>
~~~
### 9.將打包后的html引入的js換成線上的地址
**修改webpack.config**
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
main: './src/script/main.js',
another: './src/script/another.js'
},
output:{
path: path.resolve(__dirname,'./dist'),
publicPath: 'https://cdn.example.com/',
filename: 'js/[name]-[hash]-bundle.js'
},
plugins:[
new htmlWebpackPlugin({
template: 'index.html',
filename: 'index-[hash].html',
inject: false, //打包生成的js,css和其他東西注入的位置
title: 'This is my plugin title',
})
]
}
~~~
**dist下新生成的index.html**
script中src已經改成線上地址
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>This is my plugin title</title>
<script type="text/javascript" src="https://cdn.example.com/js/main-60ab79c0b9a1c47b5eed-bundle.js"></script>
<script type="text/javascript" src="https://cdn.example.com/js/another-60ab79c0b9a1c47b5eed-bundle.js"></script>
</head>
<body>
</body>
</html>
~~~
## 生成多個頁面
### 1.新建文件目錄
在script下創建多個js文件:a、b、c.js

### 2.修改webpack.config
~~~
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './src/script/a.js',
b: './src/script/b.js',
c: './src/script/c.js',
},
output:{
path: path.resolve(__dirname,'./dist'),
filename: 'js/[name].js'
},
plugins:[
new htmlWebpackPlugin({
template: 'index.html',
filename: 'a.html',
title: 'This is a',
}),
new htmlWebpackPlugin({
template: 'index.html',
filename: 'b.html',
title: 'This is b',
}),
new htmlWebpackPlugin({
template: 'index.html',
filename: 'c.html',
title: 'This is c',
}),
]
}
~~~
**模板index.html**
~~~html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
~~~
### 3.生成的html文件
~~~html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>This is a</title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="js/c.js"></script><script type="text/javascript" src="js/b.js"></script><script type="text/javascript" src="js/a.js"></script></body>
</html>
~~~
這與我們預期在打包后的a.html只引入a.js,b.html只引入b.js,c.html只引入c.js不一樣,這個時候就要去看html-webpack-plugin里面的chunks和excludeChunks:
(1) chunks: 指定載入哪些chunk到打包生成的html頁面
(2) excludeChunks: 指定排除哪些頁面將剩下的chunks載入到打包生成的html頁面
### 4.再次修改webpack.config
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './src/script/a.js',
b: './src/script/b.js',
c: './src/script/c.js',
},
output:{
path: path.resolve(__dirname,'./dist'),
filename: 'js/[name].js'
},
plugins:[
new htmlWebpackPlugin({
template: 'index.html',
filename: 'a.html',
title: 'This is a',
chunks: ['a'] //注意是數組,或者是excludeChunks: ['b', 'c']
}),
new htmlWebpackPlugin({
template: 'index.html',
filename: 'b.html',
title: 'This is b',
chunks: ['b'] //注意是數組,或者是excludeChunks: ['a', 'c']
}),
new htmlWebpackPlugin({
template: 'index.html',
filename: 'c.html',
title: 'This is c',
chunks: ['c'] //注意是數組,或者是excludeChunks: ['a', 'b']
}),
]
}
~~~
**再次生成后的a.html**
~~~html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>This is a</title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="js/a.js"></script></body>
</html>
~~~
## 引入內聯js和外鏈js
我們都知道當html頁面引入多個js的時候就需要多次向服務器發送請求,這樣會增加帶寬消耗和時間消耗,為了解決這個問題,可以將共用的js源碼直接寫在html,不共用js再外鏈引入。
之前插件html-webpack-plugin并沒有考慮這種內聯情況,但是插件的作者給出了在webpack里面打包的[解決方法](https://github.com/jantimon/html-webpack-plugin/blob/master/examples/inline/template.jade)
### 1.新建文件目錄

### 2.修改webpack.config
~~~javascript
var path = require('path'); //webpack2.0以后,路徑需要引用這個模塊
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './src/script/a.js',
b: './src/script/b.js',
c: './src/script/c.js',
main: './src/script/main.js'
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: 'https://cdn.example.com/',
filename: 'js/[name].js'
},
plugins: [
new htmlWebpackPlugin({
template: 'index.html',
filename: 'a.html',
title: 'This is a',
inject: false,
excludeChunks: ['b', 'c']
}),
new htmlWebpackPlugin({
template: 'index.html',
filename: 'b.html',
title: 'This is b',
inject: false,
excludeChunks: ['a', 'c']
}),
new htmlWebpackPlugin({
template: 'index.html',
filename: 'c.html',
title: 'This is c',
inject: false,
excludeChunks: ['a', 'b']
})
]
}
~~~
### 3.修改模板index.html
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<script type="text/javascript">
<%= compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %> //內聯化引入js
</script>
</head>
<body>
<% for (var i in htmlWebpackPlugin.files.chunks){%>
<% if (i!=='main'){%>
<script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks[i].entry %>"></script>
<% } %>
<% } %>
</body>
</html>
~~~
### 4.成功生成的a.html
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
This is a
</title>
<script type="text/javascript">
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "https://cdn.example.com/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 3);
/******/ })
/************************************************************************/
/******/ ({
/***/ 3:
/***/ (function(module, exports) {
function main() {
alert("main");
}
/***/ })
/******/ }); //內聯化引入js
</script>
</head>
<body>
<script type="text/javascript" src="https://cdn.example.com/js/a.js"></script>
</body>
</html>
~~~
這樣,我們就把main.js內嵌到a、b、c.html中,而以外鏈的形式引用各個單獨的js