Vite 里使用动态加载

有时候,我们希望根据用户当前的使用状态决定加载哪些模块。比如一个网页 IDE,用户在写 JS,我们就加载 JS 模块;用户在写 PHP 我们就加载 PHP 模块。这个功能有点类似路由懒加载,但又不完全相同。

以前在 wepback 里,我们可以通过动态 import 加注释的方式来做:

webpack.config.js
const _ = await import(/* webpackChunkName: "lodash" */ 'lodash'); // 通过组合不同注释,还可以实现不同的分包和加载策略 // Single target import( /* webpackChunkName: "my-chunk-name" */ /* webpackMode: "lazy" */ /* webpackExports: ["default", "named"] */ 'module' ); // Multiple possible targets import( /* webpackInclude: /\.json$/ */ /* webpackExclude: /\.noimport\.json$/ */ /* webpackChunkName: "my-chunk-name" */ /* webpackMode: "lazy" */ /* webpackPrefetch: true */ /* webpackPreload: true */ `./locale/${language}` );

上面的内容可以在 Webpack 官方文档 找到。

Vite 里提供了类似的功能,不过使用方式不太一样。现在的 Vite 2 已经抛弃了以前的插件式实现,即 vite-plugin-dynamic-import 和 @rollup/plugin-dynamic-import-vars 都不会用到。

首先,我们要使用 import.meta.glob('./*.js`) 声明哪些文件可能要用到;接下来,我们就可以根据实际需求加载具体文件。大概方式如下:

/src/components/share.vue
<script lang="ts" setup> // <script setup> 的代码,相当于 `created`,所以可以使用动态加载 // 未来要使用的变量 let shareTexts:ShareTexts; // 声明符合 `/src/data/share*.ts` 的文件都可能要用到 const modules = import.meta.glob('../data/share*.ts'); // 如果 store 里有 `langName`,就加载 i18n 版,否则加载普通版 modules[`../data/${store.state.langName ? 'share-i18n' : 'share'}.ts`]() .then(data => { // 因为用到 esm,所以要加 `default` shareTexts = data.default; }); </script>

接下来,还可以配合 vite.config.js,将相关装入特定分包:

vite.config.js
export default defineConfig(({command, mode}) => { return { plugins: [ vue(), ], build: { rollupOptions: { output: { manualChunks(id) { let result; if (result = /(shares\/)?share\d\.txt\?raw$/.exec(id)) { return result[1] ? 'share-i18n' : 'share'; } else if (id.includes('node_modules')) { return 'vendor'; } }, }, }, }, }; });

如果您觉得文章内容对您有用,不妨支持我创作更多有价值的分享:


已发布

分类

来自

标签:

评论

欢迎吐槽,共同进步

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理