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

标签 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上面代码的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. The import() 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/

相关文章:

css - Vue - 更改作用域 <style> 中的内容?

javascript - 正则表达式从缩小中排除 npm 库

javascript - 如何托管创建一个简单的登录门户,可供不同用户通过同一本地网络访问?

javascript - Onclick 刷新然后 href 使用相同的点击?

javascript - 自定义函数中的回调函数

javascript - jquery 将点击事件传递给 onclick 属性

javascript - 对话框打开时在对话框内设置焦点文本字段

vue.js - 在 nuxt.js 中添加 cdn 样式表和 javascript

javascript - Webpack copyFiles将文件从子目录复制到主目录

reactjs - Webpack - 类型错误 : $ is not a function