Webpack依赖性管理和Vue.js异步组件加载

时间:2018-12-05 10:56:54

标签: javascript vue.js webpack

我正在尝试实现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以上代码的情况抛出错误

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')) 它可以正常工作,但是当我尝试动态执行此操作时,它会失败。如果可以的话,是否可以进行这种async component注册?

这也不起作用:

const button = '../components/base/base-button.vue'
Vue.component('BaseButton', () => import(button))

仅当我从字面上将字符串正确导入导入功能时。

1 个答案:

答案 0 :(得分:3)

当模块路径是完全动态的时,不能使用

import。参见docs

  

完全动态的语句(例如import(foo))将失败,因为webpack至少需要一些文件位置信息。这是因为foo可能是系统或项目中任何文件的任何路径。 import()必须至少包含有关模块位置的某些信息,因此捆绑可以限制为特定目录或文件集。

您没有为mode指定require.context参数,该参数默认为“ sync”;这意味着所有匹配的模块将立即加载。您想使用“ lazy”,它为每个模块生成一个可延迟加载的块。

未经测试,但我想它会是这样的:

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));
});