# webpack是什么
webpack
是一个JavaScript
静态模块打包器,当webpack
处理应用程序时会递归构建一个依赖关系图,包含程序需要的每个模块,然后将这些模块打包成一个或者多个budle
# webpack核心概念
核心
webpack
配置中需要理解的几个核心概念 :Entry
,Output
,Loaders
,Plugins
,Chunk
Entry
:指定webpack
开始构建的入口模块,从该模块开始构并计算出直接或间接依赖的模块或者库。Output
:告诉webpack
如何命名输出文件以及输出的目录Loaders
:由于webpack
只能处理JavaScript
,所以我们需要将一些非js
文件处理成webpack
能够处理的模块,比如.vue、.scss
等文件。Plugins
:plugin
有着很强的能力,从打包优化和压缩,一直到重新定义环境中的变量。辅助webpack
更好的按照我们指定的方式打包代码。module
:我们自己写的代码文件,一个文件就相当于一个模块,不管是css、js都是模块。Chunk
:当webpack
根据我们传入的入口文件将我们写的module
进行打包时,会根据文件的引用关系,生成chunk
,将一个模块中用到的代码(包括引用的)都生成到一个chunk
。额外打包的代码会被单独分出一个文件,实现单独加载,但是属于同一个chunk
,webpack
会建立内部关系。
coding split
的产物,我们可以把一些代码打包成一个单独的Chunk
,比如某些公共模块、组件、第三方包,更好的利用缓存。或者按需加载某些功能模块,优化加载时间。在webpack3
中我们使用CommonsChunkPlugin
将一些公共代码分割成一个chuak
,实现单独加载。在webpack4中我们使用SplitChunksPlugin
bundle
:webpack
将chunk
文件处理好之后,最终会输出bundle
文件,bundle
文件包含了经过压缩和编译的最终代码文件,可以直接在浏览器中运行。
一般来说一个chunk
对应一个bundle
,但是一个chunk
也可以对应多个bundle
,比如对于同一个chunk
的需要额外抽离的css
文件
# filename 和 chunkFilename、webpackChunkName
# filename
filename
filename
就是打包出来的文件的名称,一般在output
对象中会用到,在MiniCssExtractPlugin
额外提取CSS插件中也会用到,output.filename
的输出文件名是[name].min.js
,[name]
代表入口名称。
# chunkFilename
chunkFilename
chunkFilename
指的是不在entry
中,却需要额外被打包出来的文件的名称,一般是需要懒加载的模块,比如loadsh
文件。当output.chunkFilename
没有被指定时,默认就会把chunk文件的id号当成前缀,比如1.min.js
。
# webpackChunkName
webpackChunkName
对于多个需要异步加载的文件,如果写成[name].bundle.js
,就会打包出1.bundle.js
这种辨识度不高的文件名称,区分起来十分困难,这时候就可以用webpackChunkName
注释 来标识异步加载的文件名:在import导入的时候,以注释的方式为引入的文件起别名,比如await import(/* webpackChunkName: "lodash" */ 'lodash')
,这样打包出来的就是vendors~lodash.bundle.js
,vendors~
的前缀是webpack
的懒加载插件SplitChunksPlugin
里的默认配置增加的。
webpackChunkName
就是为预加载的文件取别名
# webpackPrefetch、webpackPreload
# webpackPrefetch
webpackPrefetch
预获取配置。对于懒加载的文件,只有我们需要的时候才会引入,比如点击按钮加载loadsh
,只有点击的时候才会才会加载lodash
:懒加载时,会动态创建一个script
标签,被添加到head
头里加载资源。如果我们在import
的时候添加webpackPrefetch
注释,会将需要预获取的文件在请求中优先级变为Lowest
,不会等到点击按钮的时候再加载文件,而会在父chunk
文件加载完成后,空闲时加载lodash
文件。
<link rel="prefetch" as="script" href="vendors-loadsh.bundle.js">
# webpackPreload
webpackPreload
需要在webpack
中使用preload-webpack-plugin
插件,并在需要预先加载的添加/* webpackPreload: true */
来实现预加载配置。加了webpackPreload
注释的chunk
会在父chunk
加载时,以并行的方式加载,将需要预加载的文件在请求中优先级提升到High
。原理是利用link
标签也能加载js
的原理,并增加preload
属性,来实现的预加载。
<link rel="preload" as="script" href="title.js">
# hash、chunkhash、contenthash
TIP
哈希一般都是配合CDN
缓存来使用的。如果文件内容改变了,那么文件的哈希值也会改变,对应的HTML
引用的URL
地址也会改变,用户请求时,CDN
服务器发现文件哈希更新了,会从源服务器上拉取对应的数据,更新本地缓存
# hash
hash
hash
的计算是跟项目的构建相关的,项目每次构建都会生成一个新的构建hash
值,输出的文件名中如果带有hash
值[name].[hash].js
,打包出的文件就会带上项目构建生成的hash
,比如index.def5949da1857d01b87e.js
。
# chunkhash
chunkhash
如果都以hash
来命名,那么每次打包,都会生成新的hash
,这样所有资源的名字都会变,对于内容没有改变的文件,就失去了CDN
缓存的作用。chunkhash
就解决了这个问题,根据不同的入口文件进行依赖解析、构建对应的chunk
,生成不同的chunkhash
。当有文件改变时,只有属于同一个chunk
的文件名称才会改变。
# contenthash
contenthash
使用chunkhash
时,其中有一个文件改变了,会生成新的chunkhash
,那么属于同一个chunk
的其他文件的名称也会变,但是其他文件并没有发生变化,这样也会浪费CDN
缓存。contenthash
就是解决这个问题的,contenthash
是根据文件内容生成的唯一hash
值,当文件内容不改变时,contenthash
不会改变。一般额外提取出来的css
会使用contenthash
作为名称。
# sourse-map的应用
sourse-map
sourse-map
,就是一份源码和转换后代码的映射文件。
devtool
常用值:
- 1、
source-map
:大而全,啥都有,webpack
构建时间变长,看情况使用。 - 2、
cheap-sourse-map
:cheap
,就是廉价的意思,只会映射到行,没有列的映射,而且是转换过的代码。响应的体积会小很多。 - 3、
cheap-module-eval-source-map
:开发环境可使用,在构建速度报错提醒上做了比较好的均衡。 - 4、
cheap-module-source-map
:线上环境一般是不配置source-map
的,如果想要捕捉线上的代码报错,可以用这个。
开发环境一般使用cheap-module-eval-source-map
或者cheap-sourse-map
,区别如下