Webpack坑位之输出

栏目: 编程语言 · 发布时间: 5年前

内容简介:webpack的最后就是为了得到打包结果。那这是一个怎么样的过程,不同的配置,会有什么样的结果呢?本文的原文在我的博客中:

webpack的最后就是为了得到打包结果。

那这是一个怎么样的过程,不同的配置,会有什么样的结果呢?

本文的原文在我的博客中: github.com/RachelRen/b… ,欢迎star。

首先从最简单的配置开始 output 。告诉webpack在哪里打包应用程序。

output: {
	    path: path.resolve(__dirname, 'build'),
	    filename: 'js/[name].js',
	    publicPath: '/',
	    chunkFilename:'js/[name].chunk.js',
		//chunkFilename:'js/[name].[chunkhash:8].chunk.js',
	},

复制代码

在这里可以看到很多相似,但是有不同含义的名次,如 filenamechunkFilenamehashchunkhash ,那他们有什么区别呢?

而这里的chunk又是什么意思呢?

chunkFilename VS filename

webpack 将多个模块打包之后的代码集合称为 chunk。 这两个的区别:chunkFilename 是无入口的chunk在输出时的文件名称。chunkFilename只用于在指定在运行过程中生成的chunk在输出时的文件名称。

但在webpack4以上的时候,发现在entry中配置的入口文件,打包的结果是 index.chunckfile.js ,属于chunkFilename,因为设置了

optimization: {
    splitChunks: {
      	chunks: 'all',
     	name: 'common',
    },
    runtimeChunk: { 
     	name: 'runtime',
    }
},
复制代码

当去掉 runtimeChunk 这个配置时,那么入口文件,又会变成filename。主要原因是

通过设置 optimization.splitChunks.chunks: "all" 来启动默认的代码分割配置项。通过满足下面的条件,webpack会自动打包chunks

  • 当前模块是公共模块(多处引用)或者模块来自 node_modules
  • 当前模块大小大于 30kb
  • 如果此模块是按需加载,并行请求的最大数量小于等于 5
  • 如果此模块在初始页面加载,并行请求的最大数量小于等于 3

optimization.runtimeChunk

通过设置 optimization.runtimeChunk: true 来为每一个入口默认添加一个只包含 runtime 的 chunk(webpack会添加一个只包含运行时(runtime)额外代码块到每一个入口)。

chunkhash VS hash

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

[chunkhash] is replaced by the hash of the chunk.

chunkhash 代表的是chunk的hash值。chunk在webpack中的就是模块的意思,那么chunkhash就是根据模块内容计算得出的hash值。

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指纹,不会影响其他文件

hash的应用场景

接上文所述,webpack的hash字段是根据每次编译compilation的内容计算所得,也可以理解为项目总体文件的hash值,而不是针对每个具体文件的。

所以如果用 optimization.splitChunks.runtimeChunk 生成的文件,就是以hash作为文件后缀的 runtime.[hash].js ,而且每次文件修改,都会生成一个新的文件。

hash是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的hash值都会更改,并且全部文件都共用相同的hash值

总之一句话: hash是整体的文件计算所得,chunkhash是具体模块文件所得。

代码分离

现在很多系统都是SPA,当发展越来越庞大的时候,js的拆分就越来越重要的。那么怎么拆分js就很重要了。

分离主要有三种方式:

  1. 入口起点:使用 entry 配置手动地分离代码。
  2. 防止重复:使用 SplitChunksPlugin 去重和分离 chunk。
  3. 动态导入:通过模块中的内联函数调用来分离代码。

入口起点

这种方式是最简单,最直观的方式。但是有一些他的缺点:

  1. 如果入口 chunk 之间包含一些重复的模块,那些重复模块都会被引入到各个 bundle 中。
  2. 这种方法不够灵活,并且不能动态地将核心应用程序逻辑中的代码拆分出来。

防止重复

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种方式来拆分代码。

  1. 符合 ECMAScript 提案 的 import() 语法 来实现动态导入。(import() 调用会在内部用到 promises。)
  2. 则是 webpack 的遗留功能,使用 webpack 特定的 require.ensure

Public Path vs Path

在配置过程中,也会遇到这两个概念。

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]')

复制代码

Webpack中hash与chunkhash的区别,以及js与css的hash指纹解耦方案

脑阔疼的webpack按需加载

代码分离


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Agile Web Application Development with Yii 1.1 and PHP5

Agile Web Application Development with Yii 1.1 and PHP5

Jeffrey Winesett / Packt Publishing / 2010-08-27

In order to understand the framework in the context of a real-world application, we need to build something that will more closely resemble the types of applications web developers actually have to bu......一起来看看 《Agile Web Application Development with Yii 1.1 and PHP5》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具