Webpack 5号

2020-10-11 16:30:40

《webpack 4》于2018年2月上映。从那时起,我们在没有破坏更改的情况下发布了许多功能。我们知道,人们不喜欢有突破性变化的重大变化。尤其是webpack,人们通常一年只摸两次,剩下的时间就行了。但是,在不破坏更改的情况下交付功能也是有代价的:我们不能对API或架构进行重大改进。

因此,有时会有困难堆积起来的时候,我们被迫做出破坏性的改变,以避免把一切搞得一团糟。这是一个新的主要版本的时候了。因此,webpack 5包含了这些架构改进以及没有它们就不可能实现的特性。

主要版本还提供了修改一些默认设置并与同时出现的建议和规范保持一致的机会。

所以今天(2020年10月10日)“webpack 5.0.0”发布了,但这并不意味着它已经完成,没有漏洞,甚至功能齐全。就像webpack 4一样,我们通过修复问题和增加功能来继续开发。在接下来的几天里,可能会有很多错误修复。功能将在稍后介绍。

这意味着我们已经完成了突破性的改变。已经进行了许多重构,以提升体系结构级别,并为将来的功能(和当前功能)创建良好的基础。

那得看情况。升级失败的可能性很大,您需要进行第二次或第三次尝试。如果你对此持开放态度,现在就试着升级,并向webpack、插件和加载器提供反馈。我们急于解决这些问题。总得有人开始,你将是第一批从中受益的人之一。

Webpack完全立足于赞助。它不像其他一些开源项目那样与大公司捆绑在一起(并由大公司支付费用)。99%的赞助收益根据贡献者和维护者的贡献分配给他们。我们相信应该把这笔钱用来让webpack变得更好。

但现在流行起来了,公司不再那么愿意赞助了。Webpack也在这种情况下苦不堪言(和许多其他公司和个人一样)。

我们从来没有能力支付给我们的捐赠者我们认为他们应该得到的金额,但现在我们只有一半的钱可用,所以我们需要更认真地削减。在情况好转之前,我们只会在每个月的前10天付钱给贡献者和维护者。剩下的日子,他们可以自愿工作,由雇主支付工资,做其他事情,或者休息几天。这使得我们可以在前10天为他们的工作支付更多的费用,相当于投入的时间。

最大的一笔奖金给了Trivago,它在过去的三年里一直在为webpack提供巨额资助。遗憾的是,他们今年无法继续赞助,因为他们受到了新冠肺炎的沉重打击。我希望有其他公司挺身而出,追随这些(巨大的)脚步。

在不引入任何破坏性更改的情况下实现v4中的功能时,清理处于奇怪状态的内部结构。

现在引入突破性的更改,让我们尽可能长时间地使用v5,从而为未来的功能做好准备。

以下是v4中已删除但没有弃用警告的一些内容:

现在只能向IgnorePlugin和BannerPlugin传递一个参数,该参数可以是对象、字符串或函数。

在早期,webpack的目标是允许在浏览器中运行大多数Node.js模块,但模块环境发生了变化,许多模块的使用现在主要是为了前端目的而编写的。Webpack<;=4为许多Node.js核心模块提供了多个填充,一旦模块使用了任何核心模块(即加密模块),就会自动应用这些填充。

虽然这使得使用为Node.js编写的模块变得很容易,但它将这些巨大的多边形填充添加到包中。在许多情况下,这些多层填充是不必要的。

Webpack 5停止自动填充这些核心模块,专注于前端兼容模块。我们的目标是改善与Web平台的兼容性,在Web平台上Node.js核心模块不可用。

可以手动为Node.js核心模块添加多边形填充。一条错误消息将给出如何实现该目标的提示。

包作者:使用Package.json中的Browser字段使包与前端兼容。提供浏览器的替代实现/依赖项。

添加了用于长期缓存的新算法。默认情况下,在生产模式下会启用这些功能。

算法以确定性的方式为模块和区块分配短(3位或5位)数字ID,并为导出分配短(2个字符)名称。这是包大小和长期缓存之间的权衡。

