Vue 动态导入即使从未使用过也会被导入 [英] Vue dynamic import is being imported even if it is never used

查看:37
本文介绍了Vue 动态导入即使从未使用过也会被导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个名为 vue-scan-field 的 vue 插件.在之前的版本 (0.1.2) 中,该插件仅支持 vuetify.现在我还想向这个插件添加类星体.所以我决定做的是对组件使用动态导入.例如类星体文件如下所示:

出口默认{成分: {scan_text_field: () =>import('quasar/src/components/input/QInput'),scan_textarea: () =>import('quasar/src/components/input/QInput'),scan_checkbox: () =>import('quasar/src/components/checkbox/QCheckbox'),scan_select: () =>import('quasar/src/components/select/QSelect')},...}

我也有这个用于 vuetify:

出口默认{成分: {scan_text_field: () =>import('vuetify/lib/components/VTextField'),scan_textarea: () =>import('vuetify/lib/components/VTextarea'),scan_checkbox: () =>import('vuetify/lib/components/VCheckbox/VCheckbox'),scan_select: () =>import('vuetify/lib/components/VAutocomplete'),},...}

现在从 npm 下载模块并运行我的类星体项目,我收到这些错误:

未找到这些依赖项:* vuetify/lib/components 在 ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js* vuetify/lib/components/VAutocomplete in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js* ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js 中的 vuetify/lib/components/VCheckbox/VCheckbox* ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js 中的 vuetify/lib/components/VTextField* vuetify/lib/components/VTextarea 在 ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js

现在这可能是因为我的编译器在构建时导入了组件.我不知道我是否可以安全地禁用此功能(我不这么认为).有什么办法可以解决这个问题吗?

NPM 包:https://www.npmjs.com/package/vue-扫描场

Github 页面:https://github.com/jessielaf/vue-scan-field

解决方案

Webpack 中的动态组件(以及一般情况下)之所以能工作,是因为 bundler 在构建时准备了 js 文件(带有组件代码),这些文件在运行时加载(或不加载 ...取决于逻辑)由应用程序.Bundler 无法执行您的代码并评估决定应加载哪个组件的逻辑.它必须为所有可能的结果做好准备.

是的,当然,您的捆绑器会查找并捆绑所有文件,即使它们用于动态导入.

我不知道如何正确设置 Rollup,但我很确定您不希望将任何 Vuetify/Quasar 代码包含在您的库中.此类代码将是重复的,并且可能来自库的用户已经在使用的不同版本的框架!因此,不要使用字符串配置(framework: 'vuetify'),而是将它留给您的用户来传递组件映射(并且可能将示例添加到您的文档中)...

//动态Vue.use(ScanField, { 组件: {scan_text_field: () =>import('quasar/src/components/input/QInput'),scan_textarea: () =>import('quasar/src/components/input/QInput'),scan_checkbox: () =>import('quasar/src/components/checkbox/QCheckbox'),scan_select: () =>import('quasar/src/components/select/QSelect'),scan_date: () =>空值}})//静止的从 'quasar/src/components/input/QInput' 导入 QInputVue.use(ScanField, { 组件: {scan_text_field: QInput,...}})

替代解决方案是使用普通(非动态)导入,但配置 Rollup 以便 Vuetify 和 Quasar 都被视为 peerDependencies(依赖您的 lib 需要但用户负责将其添加/安装到他的项目中) - 请参阅文档

I am building a vue plugin called vue-scan-field. At the previous version (0.1.2) the plugin only supported vuetify. Now I want to also add quasar to this plugin. So what I have decided to do is use dynamic imports for the components. For example the quasar file looks like this:

export default {
  components: {
    scan_text_field: () => import('quasar/src/components/input/QInput'),
    scan_textarea: () => import('quasar/src/components/input/QInput'),
    scan_checkbox: () => import('quasar/src/components/checkbox/QCheckbox'),
    scan_select: () => import('quasar/src/components/select/QSelect')
  },
  ...
}

And I also have this for vuetify:

export default {
  components: {
    scan_text_field: () => import('vuetify/lib/components/VTextField'),
    scan_textarea: () => import('vuetify/lib/components/VTextarea'),
    scan_checkbox: () => import('vuetify/lib/components/VCheckbox/VCheckbox'),
    scan_select: () => import('vuetify/lib/components/VAutocomplete'),
  },
  ...
}

Now download the module from npm and run my quasar project I get these errors:

These dependencies were not found:

* vuetify/lib/components in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
* vuetify/lib/components/VAutocomplete in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
* vuetify/lib/components/VCheckbox/VCheckbox in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
* vuetify/lib/components/VTextField in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
* vuetify/lib/components/VTextarea in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js

Now this can be because maybe my compiler imports the components on build. I don't know if I can safely disable this function (I don't think so). Is there any way to fix this?

NPM Package: https://www.npmjs.com/package/vue-scan-field

Github page: https://github.com/jessielaf/vue-scan-field

解决方案

Dynamic components in Webpack (and in general) work because bundler at build time prepares js files (with component code) which are at runtime loaded (or not ...depending on logic) by the app. Bundler can not execute your code and evaluate the logic which decides which component should be loaded. It must prepare the budle for all possible outcomes.

So yes, of course your bundler looks for and bundle all the files even they are used in dynamic import.

I do not know exactly how to set up Rollup correctly but I'm pretty sure you don't want to include any Vuetify/Quasar code as part of your library. Such code would be duplicate and possibly from different version of the framework the user of your library is already using! So instead of using string configuration (framework: 'vuetify'), leave it to your users to pass the component mapping (and maybe add sample to your docs)...

// dynamic
Vue.use(ScanField, { components: {
    scan_text_field: () => import('quasar/src/components/input/QInput'),
    scan_textarea: () => import('quasar/src/components/input/QInput'),
    scan_checkbox: () => import('quasar/src/components/checkbox/QCheckbox'),
    scan_select: () => import('quasar/src/components/select/QSelect'),
    scan_date: () => null
}})

// static
import QInput from 'quasar/src/components/input/QInput'

Vue.use(ScanField, { components: {
    scan_text_field: QInput,
    ...  
}})

Alternative solution is to use normal (not dynamic) imports, but configure Rollup so that both Vuetify and Quasar are treated as peerDependencies (dependency your lib requires but the user is responsible to add/install it into his project) - see the docs

这篇关于Vue 动态导入即使从未使用过也会被导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