webpack5开箱体验
如果您正在打包前端代码,很可能使用一个工具来实现。这个工具极有可能是Webpack。目前Webpack5已经处于beta阶段。
此版本重点关注以下内容:
- 通过持久缓存提高构建性能
- 使用更好的算法和默认值来改善长期缓存
- 通过更好的Tree Shaking和代码生成来提高bundle的大小,Commonjs 的 TreeShaking,更好的 TreeShaking
- 可以生成 ES5 和 ES6 / ES2015 代码
- 提高与Web平台的兼容性
- 通过更好的树摇和代码生成来改善捆绑包大
- 清除处于怪异状态的内部结构,同时在 v4 中实现功能而不引入任何重大更改
- 通过引入重大更改来为将来的功能做准备,以使我们能够尽可能长时间地使用 v5
安装
npm i webpack@next webpack-cli -D
体验
更彻底的Tree Shaking
- webpack 现在能够处理对嵌套模块的 tree shaking
// a.js
export const name = 'JavaScript';
export const age = "Brendan Eich于1995年创造了我,我都25岁了";
// b.js
import * as a from './a';
export { a };
// index.js
import * as b from './b';
console.log(b.a.name);
webpack4
// webpack.config.js
const { resolve } = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: '[name].js',
path: resolve(__dirname, 'build')
},
mode: 'production'
};
打包后生成代码:
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=0)}([function(e,n,t){"use strict";t.r(n);var r={};t.r(r),t.d(r,"name",(function(){return o})),t.d(r,"age",(function(){return u}));const o="JavaScript",u="Brendan Eich于1995年创造了我,我都25岁了";console.log(r.name)}]);
webpack5
// webpack.config.js
module.exports = {
mode: 'production'
};
打包后生成代码:
(()=>{"use strict";console.log("JavaScript")})();
- webpack 现在能够多个模块之前的关系
import { something } from './something';
function usingSomething() {
return something;
}
export function test() {
return usingSomething();
}
当设置了"sideEffects": false
时,一旦发现test
方法没有使用,不但删除test
,还会删除 "./something"
- webpack 现在能处理对 Commonjs 的 tree shaking
-
Output
webpack 4 默认只能输出 ES5 代码 webpack 5 开始新增一个属性 output.ecmaVersion, 可以生成 ES5 和 ES6 / ES2015 代码,如:output.ecmaVersion: 2015
-
SplitChunk
// webpack4 minSize: 30000;
可以对JS和css做代码切割
// webpack5 minSize: { javascript: 30000, style: 50000, }
-
Caching
// 配置缓存 cache: { // 磁盘存储 type: "filesystem", // 'memory' | 'filesystem' buildDependencies: { // 当配置修改时,缓存失效 config: [__filename] } }
缓存将存储到
node_modules/.cache/webpack
-
监视输出文件
之前 webpack 总是在第一次构建时输出全部文件,但是监视重新构建时会只更新修改的文件。 此次更新在第一次构建时会找到输出文件看是否有变化,从而决定要不要输出全部文件。
-
自动删除 Node.js Polyfills
早期,webpack 的目标是允许在浏览器中运行大多数 node.js 模块,但是模块格局发生了变化,许多模块用途现在主要是为前端目的而编写的。webpack <= 4 附带了许多 node.js 核心模块的 polyfill,一旦模块使用任何核心模块(即 crypto 模块),这些模块就会自动应用。 尽管这使使用为 node.js 编写的模块变得容易,但它会将这些巨大的 polyfill 添加到包中。在许多情况下,这些 polyfill 是不必要的。 webpack 5 会自动停止填充这些核心模块,并专注于与前端兼容的模块。 迁移: - 尽可能尝试使用与前端兼容的模块。 - 可以为 node.js 核心模块手动添加一个 polyfill。错误消息将提示如何实现该目标。
-
Chunk 和模块 ID
添加了用于长期缓存的新算法。在生产模式下默认情况下启用这些功能。
chunkIds: "deterministic", moduleIds: "deterministic", mangleExports: "deterministic"
该算法为模块和块分配短(3或4个字符)数字ID,并以确定性方式为导出分配短(2个字符)名称。这是包大小和长期缓存之间的折衷方案。moduleIds/chunkIds/mangleExports: false
禁用默认行为,并且可以通过插件提供自定义算法。请注意,在moduleIds/chunkIds: false
没有自定义插件的webpack 4中,生成的版本有效,而在webpack 5中,您必须提供自定义插件。 注意:在webpack 4中,散列的模块ID导致gzip性能降低。这与更改的模块顺序有关,并且已得到修复。 注意:在webpack 5中,deterministic
在生产模式下默认启用ID -
Chunk ID
你可以不用使用
import(/* webpackChunkName: "name" */ "module")
在开发环境来为 chunk 命名,生产环境还是有必要的。 可以chunkIds: "named"
在生产中使用,但请确保不要意外地泄露有关模块名称的敏感信息。 webpack 内部有 chunk 命名规则,不再是以 id(0, 1, 2)命名了 迁移:如果您不喜欢在开发中更改文件名,则可以通过chunkIds: "natural"
使用旧的数字模式。 -
默认值
entry: "./src/index.js
output.path: path.resolve(__dirname, "dist")
output.filename: "[name].js"
-
更多配置参考
- 联邦模块 (重点)
Webpack 5添加了一个称为“联邦模块”的新功能,该功能允许多个Webpack构建协同工作。从运行时的角度来看,形成多个构建的模块的行为将类似于巨大的连接模块图。从开发人员角度来看,可以从指定的远程版本中导入有针对性的模块,并以最小的限制使用它们。 有关更多详细信息,请参阅此单独的指南。
联邦模块为更大型的前端应用提供了开箱解决方案,并已经作为 Webpack5 官方模块内置,可以说是继 Externals 后最终的运行时代码复用解决方案。
转载自:https://juejin.cn/post/6882616889907150855