# webpack是什么

webpack 是一个JavaScript静态模块打包器,当webpack处理应用程序时会递归构建一个依赖关系图,包含程序需要的每个模块,然后将这些模块打包成一个或者多个budle

# webpack核心概念

核心

webpack 配置中需要理解的几个核心概念 :EntryOutputLoadersPluginsChunk

  • Entry:指定webpack开始构建的入口模块,从该模块开始构并计算出直接或间接依赖的模块或者库。

  • Output:告诉webpack如何命名输出文件以及输出的目录

  • Loaders:由于webpack只能处理JavaScript,所以我们需要将一些非js文件处理成webpack能够处理的模块,比如.vue、.scss等文件。

  • Pluginsplugin有着很强的能力,从打包优化和压缩,一直到重新定义环境中的变量。辅助webpack更好的按照我们指定的方式打包代码。

  • module:我们自己写的代码文件,一个文件就相当于一个模块,不管是css、js都是模块。

  • Chunk:当webpack根据我们传入的入口文件将我们写的module进行打包时,会根据文件的引用关系,生成chunk,将一个模块中用到的代码(包括引用的)都生成到一个chunk。额外打包的代码会被单独分出一个文件,实现单独加载,但是属于同一个chunkwebpack会建立内部关系。

coding split的产物,我们可以把一些代码打包成一个单独的Chunk,比如某些公共模块、组件、第三方包,更好的利用缓存。或者按需加载某些功能模块,优化加载时间。在webpack3中我们使用CommonsChunkPlugin将一些公共代码分割成一个chuak,实现单独加载。在webpack4中我们使用SplitChunksPlugin

  • bundlewebpackchunk文件处理好之后,最终会输出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.jsvendors~的前缀是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,区别如下 webpack-devtool

上次更新: 2/21/2023, 3:05:32 PM