webpack的一些基本解释
- webpack是一个打包工具:
- 什么是打包呢?
- 打包就是把源代码经过一系列处理输出为最终代码的过程,webpack官网封面就解释的很好
什么是chunk(1)
- chunk就是打包成的一个个的块
- 我们以前用jquery之类的开发的时候,我们的js,css等文件都是单独引入的,比如下面的代码
<link rel="stylesheet" href="./bootstrap.css">
<link rel="stylesheet" href="./bootstrap-datepicker.css">
<script src="./jquery.min.js"></script>
<script src="./bootstrap.min.js"></script>
然而到了今天,我们在引入资源的时候可能就不再是使用上面的这种方式引入了,我们使用es6 modules 的方式来引入资源,如main.js中下面的代码
import App from './App'
import store from './store'
import router from './router'
什么是chunk(2)
上页中的main.js中引入的三个资源文件最终打包后在html页面中是什么样子的呢?是下面这个样子吗?
<script src="./App.js"></script>
<script src="./store.js"></script>
<script src="./router.js"></script>
不是的!
最终这些资源会全部打包到一个文件中这个文件(假定最终生成的文件名字叫做bundle.js)
这个bundle.js就是一个chunk所以我们大体(其实css文件不一定是一个chunk)
可以认为打包生成的每一个文件都是一个chunk
一个项目可以有多少个chunk
一个项目中的chunk数量大约就是打包后文件的数量,然而使用es6 modules 方式引入资源的时候,这些资源默认就是打包成一个chunk,只有一个chunk
生成chunk的方式有 、
- 比较大的图片等二进制文件
- 异步引入的块,也就是import(‘’)方式引入的资源,包括异步模块,路由加载等
- Webpack优化生成的chunk,比如pollyfill提取到一个单独的chunk中
大部分资源都打包到一个chunk中有什么问题
主要问题是:
- 导致这个chunk比较大,加载比较慢
- 每次发版不能充分利用浏览器的缓存
- 多页面的时候不能充分利用浏览器缓存
如何进行chunk分割呢?
不同的人有不同的分割方式
但一般会把不常改变的大资源单独分割成一个chunk
把其他的不常改变的小资源合并分割成一个chunk
http1.1下面分割的chunk也不宜太多,因为在同一个域下面的资源并发下载的资源数量是有限的,比如chrome大约是6个资源同时下载,这6个资源中必须要有某个资源下载完毕后才会下载其他资源,但也不一定非要少于6个,因为某些资源可能直接读取内存,某些资源可以通过cdn从别的域中读取
项目中分割的代码
-
minChunks:表示同一个模块被不同引入的次数当小于等于多少的时候被分割出来
-
Name:将要分割出来的chunk的名字
-
Priority:权重,比如同样的模块在这里分割中都可以被划分到,会根据权重来决定是将模块放到哪个chunk中
-
Test:被查找的资源所在的文件夹或文件自身
-
Chunks:什么样子的资源会被分割,initial表示静态chunk中的资源被分割不包含异步引入块中的资源,all表示所有的资源都要查找分割,可能异步引入的和静态引入的块共用,async表示只有异步块中的被分割我们这个项目因为是多页面项目,根据我的实践all会导致出现chunk丢失的问题,欢迎有兴趣的同学研究看看为什么会这样
-
其他 optimization.splitChunks中还有很多
-
其他的属性可以配置,比如maxInitialRequests表示最多可以分割成多少个chunk
单页面开发和多页面开发
我们一般情况下的项目都是单页面开发,单页面开发就是对于一个项目,就只是打开一个tab页面也就是自始至终就在一个html下面操作,所有的操作都是在这一个html页面中展开的,多页面是浏览器中可以打开多个tab页面,不同的tab页面引入不同的chunk,比如我们早期的jquery项目为例子,我们某个页面中的引入first.html
first.html
<script src="./jquery.min.js"></script>
<script src="./bootstrap.min.js"></script>
<script src="./first.js"></script>
另外一个页面中的引入
Second.html
<script src="./jquery.min.js"></script>
<script src="./bootstrap.min.js"></script>
<script src="./second.js"></script>
Webpack中的单页面项目如何实现的
entry: {
app:'D:\\workspace\\hcs\\src\\main.js',
filename: '[name].[chunkhash:8].js',
},
output: {
path: 'D:\\workspace\\hcs\\dist',
},
new HtmlWebpackPlugin(
{
template: 'D:\\workspace\\hcs\\public\\index.html',
filename: 'index.html',
chunks: [ 'app' ]
}
),
Webpack多页面如何实现
entry: {
app: 'D:\\workspace\\hcs\\src\\main.js',
app2: 'D:\\workspace\\hcs\\src\\main2.js',
},
output: {
path: 'D:\\workspace\\hcs\\dist',
filename: '[name].[chunkhash:8].js',
},
new HtmlWebpackPlugin(
{
template: 'D:\\workspace\\hcs\\public\\index.html',
filename: 'index.html',
chunks: [ 'app' ]
}
),
new HtmlWebpackPlugin(
{
template: 'D:\\workspace\\hcs\\public\\index2.html',
filename: 'index2.html',
chunks: ['app2' ]
}
),
- Template:最终生成的页面文件的模板文件
- Filename:最终生成的页面文件的名称
- Chunks:有哪些chunks将要包含到页面文件中,当chunks缺省的时候,所有的静态chunk都会被包含到生成的页面中,上面的代码生成两个页面
Index.html中
<script src=“app.js” ></script>
Index2.html中
<script src=“app2.js” ></script>
Vue-cli中多页面的实现
Vue-cli对webpack进行了扩展,提供了一个叫做pages的属性,这是一个hash对象,指定了生成多页面的代码
Chunks属性指定将要在这个页面中静态包含的chunk块,倘若不设置的话,那么就包含
[
'chunk-vendors',
'chunk-common',
‘该chunk的名字'
]
其中chunk-vendors和chunk-common是固定的,实际项目中需要自己设置chunks
最终会生成webpack中多页面的配置
module.exports = {
pages: {
index: {
// page 的入口
entry: 'src/index/main.js',
// 模板来源
template: 'public/index.html',
// 在 dist/index.html 的输出
filename: 'index.html',
// 当使用 title 选项时,
// template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
title: 'Index Page',
// 在这个页面中包含的块,默认情况下会包含
// 提取出来的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-common', 'index']
}
}
}
分割块和多页面集成
这个集成就比较简单了,只需要在chunks中将我们的分割块以及当前chunk一起放到每一个pages项下面的chunks中就可以了
module.exports = {
pages: {
app: {
entry: 'src/index/main.js',
template: 'public/index.html',
filename: 'index.html',
title: 'Index Page',
chunks: [
'chunk-libs',
'chunk-elementUI',
'chunk-fabric',
'chunk-icons',
'chunk-commons',
'app'
]
}
}
}
查看vue-cli中配置项最终生成的webpack配置
在package.json中添加
"scripts": {
"inspect": "vue inspect > webpack.inspect.json",
}
执行一下 npm run inspect 那么就可以生成一个webpack.inspect.json的文件
查看最终打包的信息
webpack-bundle-analyzer这个plugin可以查看最终打包的信息
在代码中执行下面的命令就可以调用上面的这个plugin来查看最终打包的信息
npm run preview – --report