webpack的最后就是为了获得打包结果。css
那这是一个怎么样的过程,不一样的配置,会有什么样的结果呢?html
本文的原文在个人博客中:github.com/RachelRen/b…,欢迎star。node
首先从最简单的配置开始output
。告诉webpack在哪里打包应用程序。webpack
output: {
path: path.resolve(__dirname, 'build'),
filename: 'js/[name].js',
publicPath: '/',
chunkFilename:'js/[name].chunk.js',
//chunkFilename:'js/[name].[chunkhash:8].chunk.js',
},
复制代码
在这里能够看到不少类似,可是有不一样含义的名次,如filename
和chunkFilename
,hash
和chunkhash
,那他们有什么区别呢?git
而这里的chunk又是什么意思呢?github
webpack 将多个模块打包以后的代码集合称为 chunk。 这两个的区别:chunkFilename 是无入口的chunk在输出时的文件名称。chunkFilename只用于在指定在运行过程当中生成的chunk在输出时的文件名称。web
但在webpack4以上的时候,发如今entry中配置的入口文件,打包的结果是index.chunckfile.js
,属于chunkFilename,由于设置了promise
optimization: {
splitChunks: {
chunks: 'all',
name: 'common',
},
runtimeChunk: {
name: 'runtime',
}
},
复制代码
当去掉runtimeChunk
这个配置时,那么入口文件,又会变成filename。主要缘由是bash
经过设置 optimization.splitChunks.chunks: "all" 来启动默认的代码分割配置项。经过知足下面的条件,webpack会自动打包chunkside
optimization.runtimeChunk
经过设置 optimization.runtimeChunk: true 来为每个入口默认添加一个只包含 runtime 的 chunk(webpack会添加一个只包含运行时(runtime)额外代码块到每个入口)。
output: {
filename: 'js/[name].[chunkhash:8].js',
path: path.join(__dirname, './build'),
publicPath: '/',
chunkFilename:'js/[name].[chunkhash:8].chunk.js',
},
复制代码
在webpack 4这样打包的话,会报错。
ERROR in chunk runtime [entry]
js/[name].[chunkhash:8].js
Cannot use [chunkhash] or [contenthash] for chunk in 'js/[name].[chunkhash:8].js' (use [hash] instead)
复制代码
因此就想搞明白这两个的区别究竟是什么。
[chunkhash] is replaced by the hash of the chunk.
chunkhash
表明的是chunk的hash值。chunk在webpack中的就是模块的意思,那么chunkhash就是根据模块内容计算得出的hash值。
[hash] is replaced by the hash of the compilation.
hash 是compilation的hash值。
compilation对象表明某个版本的资源对应的编译进程。在使用webpack的development中间件时,每次检测到项目文件有变更时会建立一个compilation,因此可以针对改动生成全新的编译文件。compilation对象包含当前模块资源,编译文件,有改动的文件盒监听依赖的全部信息。
compiler和compilation的区别是。 compiler是配置完备的webpack环境。compiler只在webpack启动时构建一次,由webpack组合全部的配置构建生成。compiler是不变的webpack环境,是针对webpack的。而compilation是针对随时可变的项目文件,只要有文件改动,compilation就会被从新建立。
compilation在项目中任何一个文件改动后就会被从新建立,而后webpack计算新的compilation的hash值,这个hash值即是hash。
hash是compilation对象(所用compilation对象?)计算所得,而不是具体的项目文件计算所得。因此以上配置的编译输出文件,全部的文件名都会使用相同的hash指纹。
chunkhash是根据具体模块文件的内容计算所得的hash值,因此某个文件的改动只会影响它自己的hash指纹,不会影响其余文件
接上文所述,webpack的hash字段是根据每次编译compilation的内容计算所得,也能够理解为项目整体文件的hash值,而不是针对每一个具体文件的。
因此若是用optimization.splitChunks.runtimeChunk
生成的文件,就是以hash做为文件后缀的runtime.[hash].js
,并且每次文件修改,都会生成一个新的文件。
hash是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的hash值都会更改,而且所有文件都共用相同的hash值
总之一句话: hash是总体的文件计算所得,chunkhash是具体模块文件所得。
如今不少系统都是SPA,当发展愈来愈庞大的时候,js的拆分就愈来愈重要的。那么怎么拆分js就很重要了。
分离主要有三种方式:
这种方式是最简单,最直观的方式。可是有一些他的缺点:
SplitChunksPlugin
插件能够将公共的依赖模块提取到已有的 entry chunk 中,或者提取到一个新生成的 chunk。在webpack 4.0 以前是用CommonsChunkPlugin
来作代码分离的
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
})
]
复制代码
在webpack 4.0以后,就经过optimization.splitChunks
来分离代码了。
optimization: {
splitChunks: {
chunks: 'all'
}
}
复制代码
若是系统很庞大,将代码一次性载入,就显得太过于强大,最好能作到根据咱们的需求来选择性地加载咱们须要的代码。
webpack 提供了2种方式来拆分代码。
在配置过程当中,也会遇到这两个概念。
publicPath
: 用来为项目中的全部资源指定一个基础路径。使用的是相对路径。
filename:'[name]_[chunkhash:8].js'
publicPath: 'https://cdn.example.com/assets/'
复制代码
那么发布上线的时候,路径就是:
<script src='https://cdn.example.com/assets/a_12345678.js'></script>
复制代码
静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径
path
: 配置输出文件存放在本地的目录,必须是 string 类型的绝对路径,一般经过 Node.js 的 path 模块去获取绝对路径:
path: path.resolve(__dirname, 'dist_[hash]')
复制代码