webpack4和5的区别(待完善)

本文介绍了Webpack 5的重大变更,包括移除废弃功能、不再自动填充Node.js核心模块的polyfills,转而鼓励使用前端兼容的模块。讲解了如何在Webpack 5中手动配置polyfills,并对比了Webpack 4和5在长期缓存、开发支持、模块联邦等方面的不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

webpack4:2018年2月
webpack5:2021年10月10号

重大变更:

功能清除
  1. 清理弃用的能力
    所有在 v4 中被废弃的能力都被移除。
  2. 废弃代码
  3. 语法废弃
  4. 不再为Node.js模块自动引用polyfills
    webpack<=4.0版本:提供了许多Node.js核心模块的polyfills,当引用任何一个核心模块时(如crypto模块),webpack会自动引入polyfills。
    如下代码:实现一个签名的函数。
const crypto = require('crypto')

// 将值通过私钥签名,由.分割原值和签名
function sign (val, secret) {
  return val + '.' + crypto
    .createHmac('sha256', secret)
    .update(val)
    .digest('base64')
    .replace(/\=+$/, '');
};

module.exports = sign;

代码中使用到了 crypto 模块,因为在浏览器环境下是没有 crypto 这个东西,所以要引入 polyfills 做兼容处理。保证在浏览器中可以正常运行。
引入 polyfills 导致的问题就是打包的体积变大了。
怎么防止打包的时候把 crypto 模块打进去了,其实我们可以在 package.json 里面配置 browser 字段,然后设置值 false 就可以。这样代码就只能在 node 环境下运行了。

{
  "name": "webpack4",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "browser": {
    "buffer": false
  },
  "scripts": {
    "webpck": "npx webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "webpack": "^4.35.3",
    "webpack-cli": "^3.1.0"
  }
}

webpack5:不再自动填充这些 polyfills,而会专注于前端模块兼容。目标是提高 web 平台的兼容性。因为 node 模块本身就不是为浏览器设计的。

  • 尽量使用前端兼容的模块。比如 axios 这样的库,即可以在浏览器中运行,也可以在 node 环境中运行。
  • 可以手动为 Node.js 核心模块添加 polyfill。错误提示会告诉如何实现。
    比如下面的使用 webpack5 打包,报错信息是这样的。然后按照报错信息改。
    在这里插入图片描述
let path = require('path')
module.exports = {  
	mode: 'development',  
	entry: './src/index.js',  
	output: {
		filename: 'bundle.js',
		path: path.resolve(__dirname, 'dist'),
		library: 'result'
  	},  
  	resolve: {
  		fallback: {      
  			"crypto": require.resolve("crypto-browserify"), 
  			"stream": require.resolve("stream-browserify")
    	}
  	},
}
  • 在 package.json 中添加 browser 字段,使 node 模块 与前端兼容。为浏览器提供其他的 dependencies 依赖。
    下面 browser 字段的含义是在浏览器环境中把 crypto 模块替换为 crypto-js 模块。
{  
	"name": "webpack4",  
	"version": "1.0.0",  
	"description": "",  
	"main": "index.js",  
	"browser": {
		"crypto": "crypto-js"
  	},  
  	"scripts": {
  		"webpck": "npx webpack"
  	},  
  	"keywords": [],  
  	"author": "",  
  	"license": "ISC",  
  	"dependencies": {
  		"crypto-js": "^4.0.0","webpack": 
  		"^4.35.3","webpack-cli": "^3.1.0"
  	}
}

总结:因为 webpack 打包默认是输出到浏览器端,如果我们在编写代码的时候引入了 node 的核心模块,此时 webpack5 就会抛出错误,提示我们需要配置 polyfills 。解决办法有三个,第一就是不要去使用 node 模块,而是替换成其他的前端模块。第二就是自己配置 polyfills,第三就不让 node 模块打包进行。
如果我们写的代码只运行在 node 环境,直接配置 taget 就可以。

let path = require('path')
module.exports = {  
	mode: 'development',  
	entry: './src/index.js',  
	output: {
		filename: 'bundle.js',
		path: path.resolve(__dirname, 'dist'),
		library: 'result'
  	},  
  	target: 'node'
}

参考文章:https://blog.51cto.com/u_15081056/2594195

