## 简单的文件打包
### 1.创建文件目录
![](https://box.kancloud.cn/1da4277b3dc6fef179d2782dbd8c45e7_207x259.png)
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命令打包
![](https://box.kancloud.cn/d2d3ab5f2f9ec531f22a09b28ff53806_417x131.png)
如入口与输出一节类似,我们会看到dist下面多了个js文件夹,并且js文件夹里面多了个bundle.js,:
![](https://box.kancloud.cn/f32470d1be9a146d16a794f4e2d32e1c_195x287.png)
**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'
}
}
~~~
![](https://box.kancloud.cn/607b0bc9667f51d0958f9d9861df5153_617x152.png)
**新的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'
}
}
~~~
这个时候会出现报错:
![](https://box.kancloud.cn/bf6b7638fb87ab95fa7a5a1edc5b7ce6_504x201.png)
因为两个文件分开输出到各自的打包文件,但是我们输出出口都是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)来确保每个文件具有唯一的名称。
重新打包生成
![](https://box.kancloud.cn/6d0f04115a7ed8cb3b61cdf3e50d93f9_635x149.png)
在dist/js下生成了两个js文件
![](https://box.kancloud.cn/ae72fdc4e509bfa05132456b2fcc2932_352x308.png)
**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.打包生成
![](https://box.kancloud.cn/3a00c3ff97a5877ff5f261f89ec36d84_654x223.png)
发现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>
~~~
**再次打包生成**
![](https://box.kancloud.cn/80815c10163fff2d4d8e079a3e1f8bd0_750x237.png)
**新生成的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'
})
]
}
~~~
![](https://box.kancloud.cn/eaf61ffc63ec21f83142db0127fda568_739x245.png)
**新的文件目录**
![](https://box.kancloud.cn/f1fca94cfe28b4e05f61b06a2f0e3050_205x140.png)
### 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
![](https://box.kancloud.cn/f08695bff28e05eb5fe2eea819acb26b_208x267.png)
### 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.新建文件目录
![](https://box.kancloud.cn/02da85a29054d1ace43e1dc4ce93a237_215x285.png)
### 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