webpack5新功能展望
Author:zhoulujun Date:
webpack5 beta0,由sokra released on 11 Oct 2019,2063 commits to master since this release
当天,webpack更新到 v4.41.1
现在最新版本的 webpack4 更新到了 v4.44.1,webpack5 已经到 v5.0.0-beta.25
其中,v5.0.0-beta.23、v5.0.0-beta.18、v5.0.0-beta.17,Features 都是一个大列表
虽然还没有正式版放出,但是我们也得上车,体验了
webpack5新特性总结
使用持久化缓存提高构建性能,使用cache: {type: "filesystem"}配置实现持久化缓存,提高构建速度;
使用更好的算法和默认值改进长期缓存(long-term caching),解决生产环境下moduleIds & chunkIds变化的问题;
清理内部结构而不引入任何破坏性的变化;
引入一些breaking changes,以便尽可能长的使用v5版本。
减小打包后的文件体积,按需加载支持文件名模式
优化minSize&maxSize的配置方式
Node.js polyfills 自动加载功能被移除,Webpack 5 开始将不再自动添加 Polyfill 脚本了,可以有效减少最终编译代码的大小。
下面细讲
Persistent Caching
在 Webpack 编译过程中,如果某个文件发生变化,那么 Webpack 会从 entry 开始,从新递归查找所依赖的模块,然后重新编译。
Webpack 5 中采用持久化缓存来优化整个编译流程:当检测到文件发生变化时,只会对发生变更的文件进行编译,从而提高编译效率。
默认情况下,持久化缓存是不开启的,可以通过下面的配置启用持久化缓存:
cache: { // 1. Set cache type to filesystem type: "filesystem", buildDependencies: { // 2. Add your config as buildDependency to get cache invalidation on config change config: [__filename] // 3. If you have other things the build depends on you can add them here // Note that webpack, loaders and all modules referenced from your config are automatically added } }
缓存文件存储在 node_modules/.cache/webpack 或 .pnp/.cache/webpack 中。
Named Chunk IDs
在 Webpack5 中开发模式将默认启用全新的 Chunk ID 命名算法,提高 Chunk 名称的可读性。Module ID 由其相对的上下文路径决定,Chunk ID 由其内容决定。
也可以通过下面的配置开启或禁用新的命名算法:
开启:optimization: { chunkIds: 'named' }
关闭:optimization: { chunkIds: 'natural' }
Deterministic Chunk and Module IDs
为了帮助长期缓存(long term caching),Webpack 5 增加了新的算法。新算法会以确定的方式为 Module、Chunk 分配一个非常短(3~4 个字符)的数字 ID。因此,对于没有发生变化的 Module 或 Chunk,它们对于的 ID 也不会发生变化,仍然可以被浏览器缓存,提高资源加载的性能。
开启:optimization: { chunkIds: 'deterministic' }
关闭:optimization: { chunkIds: 'size' }
Tree-shaking Optimize
Webpack 5 可以追踪分析嵌套模块的再输出,移除未使用的代码。
下面代码中编译后 b 将会被移除:
// inner.js export const a = 1; export const b = 2; // module.js import * as inner from "./inner"; export { inner } // user.js import * as module from "./module"; console.log(module.inner.a);
另外,Webpack 5 新增了优化选项 optimization.innerGraph,可以分析模块内部输入、输出的依赖关系,来判断哪些代码未使用。
import { something } from "./something"; function usingSomething() { return something; } export function test() { return usingSomething(); }
上面的代码,如果 test() 未被使用,那么 ./something 将会在 Tree-shaking 过程中被移除。
Improved Code Generation
Webpack 4 最终编译生成的代码对应的版本是 ES5,Webpack 5 中可以指定编译后的代码版本为 ES5 或 ES6/ES2015。
output: { ecmaVersion: 5 | 2015 }
其实es6,目前大部兼容性还是不太好。未来可期
SplitChunks and Module Sizes
Webpack 支持 splitChunks 给不同的文件类型设定文件最小、最大的拆分限制条件。
minSize: { javascript: 30000, style: 50000, }
这是主要功能
webpack4升级到webpack5
To v5 from v4,官方文档:https://webpack.js.org/migrate/5/
npm install webpack@next --dev
配置还是需要修改的
更新的配置项
以下配置需要更新
optimization.hashedModuleIds: true
↦optimization.moduleIds: 'hashed'
optimization.namedChunks: true
↦optimization.chunkIds: 'named'
optimization.namedModules: true
↦optimization.moduleIds: 'named'
NamedModulesPlugin
↦optimization.moduleIds: 'named'
NamedChunksPlugin
↦optimization.chunkIds: 'named'
HashedModulesPlugin
↦optimization.moduleIds: 'hashed'
optimization.occurrenceOrder: true
↦optimization: { chunkIds: 'total-size', moduleIds: 'size' }
optimization.splitChunks.cacheGroups.vendors
↦optimization.splitChunks.cacheGroups.defaultVendors
Compilation.entries
↦Compilation.entryDependencies
serve
↦serve
is removed in favor ofDevServer
清除的配置项
Consider removing optimization.moduleIds and optimization.chunkIds from your webpack configuration. The defaults could be better, because they support long term caching in production mode and debugging in development mode.
When using [hash] placeholder in webpack configuration, consider changing it to [contenthash]. It is not the same, but proven to be more effective.
If you are using Yarn's PnP and the pnp-webpack-plugin, we have good news: it is supported by default now. You have to remove it from the configuration.
If you are using IgnorePlugin with a regular expression as argument, it takes an options object now: new IgnorePlugin({ resourceRegExp: /regExp/ }).
Reconsider optimization.splitChunks:
It's recommended to use either the defaults or
optimization.splitChunks: { chunks: 'all' }
.When using HTTP/2 and long term caching, set
optimization.splitChunks: { chunks: 'all', maxInitialRequests: 30, maxAsyncRequests: 30, maxSize: 100000 }
.When using a custom configuration, replace
name
withidHint
.It was possible to turn off the defaults by setting
optimization.splitChunks: { default: false, vendors: false }
. We don't recommend doing this, but if you really want to get the same effect in webpack 5:optimization.splitChunks: { default: false, defaultVendors: false }
.
高级进阶
CDN配置
// webpack.config.jsconst path = require('path');{ entry: { main: './src/index.js', sub: './src/sub.js' }, output: { publicPath: 'http://cdn.example.com' filename: '[name].js', path: path.resolve(__dirname, 'dist') }}
写入到http://cdn.example.com/main.js, http://cdn.example.com/sub.js
Webpack5 模块联邦让 Webpack 达到了线上 Runtime 的效果,让代码直接在项目间利用 CDN 直接共享,不再需要本地安装 Npm 包、构建再发布了!
我们知道 Webpack 可以通过 DLL 或者 Externals 做代码共享时 Common Chunk,但不同应用和项目间这个任务就变得困难了,我们几乎无法在项目之间做到按需热插拔。
模块联邦是 Webpack5 新内置的一个重要功能,可以让跨应用间真正做到模块共享,所以这周让我们通过 webpack-5-module-federation-a-game-changer-in-javascript-architecture 这篇文章了解什么是 “模块联邦” 功能。
NPM 方式共享模块:常的代码共享需要将依赖作为 Lib 安装到项目,进行 Webpack 打包构建再上线
UMD 方式共享模块:真正 Runtime 的方式可能是 UMD 方式共享代码模块,即将模块用 Webpack UMD 模式打包,并输出到其他项目中。
微前端方式共享模块:微前端就是要解决多项目并存问题,多项目并存的最大问题就是模块共享,不能有冲突。
子应用独立打包,模块更解耦,但无法抽取公共依赖等。
整体应用一起打包,很好解决上面的问题,但打包速度实在是太慢了,不具备水平扩展能力。
讨论地址是:精读《Webpack5 新特性 - 模块联邦》 · Issue #239 · dt-fe/weekly
PWA 打包配置
渐进式网络应用程序(Progressive Web Application - PWA),是一种可以提供类似于原生应用程序(native app)体验的网络应用程序(web app)。PWA 可以用来做很多事。其中最重要的是,在离线(offline)时应用程序能够继续运行功能。这是通过使用名为 Service Workers 的网络技术来实现的 添加 workbox-webpack-plugin 插件,并调整 webpack.config.js 文件:
npm install workbox-webpack-plugin --save-dev
webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const WorkboxPlugin = require('workbox-webpack-plugin'); module.exports = { entry: { app: './src/index.js', print: './src/print.js' }, plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title: 'Output Management' title: 'Progressive Web Application' }) }), new WorkboxPlugin.GenerateSW({ // 这些选项帮助 ServiceWorkers 快速启用 // 不允许遗留任何“旧的” ServiceWorkers clientsClaim: true, skipWaiting: true }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };
注册 Service Worker
import _ from 'lodash'; import printMe from './print.js'; if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js').then(registration => { console.log('SW registered: ', registration); }).catch(registrationError => { console.log('SW registration failed: ', registrationError); }); }); }
现在来进行测试。停止服务器并刷新页面。如果浏览器能够支持 Service Worker,你应该可以看到你的应用程序还在正常运行。然而,服务器已经停止了服务,此刻是 Service Worker 在提供服务。
参考文章:
了解 Webpack 5 https://www.hexuanzhang.com/2413384094.html
精读《Webpack5 新特性 - 模块联邦》 https://zhuanlan.zhihu.com/p/115403616
webpack5新特性总结 https://blog.csdn.net/webofrxy/article/details/94436780
webpack5快发布了,你还没用过4吗? https://zhuanlan.zhihu.com/p/99339368?from_voters_page=true
转载本站文章《webpack5新功能展望》,
请注明出处:https://www.zhoulujun.cn/html/tools/Bundler/webpackTheory/8544.html