我正在尝试实现 Vue.js 动态 async component
注册。 This video给了我工作得很好的代码,但它加载了所有模块,即使它们没有被使用。
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
// Require in a base component context
const requireComponent = require.context(
'../components/base', false, /base-[\w-]+\.vue$/,
)
requireComponent.keys().forEach(fileName => {
// Get component config
const componentConfig = requireComponent(fileName)
// Get PascalCase name of component
const componentName = upperFirst(
camelCase(fileName.replace(/^\.\//,
'').replace(/\.\w+$/,
'')),
)
// Register component globally
Vue.component(componentName, componentConfig.default || componentConfig)
})
我试图实现的是创建异步组件。像这样
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
// Require in a base component context
const requireComponent = require.context(
'../components/base', false, /base-[\w-]+\.vue$/,
)
requireComponent.keys().forEach(fileName => {
const componentPath = fileName.replace('./', '../components/base/');
// Get PascalCase name of component
const componentName = upperFirst(
camelCase(fileName.replace(/^\.\//,
'').replace(/\.\w+$/,
'')),
)
// Register component globally
Vue.component(componentName, () => import(componentPath))
})
如果vue上面代码的case抛出错误
vue.esm.js:591 [Vue warn]: Failed to resolve async component: function () {
return __webpack_require__("./lib lazy recursive")(componentPath);
}
Reason: Error: Cannot find module '../components/base/base-button.vue'
如果我手动写下 Vue.component('BaseButton', () => import('../components/base/base-button.vue'))
它可以正常工作,但是当我尝试动态地执行此操作时,它会失败。如果可以,是否可以进行这样的异步组件
注册?
这也行不通:
const button = '../components/base/base-button.vue'
Vue.component('BaseButton', () => import(button))
仅当我从字面上正确地将字符串放入导入函数时。
最佳答案
import
不能在模块路径完全动态时使用。查看docs :
Fully dynamic statements, such as
import(foo)
, will fail because webpack requires at least some file location information. This is because foo could potentially be any path to any file in your system or project. Theimport()
must contain at least some information about where the module is located, so bundling can be limited to a specific directory or set of files.
您没有为默认为“sync”的require.context
指定mode
参数;这意味着所有匹配的模块将立即加载。您想使用“惰性”,它为每个模块生成一个可延迟加载的 block 。
未经测试,但我想它会是这样的:
const context = require.context('../components/base', false, /base-[\w-]+\.vue$/, 'lazy');
context.keys().forEach(fileName => {
const componentPath = fileName.replace('./', '../components/base/');
// Get PascalCase name of component
const componentName = upperFirst(
camelCase(fileName.replace(/^\.\//,
'').replace(/\.\w+$/,
'')),
);
// Register component globally
Vue.component(componentName, () => context(fileName));
});
关于javascript - Webpack 依赖管理和 Vue.js 异步组件加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53630683/