ModeIds/chunkIds/mangleExports:false禁用默认行为,用户可以通过插件提供自定义算法。请注意,在webpack 4中,没有自定义插件的模块ID/chunkIds:false会导致构建正常,而在webpack 5中,您必须提供自定义插件。

迁移:最好使用chunkIds、modeIds和mangleExports的默认值。您还可以选择加入旧的默认数据块Ids:";size";,modeIds:";size";,mangleExports:";size";,这将生成较小的捆绑包,但会更频繁地使它们失效以进行缓存。

注意:在webpack中,4个散列模块ID会降低gzip性能。这与更改模块顺序有关,已修复。

Webpack 5现在使用[contenthash]时将使用文件内容的真实哈希。在它之前,只有";使用了内部结构的散列。当仅更改注释或重命名变量时,这可能会对长期缓存产生积极影响。最小化后,这些更改不可见。

在开发模式中默认启用的新命名块id算法会给出块(和文件名)人类可读的名称。模块ID由其相对于上下文的路径确定。区块ID由区块的内容确定。

因此,您不再需要使用import(/*webpack ChunkName:";name";*/";module";)进行调试。但是,如果您想要控制生产环境的文件名,这仍然是有意义的。

可以在生产中使用名为chunkIds:";的chunkIds:,但请确保不会意外暴露有关模块名称的敏感信息。

迁移:如果您不喜欢在开发过程中更改文件名,您可以传递chunkIds:";Natural";来使用旧的数字模式。

Webpack 5增加了一个名为“模块联盟”的新功能,它允许多个webpack版本协同工作。从运行时的角度来看,来自多个构建的模块将表现为一个巨大的连接模块图。从开发人员的角度来看,可以从指定的远程构建导入模块,并以最低限度的限制使用这些模块。

JSON模块现在与建议保持一致,并在使用非默认导出时发出警告。从严格的ECMAScript模块导入时,JSON模块不再具有命名导出。

即使在使用默认导出时,未使用的属性也会被Optimization.usedExports优化删除,而属性会被Optimization.mangleExports优化破坏。

可以在Rule.parser.parse中指定自定义JSON解析器来导入类似JSON的文件(例如,用于toml、yaml、json5等)。

Port.meta.url是当前文件的file:url(类似于__filename,但作为文件url)。

Webpack 5现在原生支持表示资产的模块。这些模块将发出一个文件到输出文件夹中,或者将一个DataURI注入到javascript包中。无论哪种方式,他们都会给出一个要使用的URL。

匹配导入时,从";./image.png";导入url,并在module e.ules中设置类型:";ASSET";。(老办法)。

选择新的方式语法也是为了允许在没有绑定器的情况下运行代码。此语法在浏览器的本机ECMAScript模块中也可用。

在将资产的新URL与新Worker/new SharedWorker/Navigator.serviceWorker.register组合时,webpack将自动为Web Worker创建一个新的入口点。

语法的选择也是为了允许在没有绑定器的情况下运行代码。此语法在浏览器的本机ECMAScript模块中也可用。

数据:支持。支持base64或RAW编码。Mimetype可以映射到mode.ules中的加载器和模块类型。示例:从";data:text/javascript导入x,导出默认值42";

HTTP(S):受支持,但需要通过新的webpack选择加入。实验。schemesHttp(S)UriPlugin()默认情况下,当目标为";web";时,这些URI会导致对外部资源的请求(它们是外部的)。

Webpack 5支持所谓的异步模块。它们是不同步求值的模块,而是异步的、基于承诺的模块。

通过IMPORT导入它们是自动处理的,不需要额外的语法,差异几乎不明显。

承诺:计算结果为承诺的表达式。外部模块是异步模块,解析值用作模块导出。

Import:Native import()用于加载指定的请求。外部模块是异步模块。

Script:通过<;script>;标记加载URL,并从全局变量(以及可选的属性)获取导出。外部模块是异步模块。

Webpack 5允许传递目标列表,还支持TARGET的版本。

这是一种简单的方式,可以为webpack提供其确定所需的所有信息:

Stats测试格式在可读性和冗余性方面得到了改进。默认设置已改进为不那么冗长,也适用于大型构建。

统计信息现在默认隐藏模块和区块ID。这可以使用stats.id进行切换。

