Webpack 5 的变化

发布于 2023-07-07 05:46:42 字数 3379 浏览 50 评论 0

现代前端开发都讲究模块化开发,作为打包界的扛把子,Webpack 对与整个前端生态有着巨大的影响。但是随着 Vite,ESBuild 等后起之秀的崛起,webpack 本身存在的问题就愈发明显。无论是繁琐的配置文件,还是奇慢无比的构建速度都令人望而却步。

Webpack 官方也知道自身的问题,于是 Webpack 5 来了

1. 它的变化

版本来到了 5,Webpack 有了以下这些变化:

1.1 基于文件系统的缓存

{
	cache: "filesystem"
}

新增的缓存的功能让开发者在首次构建后享受缓存带来的构建速度提升(是的,首次还是很慢),实际测试后,无论是直接构建还是热更新开发,首次之后的重新构建时间只有几秒,热更新甚至少于 1s.

开启了这个功能之后,会在 node_modules 文件下多一个 .cache 的文件夹,里面会存放之前构建产生的缓存。但是这个功能还是存在问题,由于缓存的存在,新添加的插件或者热更新被打断后重新运行都有几率报错。遇到这个问题,删除 .cache 文件夹就好了

1.2 Asset Modules

Webpack 5 新增了 Asset Module,取代了之前版本需要下载的 raw-load, url-loader , file-loader .

Asset Modules 总共有四种类型

asset/resource

用于文件的处理,替换了 file-loader

{
    test: /\.(mp4|mp3|wav)$/,
    type: 'asset/resource',
    generator: {
        filename: 'res/video/[name][ext]',
    }
},

asset/inline

替换了 url-loader , 会将文件转化为 data URL

asset/source

替换了 raw-loader ,会直接导入文件的内容

asset 默认

会自动选择生产文件还是生成 data URL, 可以进行设置 maxSize 来进行判断处理

{
    test: /\.(woff2|ttf|woff|png|svg|eot|jpg)$/,
    type: 'asset',
    parser: {
        dataUrlCondition: {
            maxSize: 100000
        }
    },
    generator: {
        filename: 'res/[hash][ext]',
    }
}

因为 Webpack 内置了这个所以之前的 url-loader 等依赖也无法在 Webpack 5 下生效

1.3 Module Federation

Webpack 5 的更新中,这个功能最有用(我说的)。Module Federation 即模块联邦,在配置文件中配置后可以让当前项目共享其他项目的代码,也可以共享本身的代码给其他服务。

在实际使用中就可以用来做组件库,然后共享给所有项目。完美解决了以往通用组件库存在的痛点,即每次更新后,所有使用到组件库的服务都需要重新进行依赖下载和构建。 而 Module Federation 只用构建组件库即可,依赖组件库的服务可以直接使用到最新的组件。

Module Federation 的配置如下

// 服务
new ModuleFederationPlugin({
    name: 'service-name',
    remotes: {
        microFE: `microFE@http://localhost:7777/remoteEntry.js`
    },
    shared: {
        ...deps
    }
})
// 组件库
new ModuleFederation({
    name: "microFE",
    filename: 'remoteEntry.js',
    exposes: {
        './Button': './src/components/Button/index.vue',
    },
		shared: {
			...deps, // packjson.dependencies
			vue: ..., // 有些模块需要声明共享的程度
		}
})

服务本身要切换成动态导入的模式

// main.js 入口文件
import('bootloader.js')
// main.js 入口文件
import('bootloader.js')

// bootloader.js
import Vue from 'vue
import App from 'App.vue'

new Vue({
    render: h => h(App)
}).$mount("#app")

// 页面中使用
import Button from 'microFE/Button'

Module Federation 本身的原理还是很简单的,就是利用动态导入打包成单独的包,然后其他服务使用时通过 url 加载对应的 bundle 即可。有了这个特性无论前端框架是什么,都可以做到组件共享。

然后讲一下配置项

  • name: 'service-name' 定义服务的名称
  • remotes 共享的服务的地址
  • shared 声明公用的依赖
  • exposed 声明暴露给其他服务使用的模块
  • filename 服务构建后生产的单独文件,用于其他服务 remotes 使用

1.4 其他修改

Webpack 5 还有很多其他的修改,例如一些配置项的更改, 内置了 Terser 进行代码压缩等。

2. 存在的问题

新的版本,新的功能。总的来说对于开发者的使用体验有了很大的提升。

在升级的过程中,我发现了一些问题:

  1. plugin 的写法还是过于复杂,用户自定义插件开发体验还是很糟糕
  2. 首次构建速度变慢了,因为内置了 Terser
  3. 引入的缓存系统导致构建时的报错

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

柳絮泡泡

暂无简介

文章
评论
655 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文