Webpack5更新指南

Webpack5更新指南

2020-10-10 Webpack5 正式 realease 相较于 Webpack4 已经过了两年多了.在这期间并没有什么重大的改变,因为同学们并不喜欢重大的改变尤其是像 Webpack 这种你一年可能就用两次. 但由于没有去做一些重大的改变,我们不能去做一些重要的 api 和
架构上的改变来提升效率,所以 Webpack5 出现了.

传送门

这次主要在这几点上:

  • Improve build performance with Persistent Caching (通过使用持久性缓存来提高构建性能)
  • Improve Long Term Caching with better algorithms and defaults.(通过算法和默认设置来提升长期缓存)
  • Improve bundle size with better Tree Shaking and Code Generation.(通过更好的 Tree Shaking 和代码生成来压缩包大小)
  • Improve compatibility with the web platform. (提升网络平台的兼容性)
  • Clean up internal structures that were left in a weird state while implementing features in v4 - without introducing any breaking changes.(清除一些内部架构,这些架构在v4版本中很奇怪.但并不会引起重大的改变)
  • Prepare for future features by introducing breaking changes now, allowing us to stay on v5 for as long as possible. (为了以后的release,我们现在引入了一些重大的改变,使我们可以在v5停留尽可能长的时间)

既然官方都说了要待一段时间我们就好好学吧,反正早用早享受!!!

timg.gif

我们先从这几个重大的变化娓娓道来

Improve build performance with Persistent Caching

传送门

Webpack5官方并没有将 Persistent Caching作为默认设置,而是需要我们去配置.因为Webpack5更主张安全而不是效率.不希望因为提升95%的表现而导致5%的出错.

当我们设置cache.type为 filesystem时 相对于webpack4 我们多了以下几点。

buildDependencies

传送门

buildDependencies指定构建过程的代码依赖性.让webpack负责解析和遵循指定值的依赖项.

官方推荐设置为 [__filename].
[__filename] depends在你的config文件.
当你任何使用require()的module发生改变时Persistent Caching就会无效.

module.exports = {
  cache: {
    buildDependencies: {
      // This makes all dependencies of this file - build dependencies
      config: [__filename]
      // By default webpack and loaders are build dependencies
    }
  }
};

如果是类似fs.readFile的话就不会

version

传送门

一些build的依赖是不能压缩成文件的像从数据库读取数据或者环境变量.对于这些值我们可以使用version

我们可以通过传递不一样的string来使Persistent Caching无效

如果你的config读取环境变量GIT_REV并且使用DefinePlugin来嵌入打包. 我们就可以将GIT_REV作为依赖.

仅当将cache.type设置为filesystem时,cache.version才有意义

cache: {
    version: `${process.env.GIT_REV}`
}
name

传送门
cache的名字,不同的名字将会导致不同的共存缓存。当具有多个应该具有独立缓存的配置时,使用cache.name才有意义

仅当将cache.type设置为filesystem时,cache.name才有意义

store

传送门
cache.store告诉了webpack什么时候存储data在filesystem

'pack':当编译器空闲时,将所有缓存项的数据存储在单个文件中
仅当将cache.type设置为filesystem时,cache.store选项才可用

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    store: 'pack'
  }
};

cacheDirectory

传送门
缓存的基本目录 默认node_modules/.cache/webpack

仅当将cache.type设置为filesystem时,cache.cacheDirectory选项才可用

最终路径为cache.directory + cache.name

const path = require('path');

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    cacheDirectory: path.resolve(__dirname, '.temp_cache')
  }
};
cacheLocation

传送门
cache路径 默认path.resolve(cache.cacheDirectory, cache.name).

仅当将cache.type设置为filesystem时,cache.cacheLocation才可用

const path = require('path');

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    cacheLocation: path.resolve(__dirname, '.test_cache')
  }
};

Improve Long Term Caching with better algorithms and defaults.

传送门

确定的 Chunk、模块 ID 和导出名称

这些是自动加入生产模式的

chunkIds: "deterministic" moduleIds: "deterministic" mangleExports: "deterministic"

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

真正的content hash

之前只是使用内部结构的哈希值。当只有注释被修改或变量被重命名时,这对长期缓存会有积极影响。这些变化在压缩后是不可见的。

Improve bundle size with better Tree Shaking and Code Generation.(通过更好的 Tree Shaking 和代码生成来压缩包大小)

嵌套的 tree-shaking

传送门
webpack 现在能够跟踪对导出的嵌套属性的访问。这可以改善重新导出命名空间 对象时的 Tree Shaking(清除未使用的导出和混淆导出)。

// inner.js
export const a = 1;
export const b = 2;

// module.js
export * as inner from './inner';
// or import * as inner from './inner'; export { inner };

// user.js
import * as module from './module';
console.log(module.inner.a);

在生产模式时,b会被删除

内部模块的 tree-shaking

传送门

webpack 4 没有分析模块的导出和引用之间的依赖关系。webpack 5 有一个新的选项 optimization.innerGraph,在生产模式下是默认启用的,它可以对模块中的标志进行分析,找出导出和引用之间的依赖关系。

import { something } from './something';

function usingSomething() {
  return something;
}

export function test() {
  return usingSomething();
}

innerGraph会找出 something 只有在使用 test 导出时才会使用。这允许将更多的出口标记为未使用,并从代码包中省略更多的代码。
当设置"sideEffects": false时,可以省略更多的模块。在这个例子中,当 test 导出未被使用时,./something 将被省略。
要获得未使用的导出信息,需要使用 optimization.unusedExports。要删除无副作用的模块,需要使用optimization.sideEffects。可以分析以下标记:

  • 函数声明
  • 类声明
  • 默认导出export default 或定义变量以下的:
  • 函数表达式
  • 类表达式
  • 顺序表达式
  • /#PURE/ 表达式
  • 局部变量
  • 引入的捆绑(bindings)

使用 eval() 将为一个模块放弃这个优化,因为经过 eval 的代码可以引用范围内的任何标记。这种优化也被称为深度范围分析。

CommonJs Tree的 Shaking

传送门
webpack used to opt-out from used exports analysing for CommonJs exports and require() calls.

webpack 5 增加了 一些CommonJs 构造的支持,允许消除未使用的 CommonJs 导出,并从 require() 调用中跟踪引用的导出名称。

以下结构是支持的:

  • exports|this|module.exports.xxx = ...
  • exports|this|module.exports = require("...") (reexport)
  • exports|this|module.exports.xxx = require("...").xxx (reexport)
  • Object.defineProperty(exports|this|module.exports, "xxx", ...)
  • require("abc").xxx
  • require("abc").xxx()
  • importing from ESM
  • require() a ESM
  • flagged exportType (special handling for non-strict ESM import):
  • Object.defineProperty(exports|this|module.exports, "__esModule", { value: true|!0 })
  • exports|this|module.exports.__esModule = true|!0
  • It's planned to support more constructs in future

当检测到不可分析的代码时,webpack 会放弃,并且完全不跟踪这些模块的导出信息(为了性能考虑)。

一般的Tree Shaking提升

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

export * 当webpack确定出口冲突时,将显示警告。

import()允许通过/ * webpackExports:[“ abc”,“ default”] * /魔术注释来手动tree shake。

Improve compatibility with the web platform.

webpack 5停止了nodejs中的polyfill并且专注于前端兼容模块。

我们的目标是提高与Web平台的兼容性,在Web平台上,Node.js核心模块不可用。

参考文档:

introducing-federated-modules-in-webpack-5
module-federation-guide-offical
persistent-caching-guide-offical
webpackv5-realease-changelog
精读module-federation

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349