最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    正文概述 掘金(大转转FE)   2020-12-02   356

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    1 前言

    相信大家肯定看过很多产品的开箱测评,今天来跑一个软件新版的上手测评 — webpack5.0。自从2018年2月,webpack4 发布以来,webpack 就暂时没有更进一步的重大更新,阔别 2 年多后,webpack5正式发布!通过本文也希望为我们的项目是否值得升级v5提供一些参考。

    本次介绍的升级重点:

    • 功能清除

    • 长期缓存优化

    • 性能优化 — 持久化缓存

    • Module Federation

    • 其他特性

    2 功能清除

    不再为Node.js模块自动引用 Polyfills

    时过境迁,webpack模块应用的思想也发生了变化

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    • v4以前附带了许多node.js核心模块的polyfill,在构建时给 bundle附加了庞大的polyfills,在大部分情况下,polyfills并不是必须。

    • 现在v5将要停止这一切,在模块的应用中不再自动引入Polyfills,明显的减小了打包体积。

    举个栗子:

    // index.jsimport CryptoJS from 'crypto-js';const md5Password = CryptoJS.MD5('123123');console.log(md5Password);
    

    v5 vs v4:

    • 在v4中,crypto模块会主动添加 polyfill,也就是crypto-browserify,我们运行的代码是不需要的,反而会使最后的包变大,影响编译速度。v4的编译结果: (1.56MiB)

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    • v5编译中,会出现polyfill添加提示,如果不需要node polyfille,按照提示 alias 设置为 false 即可,下面v5中的配置以及编译结果: (244KiB)

      // webpack.config.js resolve: { // 1.不需要node polyfilss alias: { crypto: false }, // 2.手动添加polyfills // fallback: { // "crypto": require.resolve('crypto-browserify') // } },

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    如何迁移?

    • 尽量尝试使用前端兼容的模块,从而减小打包后的js体积

    • 根据错误提示 手动为Node.js 核心模块添加 polyfill

    3 长期缓存优化

    对比原来的chunkId和moduleId

    在v4之前, chunkId和moduleId默认值是自增id,这样的配置下,如果有新的entry增加,chunkId也会递增

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    • 缺点:当删除或者暂时不使用1.js这个文件后,那么2.js->1.js,3.js->2.js,这样就会造成原本线上的2.js请求时会造成缓存失效.

    • 解决缓存失效:引用外部插件

    • chunkId,可安装NamedChunksPlugin插件来稳定chunkId;或者配置optimization.chunkIds='named';

    • moduleId,可安装HashedModuleIdsPlugin插件覆盖默认的moduleId规则,使用模块路径生成的hash作为moduleId。

    webpack5新增了长期缓存的算法:

    算法策略:对moduleId和chunkId的生成策略进行了优化。

    • moduleId改为根据上下文模块路径计算,chunkId根据chunk内容计算

    • 以确定性的方式为模块和分块分配短的(3或5位)数字ID,这是包大小和长期缓存之间的一种权衡,因此webpack5将不需要引入任何的外力,便可实现长期缓存。

    再举个栗子来验证一下:

    // webpack.config.jsmodule.exports = {  entry: {    a: "./src/a.js",    b: "./src/b.js",    main: "./src/index.js"  },  // 长期缓存优化配置  optimization: {    chunkIds: 'deterministic',    moduleIds: 'deterministic'  },}
    

    编译后,会发现相应的模块和分块,分别被分配了确定的数字ID和名称,当项目中删除或者不使用某个模块时,对其他文件并不会产生影响。

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    注意: 虽然chuckId不变,但更改chunk内容时,chunkhash还是会改变的。

    如何迁移?

    • 直接使用chunkIds、moduleIds的默认值 (deterministic) 便可平滑迁移

    • 也可以使用旧的默认值chunkIds: "size",moduleIds: "size",这将会生成更小的包,但为了缓存,会更频繁地将其失效 (不建议使用)

    4 性能优化 — 持久化缓存

    Webpack的编译速度相信是很多同学比较头痛的问题,在 CI持续性集成或者构建线上应用包的阶段时,要对Webpack配置加入代码优化、代码压缩等插件,当然也有很多伟大的方法来进行优化,例如HappyPack、Cache-loader等方法,来缩减构建时间、减小成本。

    存在问题:

    • 这些方案在使用上需要一定的学习成本

    • 这些方法大多是以牺牲部分文件体积和后续优化空间为代价的。

    webpack5的持久化缓存方案

    v5性能优化可以总结为:

    • 第一次构建是一次全量构建,它会利用磁盘模块缓存(以空间换时间),使得后续的构建从中获利。

    • 后续构建具体流程是:读取磁盘缓存 -> 校验模块 -> 解封模块内容

    默认情况下,缓存配置是memory,目前项目编译的时间为3298ms

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    v5中,可以修改设置为filesystem, 将缓存写入硬盘,不在需要cache-loader等性能优化的方法。

    // webpack.config.jsmodule.exports = {   cache: {    // 1. 将缓存类型设置为文件系统    type: 'filesystem', // 默认是memory    // 2. 将缓存文件夹命名为 .temp_cache,    // 默认路径是 node_modules/.cache/webpack    cacheDirectory: path.resolve(__dirname, '.temp_cache')  }};
    

    配置后的编译时间为776ms, 相比之前的默认配置,大大缩减了编译时间。

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    4 Module Federation

    如果说上面的优化都是常规套路,那么本次升级的模块联邦,有点让人出乎意料~

    什么是模块联邦?

    • Module Federation是为了解决独立应用之间代码共享问题。可以在项目内动态加载其他项目的代码,同步可以共享依赖。

    • 通过细化功能模块、组件复用、共享第三方库、runtime dependencies线上加载npm包等,可以更好的服务于多页应用、微前端等开发模式。

    以前我们共享代码是如何做的?

    NPM
    维护一个CommonComponents的NPM包,在不同项目中安装、使用。如果 NPM 包升级,对应项目都需要重新安装新版本,本地编译,打包到 bundle 中。

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    UMD
    即Universal Module Definition(通用模块规范),基本原理是利用设计模式中的工厂函数来统一不同的模块定义规范

    UMD优点在 runtime。缺点也明显,体积优化不方便,容易有版本冲突.

    微前端
    微前端也是一种模块共享的方式,主要解决多项目并存问题,多项目并存的最大问题就是模块共享,不能有冲突。

    在资源加载方式上,一般有两种打包方式:

    • 子应用独立打包,模块解耦了,但公共的依赖不易维护处理

    • 整体应用一起打包,能解决公共依赖;但庞大的多个项目又使打包变慢,后续也不好扩展

    微前端架构如下:

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    v5中模块共享方式 — 模块联邦

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    • 从图中可以看到,这个方案是直接将一个应用的 bundle,应用于另一个应用。

    • 应用可以模块化输出,就是说它本身可以自我消费,也可以动态分发 runtime 子模块给其他应用。

    模块联邦的使用方式如下

    module.exports = {  // other webpack configs...  plugins: [    new ModuleFederationPlugin({      // 1. name 当前应用名称,需要全局唯一      name: "app_one_remote",      // 2. remotes 可以将其他项目的 name 映射到当前项目中      remotes: {        app_two: "app_two_remote",        app_three: "app_three_remote"      },      // 3. exposes 表示导出的模块,只有在此申明的模块才可以作为远程依赖被使用      exposes: {        AppContainer: "./src/App"      },      // 4. shared可以让远程加载的模块对应依赖改为使用本地项目的 React或ReactDOM。      shared: ["react", "react-dom", "react-router-dom"]    }),    new HtmlWebpackPlugin({      template: "./public/index.html",      chunks: ["main"]    })  ]};
    

    比如设置了remotes: { app_two: "app_two_remote" },在代码中就可以直接利用以下方式直接从对方应用调用模块

    import { Search } from "app_two/Search";
    

    app_two/Search来自于app_two 的配置:

    // app_two的webpack 配置export default {  plugins: [    new ModuleFederationPlugin({      name: "app_two",      library: { type: "var", name: "app_two" },      filename: "remoteEntry.js",      exposes: {        Search: "./src/Search"      },      shared: ["react", "react-dom"]    })  ]};
    

    正是因为 Search在exposes被导出,我们因此可以使用 [name]/[exposes_name] 这个模块,这个模块对于被引用应用来说是一个本地模块。

    5 其他特性

    • 构建优化 — 更好的Tree Shacking

    • 支持崭新的web平台功能

    • 开发体验的提升

    • ...

    6 思考

    总体来说webpack5在打包体积、编译速度上都有了不错的提升,在很多功能的配置、迁移上也较灵活便。在升级中,一些细节和插件的兼容性是主要的问题,还有待继续完善。抛砖引玉,欢迎大家一起来吐槽~

    参考

    [1]. webpack5官网 webpack.docschina.org/blog/2020-1…
    [2]. 模块联邦官网
    module-federation.github.io/blog/get-st…
    [3]. webpack5优化和工作原理 www.jianshu.com/p/b26c5253c…
    [4]. webpack新特-模块联邦 zhuanlan.zhihu.com/p/115403616

    打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0


    起源地下载网 » 打工人,打工魂,打工不懂工具忙死人,教你如何优雅使用webpack5.0

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元