长期缓存
  1. 确定的 Chunk、模块 ID 和导出名称()
  2. 真正的内容哈希
    webpack<=4:使用内部结构的哈希值。 当只有注释被修改或变量被重命名时,这对长期缓存会有积极影响。这些变化在压缩后是不可见的。
    webpack5:当使用 [contenthash] 时,Webpack 5 将使用真正的文件内容哈希值。
开发支持
  1. 命名代码块 ID
    webpack<=4:import(/* webpackChunkName: “name” */ “module”)
    webpack5:模块 ID 由其路径决定。代码块 ID 由代码块的内容决定。
    1.可以在生产环境中使用 chunkIds: “named” 在生产环境中使用,但要确保不要不小心暴露模块名的敏感信息。
    2.如果不喜欢在开发中改变文件名,可以通过 chunkIds: “natural” 来使用旧的模式。
  2. 模块联邦
支持崭新的 Web 平台特性
  1. JSON 模块
  2. import.meta
  3. 资源模块
  4. 原生 Worker 支持
  5. URIs
  6. 异步模块
  7. 外部资源
支持全新的 Node.js 生态特性

现在支持 package.json 中的 exports 和 imports 字段。
原生支持 Yarn PnP。

开发体验
  1. 经过优化的构建目标(target)
  2. Stats
  3. 进度
  4. 自动添加唯一命名
  5. 自动添加公共路径
  6. Typescript 类型
构建优化
  1. 嵌套的 tree-shaking
  2. 内部模块 tree-shaking
    webpack 4: 没有分析模块的导出和引用之间的依赖关系。
    webpack 5: 有一个新的选项 optimization.innerGraph,在生产模式下是默认启用的,它可以对模块中的标志进行分析,找出导出和引用之间的依赖关系。
  3. CommonJs Tree Shaking
  4. 副作用分析
  5. 每个运行时的优化
  6. 模块合并
  7. 通用 Tree Shaking 改进
  8. 开发与生产的一致性问题
    webpack 4:由于 package.json 中的"sideEffects"标记不正确,这种优化导致了一些只在生产模式下出现的错误。
    webpack 5:默认在两种模式下都启用了 "sideEffects "优化。在开发过程中启用这个优化可以更快更容易地发现这些问题。
  9. 改进代码生成
    webpack 4:只生成 ES5 的代码。
    webpack 5:既可以生成 ES5 又可以生成 ES6/ES2015 代码。
  10. 改进 target 配置
  11. 代码块拆分与模块大小
性能优化
  1. 持久缓存
  2. 编译器闲置和关闭
  3. 文件生成
长期未解决的问题
  1. 单一文件目标的代码分割
  2. 更新了解析器
  3. 没有 JS 的代码块
未来计划
  1. 实验特性
  2. 最小 Node.js 版本
    最低支持的 Node.js 版本从 6 增加到 10.13.0(LTS)。

配置变更

未来计划
  1. 结构的变化
    1.entry: {} 现在可以赋值一个空对象(允许使用插件来修改入口)。
    2.target 支持数组,版本及 browserslist
    3.output.filename 可以设置为函数

  2. 默认值变更

加载器相关变更

重大内部变更

  1. 新的插件运行顺序
  2. 运行时模块
  3. 序列化
  4. 用于缓存的插件
  5. 冻结钩子对象
  6. Tapable 插件升级
  7. Stage 钩子
  8. Main/Chunk/ModuleTemplate 废弃
  9. 入口文件描述符
  10. 入口文件输出文件名
  11. 入口文件依赖
  12. 入口文件类库
  13. 入口文件运行时
  14. 入口文件代码块加载
  15. 排序与 ID
  16. 从数组到集合(Set)
  17. Compilation.fileSystemInfo
  18. Filesystems
  19. 工作队列
  20. Logging
  21. 模块和 chunk 图
  22. Init Fragments
  23. 模块 Source Types
  24. Stats 的插件
  25. 全新的监听
  26. SizeOnlySource after emit
  27. Emitting assets multiple times
  28. ExportsInfo
  29. 代码生成阶段
  30. 依赖关系参考
  31. Presentational Dependencies
  32. 弃用 loaders

微小改动

其他微小改动


当 Webpack 作为句首时,Webpack 的 W 应该大写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值