所有模块的列表现在按到入口点的距离排序。这可以使用stats.module esSort进行更改。

块模块列表现在按模块名称排序。这可以使用stats.chunkModulesSort进行更改。

现在,串联模块中的嵌套模块列表按拓扑排序。这可以使用stats.nestedModulesSort进行更改。

现在,一般信息显示在结尾处的摘要中。显示webpack版本、配置名称和警告/错误计数。

默认情况下不再显示构建的时间戳。这可以通过stats.builtAt启用。它将在摘要中显示时间戳。

对ProgressPlugin做了一些改进,它由CLI用于--Progress,但也可以手动用作插件。

它过去只统计处理过的模块。现在,它可以对条目、依赖项和模块进行计数。它们现在都是默认显示的。

用于显示当前处理的模块。这会导致大量stderr输出,并在某些控制台上产生性能问题。现在,这在默认情况下处于禁用状态(activeModules选项)。这还可以减少控制台上的垃圾邮件数量。现在,在构建模块期间写入stderr的时间限制为500ms。

分析模式也进行了升级,将显示嵌套进度消息的计时。这使得更容易找出插件何时会导致性能问题。

为了使进度百分比更准确,ProgressPlugin缓存上一次已知的模块总数,并在下一次构建时重用此值。第一个构建将预热缓存,但随后的构建将使用并更新此值。

在webpack 4中,多个webpack运行时可能会在同一个HTML页上发生冲突,因为它们使用相同的全局变量加载块。要解决此问题,需要为output.jsonpFunction配置提供自定义名称。

Webpack 5不会自动从Package.json名称中推断构建的惟一名称,并将其用作output.Unique eName的缺省名称。

Webpack 5从源代码生成打字脚本类型,并通过npm包公开它们。

Webpack现在能够跟踪对导出嵌套属性的访问。这可以改善重新导出名称空间对象时的树抖动(未使用的导出消除和导出损坏)。

//inner.js export const a=1;导出const b=2;//module e.js export*as Internal从';。/INNER';;//或从';导入*AS INTERNAL。/INNER';EXPORT{INNER};//user.js import*AS MODULE从';./module';console。Log(模块.inter.a);

Webpack 4没有分析模块出口和进口之间的依赖关系。Webpack 5有一个新的选项Optimization.innerGraph,该选项在生产模式下默认启用,它对模块中的符号运行分析,以找出从导出到导入的依赖关系。

从';导入{Something}。/Something';;函数使用Something(){return Something;}导出函数test(){return usingSomething();}。

内部图形算法将计算出只有在使用测试导出时才会使用某些内容。这允许将更多导出标记为未使用,并从捆绑包中省略更多代码。

当设置了";副作用";:false时,这允许省略更多的模块。在此示例中,./在未使用测试导出时将被省略。

要获取有关未使用的导出的信息,需要优化.unusedExports。要删除无副作用的模块,需要优化.side Effects。

反馈:如果您发现此分析中缺少某些内容,请报告问题,我们会考虑添加。

使用eval()可以解除模块的这种优化,因为valed代码可以引用作用域中的任何符号。

Webpack 5添加了对一些CommonJs构造的支持,允许删除未使用的CommonJs导出,并跟踪Required()调用中引用的导出名称。

当检测到不可分析的代码时,webpack会退出,并且根本不跟踪这些模块的导出信息(出于性能原因)。

Package.json中的";副作用";标志允许手动将模块标记为无副作用,这允许在不使用时将其删除。

根据对源代码的静态分析,webpack 5还可以自动将模块标记为无副作用。

Webpack 5现在能够(并且在默认情况下)分析和优化每个运行时的模块(一个运行时通常等于一个入口点)。这只允许在真正需要它们的这些入口点进行出口。入口点不会相互影响(只要每个入口点都使用运行时)。

模块串联已成为一等公民,现在允许任何模块和依赖项实现它。最初,webpack 5已经添加了对ExternalModules和JSON模块的支持,更多的可能很快就会发布。

Export*已改进,可以跟踪更多信息,并且不再将默认导出标记为已使用。

