webpack、vite的自动导包的“爱恨情仇“

webpack、vite的自动导包的"爱恨情仇"

前言

最近在开发Vue3+Vite的统一基座工程,遇到了模块自动导入的不同构建工具的引入方式,特此记录。

在项目中,为了避免频繁导入。大家都会在对应,例如项目使用Webpack 打包工具的。在其项目store文件下其中的index.js 文件中使用webpack提供的apirequire.context的方法实现自动导入。

ES 模块规范

在实现自动导入模块前,我们先了解下ES 模块规范

所谓的ES模块规范,即 JavaScript 的标准模块系统,它允许您使用 importexport 关键字来导入和导出模块。这是现代 JavaScript 中推荐使用的模块化方式。

ES模块规范中,提供了import.meta.glob功能。它允许在项目运行中动态匹配特定模式的模块。例如以下代码就可以动态匹配到module模块下的所有js文件。

import.meta.glob('./module/*.js')

话不多说,上干货

例如,你的项目sotre文件目录为

- store
  - module
    - module1.js
    - module2.js
    - ...
    - moduleN.js
  - main.js
​

其中module下的moduleX文件你的main.js为你的sotre入口文件,

webpack中的自动导入的实现方式

main.js入口文件中你可以使用webpack提供require.context的方法实现module文件目录下的模块自动导入。

const files = require.context('./model', false, /\.js$/)
const modules = {}
files.keys().forEach((key) => {
    modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
})
​
export default modules

其中files.keys()require.context方法返回的一个函数,它会返回一个包含所有匹配模块路径的数组。

require.context是Webpack提供的一个方法,它允许你在构建时动态地导入模块。该方法接收三个参数:

  1. directory: 表示要搜索的目录路径。

  2. useSubdirectories: 表示是否搜索子目录。

  3. regExp: 表示匹配文件的正则表达式。

在上面代码中,files就是通过require.context动态导入了./model目录下所有的.js文件,并使用正则表达式/\.js$/来匹配文件。这样,files.keys()返回一个包含所有匹配模块路径的数组。例如控制台打印files.keys()可获得以下数组

[
    "./module1.js",
    "./module2.js",
    "./。。。.js",
    "./moduleN.js"
]

接着,我们可以使用.forEach()遍历这个数组,对每个匹配的模块进行处理,提取模块名,并将模块添加到modules对象中。这样,你就得到了一个以模块名为键、模块对象为值的modules对象,它包含了所有从./model目录中动态导入的模块。

vite自动导入的实现方式

main.js入口文件中你可以使用ES模块规范提供的import.meta.glob方法来获取特定模块的匹配模式,来实现自动导入。

// main.js
const modules = {};
​
async function importAllModules() {
  const files = import.meta.glob('./module/*.js');
  for (const path in files) {
    const key = path.replace(/\.\/module\/|\.js/g, '');
    const module = await files[path]();
    modules[key] = module.default;
  }
}
​
importAllModules().then(() => {
  console.log(modules); // 所有模块已导入并组合成对象
});
​
// 现在可以导出组合后的 modules 对象供其他地方使用
export default modules;
​

在这种情况下,使用异步操作是因为模块导入是一个异步操作。import.meta.glob()方法会返回一个对象,该对象的键是匹配到的文件路径,值是一个函数,调用该函数将异步导入对应的模块。因此,我们需要使用异步操作来等待模块导入完成,然后再将其添加到modules对象中。

如果我们不使用异步操作,而是直接将模块导入的结果添加到module对象中,那么由于模块导入是异步的,modules对象可能在模块导入完成之前被导出,导致modules对象不完整或为空。使用异步操作可以确保在所有模块导入完成后再导出modules对象,保证其包含所有模块导出的内容。

总结

为什么都是打包工具,会有不同的自动导入方式呢?

在使用 Webpack 的情况下,与使用 Vite 或其他原生支持 ES 模块的项目相比,自动导入模块的实现会有一些区别。主要区别在于 Webpack 不支持 import.meta.glob,因为它是 ES 模块的一个特殊功能,而 Webpack 是一个打包工具,不完全符合 ES 模块的规范。

那这里就浅浅对比下俩种打包工具的差异吧

webpack
  • 成熟度高。Webpack是一个成熟且应用相当广泛的打包构建工具,具有强大的生态系统和社区支持。

  • 打包速度较慢。Webpack打包速度在大型项目打包速度比较慢,从入口文件开始,基于代码中的import、export、require构建依赖树,将所有的模块打包到一个或者几个少数文件中。因此,项目规模庞大的话,启动和热更新更慢。每次代码变更构建都需要生成新的Bundle文件。

  • 配置复杂。官网配置很多,需要处理不同的Loader和Plugin来管理不同的资源文件。

  • 插件系统丰富。Webpack具有强大的插件系统,允许开发者根据需求扩展定义。

  • Tree Shaking。Webpack通过使用UglifyJS等工具进行Tree Shaking,消除未使用的代码

  • 热模块替换(HMR)。Webpack支持热模块替换,但在某些情况下需要手动配置。

Vite
  • 新兴技术。Vite是一个相较新的构建工具,旨在提供更快的开发体验和构建速度。

  • 打包速度极快。Vite在开发环境下具有极快的启动和热更新速度,因为它采用了原生ES模块的方式,并且将依赖项保持为独立的文件,而不是打包到一个大文件中。

  • 配置简单。Vite的配置比Webpack简单,尤其是对于常见的项目结构,大部分任务都无需额外配置。

  • 热模块替换(HMR)。Vite对热模块替换的支持非常好,在开发过程中几乎不需要手动配置即可实现HMR。

  • Tree Shaking。Vite使用Rollup进行Tree Shaking,这使得未使用的代码更容易被消除。

  • 插件系统还不够完善。Vite的插件系统仍在发展中,目前没有Webpack那么丰富的插件支持。

总之,Webpack更加适合与大型、复杂项目的构建工作,拥有成熟和完善的生态系统和社区。Vite更适合用于一些热更新快速的程序。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值