webpack、vite的自动导包的"爱恨情仇"
webpack、vite的自动导包的”爱恨情仇”
前言
最近在开发Vue3+Vite的统一基座工程,遇到了模块自动导入的不同构建工具的引入方式,特此记录。
在项目中,为了避免频繁导入。大家都会在对应,例如项目使用Webpack 打包工具的。在其项目store文件下其中的index.js 文件中使用webpack提供的apirequire.context
的方法实现自动导入。
ES 模块规范
在实现自动导入模块前,我们先了解下ES 模块规范
。
所谓的ES模块规范
,即 JavaScript 的标准模块系统,它允许您使用 import
和 export
关键字来导入和导出模块。这是现代 JavaScript 中推荐使用的模块化方式。
在ES模块规范
中,提供了import.meta.glob
功能。它允许在项目运行中动态匹配特定模式的模块。例如以下代码就可以动态匹配到module
模块下的所有js
文件。
1 | import.meta.glob('./module/*.js') |
话不多说,上干货
例如,你的项目sotre文件目录为
1 | - store |
其中module
下的moduleX
文件你的main.js
为你的sotre入口文件,
webpack中的自动导入的实现方式
在main.js
入口文件中你可以使用webpack提供require.context
的方法实现module
文件目录下的模块自动导入。
1 | const files = require.context('./model', false, /\.js$/) |
其中files.keys()
是require.context
方法返回的一个函数,它会返回一个包含所有匹配模块路径的数组。
require.context
是Webpack提供的一个方法,它允许你在构建时动态地导入模块。该方法接收三个参数:
directory
: 表示要搜索的目录路径。useSubdirectories
: 表示是否搜索子目录。regExp
: 表示匹配文件的正则表达式。
在上面代码中,files
就是通过require.context
动态导入了./model
目录下所有的.js
文件,并使用正则表达式/\.js$/
来匹配文件。这样,files.keys()
返回一个包含所有匹配模块路径的数组。例如控制台打印files.keys()
可获得以下数组
1 | [ |
接着,我们可以使用.forEach()
遍历这个数组,对每个匹配的模块进行处理,提取模块名,并将模块添加到modules
对象中。这样,你就得到了一个以模块名为键、模块对象为值的modules
对象,它包含了所有从./model
目录中动态导入的模块。
vite自动导入的实现方式
在main.js
入口文件中你可以使用ES模块规范
提供的import.meta.glob
方法来获取特定模块的匹配模式,来实现自动导入。
1 | // main.js |
在这种情况下,使用异步操作是因为模块导入是一个异步操作。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更适合用于一些热更新快速的程序。