当webpack确定有冲突的出口时,EXPORT*现在会显示警告。

Import()允许通过/*webpackage Exports:[";ABC";,";default";]*/Magic Comment手动摇动模块。

我们试图通过提高两种模式之间的相似性,在开发模式下的构建性能和避免仅生产问题之间找到一个好的折衷。

Webpack 5在两种模式下都默认开启副作用优化。在webpack 4中,由于Package.json中的一个不正确的副作用标志,此优化会导致一些仅限生产的错误。在开发中启用此优化可以更快、更容易地找到这些问题。

在许多情况下,开发和生产发生在不同的操作系统上,文件系统对大小写的敏感度不同,所以webpack 5在出现奇怪的大小写问题时添加了更多的警告/错误。

Webpack检测何时发生ASI,并在没有插入分号时生成较短的代码。对象(...)->;(0,...)。

Webpack将多个导出getter合并为一个运行时函数调用:R.d(x,";a";,()=>;a);R.d(x,";b";,()=>;b);->;R.d(x,{a:()=>;a,b:()=>;b});

现在,output.Environment中有其他选项。它们允许指定哪个ECMAScript特性可以用于webpack生成的运行时代码。

通常不直接指定此选项,而是使用目标选项。

Webpack 4以前只发出es5代码。Webpack 5现在可以生成es5和es6/es2015代码。

只支持现代浏览器将使用箭头函数生成更短的代码,并使用常量声明和TDZ作为导出默认值生成更符合规范的代码。

在“webpack 4”中,目标是在网络和节点(以及其他几个)之间进行粗略的选择。Webpack 5在这里给了你更多的选择。

对于其中一些内容,在web和节点之间进行选择太粗糙了,我们需要更多信息。因此,我们允许指定最低版本,例如,类似于节点10.13和#34;,并推断关于目标环境的更多属性。

现在还允许将多个目标与一个数组组合,webpack将确定所有目标的最低属性。使用不提供完整信息的目标(如";web&34;或";node";(没有版本号))时,使用数组也很有用。例如,[#34;web&34;,";es2020&34;]结合了这两个部分目标。

有一个目标Browserslist&34;它将使用Browserslist数据来确定环境的属性。当项目中有可用的Browserslist配置时,默认情况下也会使用此目标。如果没有此类配置可用,默认情况下将使用网络目标。

某些组合和功能尚未实现,将导致错误。它们是为未来的功能做准备。例如:

[";web";,";node";]将导致通用的区块加载方法,该方法尚未实现

[";web";,";node";]+output.module:true将导致模块块加载方法,目前尚未实现。

";web";将导致http(S):导入被视为模块外部变量,但尚未实现(解决方法:outalsPresets:{web:false,webAsync:true},它将改用import())。

模块现在以比单个数字更好的方式表示大小。现在有不同类型的尺码。

SplitChunksPlugin现在知道如何处理这些不同的大小,并将它们用于minSize和maxSize。默认情况下,仅处理javascript大小,但您现在可以传递多个值来管理它们:

模块.exports={优化:{拆分块:{最小大小:{javascript:30000,WebAssembly:50000,};

您仍然可以对大小使用单个数字。在这种情况下,webpack将自动使用默认尺寸类型。

Mini-css-Extract-plugin使用CSS/mini-Extra作为大小类型,并自动将此大小类型添加到默认类型。

现在有了文件系统缓存。它可以选择加入,并可以通过以下配置启用:

模块.exports={cache:{//1.将缓存类型设置为文件系统类型:';filesystem';,buildDependency:{//2.将您的配置添加为buildDependency以获取配置更改配置的缓存失效:[__filename]//3.如果构建依赖于其他内容,可以将它们添加到此处//请注意,会自动添加webpack、加载器和配置中引用的所有模块};

默认情况下,webpack假设webpack所在的NODE_MODULES目录仅由包管理器修改。将跳过NODE_MODULES的散列和时间戳。相反,出于性能原因,仅使用包名和版本。符号链接(即NPM/纱线链接)只要长解析就可以。symlink:没有指定false(无论如何都要避免)。除非您选择使用快照退出此优化,否则请勿直接编辑node_module中的文件。

.