资讯专栏INFORMATION COLUMN

Webpack坑位之输出

miqt / 2677人阅读

摘要:之输出的最后就是为了得到打包结果。在这里可以看到很多相似,但是有不同含义的名次,如和,和,那他们有什么区别呢而这里的又是什么意思呢将多个模块打包之后的代码集合称为。在这样打包的话,会报错。所以就想搞明白这两个的区别到底是什么。

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就很重要了。

分离主要有三种方式:

    入口起点:使用 entry 配置手动地分离代码。

    防止重复:使用 SplitChunksPlugin 去重和分离 chunk。

    动态导入:通过模块中的内联函数调用来分离代码。

入口起点

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

    如果入口 chunk 之间包含一些重复的模块,那些重复模块都会被引入到各个 bundle 中。

    这种方法不够灵活,并且不能动态地将核心应用程序逻辑中的代码拆分出来。

防止重复

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

    符合 ECMAScript 提案 的 import() 语法 来实现动态导入。(import() 调用会在内部用到 promises。)

    则是 webpack 的遗留功能,使用 webpack 特定的 require.ensure

Public Path vs Path

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

publicPath: 用来为项目中的所有资源指定一个基础路径。使用的是相对路径。

filename:"[name]_[chunkhash:8].js"
publicPath: "https://cdn.example.com/assets/"

那么发布上线的时候,路径就是:


静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径

path: 配置输出文件存放在本地的目录,必须是 string 类型的绝对路径,通常通过 Node.js 的 path 模块去获取绝对路径:

path: path.resolve(__dirname, "dist_[hash]")

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

脑阔疼的webpack按需加载

代码分离

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/6863.html

相关文章

  • Webpack坑位整理

    摘要:在寻找相对路径的文件时会以为根目录,默认为执行启动时所在的当前目录。在文件被添加到依赖图中时,将其转换称为了模块。配置中的两个目标。仅限高级用途,默认情况下自动生成生成文件的文件名。webpack webpack现在是主要的打包工具了,现在网络上也有很多资料可以学习了。这里主要整理了一些基础概念,但没有所有的写,只是把之前遇到的问题记录了一下。 本文的原文在我的博客中:github.com...

    lidashuang 评论0 收藏0
  • 关于weex

    摘要:在最上面的,阿里一般称之为文件,通过转换成,再部署到服务器,这样服务端就完成了。例如,通过安装了业界的工具库用上和如今前端的开发,一般离不开预处理器,比如和。在默认的文件中,即使有的助力,这类预处理器也是对其无能为力的。 生命周期 module.exports = { data: {}, methods: {}, init: function () { ...

    chadLi 评论0 收藏0
  • vue-cli + webpack 多页面实例配置优化方法

    摘要:在谷歌找多页面,实例还是比较少,功夫不负有心人,在那找到了,具体可以到这个,非常感谢童鞋,今天要讲的内容是基于童鞋的多页面实例上再优化的。有需要一起交流的可以加我的微信,,记得备注技术交流哈。 vue+webpack是否有多页面 目前使用vue来做项目,估计大部分都是单页面(SPA)应用,一个轻型的 MVVM 框架,谁用了MVVM框架,就再也回不去JQ时代了,哈哈。 在手机端的项目,使...

    Taste 评论0 收藏0
  • 在没有DOM操作的日子里,我是怎么熬过来的(中)

    摘要:于是,闰土顺应呼声,在这个凛冽的寒冬早晨,将中篇热文滚烫呈上。本系列文章还没有结束,下篇,也可能是终结篇,即将来袭作者闰土少年链接来源掘金著作权归作者所有。 showImg(https://segmentfault.com/img/bVZsm6?w=669&h=445); 前言 继上篇推送之后,在掘金、segmentfault、简书、博客园等平台上迅速收到了不俗的反馈,大部分网友都留言...

    CoXie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<