异步加载模块通过knockoutjs与webpack

时间:2017-04-15 10:03:59

标签: knockout.js webpack webpack-2

我目前正在使用webpack设置knockoutjs项目。我想要实现的主要方面之一是延迟加载bundle。虽然我已经能够实现代码分割,但它目前要求应用程序专门包含此代码,我想摆脱这个特定代码,因为我认为knockoutjs已经带有必要的基础设施。

在应用设置期间,组件在knockoutjs中注册,如下所示:

ko.components.register('form-page', { require: 'components/form-page/form' });

Knockout将使用async require加载引用的模块,仅使用组件表单页面。

使用我的webpack设置,这将失败,因为

  • Webpack未检测到对components / form-page / form
  • 的依赖
  • 模块名称被webpack损坏为一些短标识符,因此组件/表单页面/表单在运行时未知

理想情况下,我会让webpack将其检测为async模块依赖项,但在第一步中,在保留模块名称的同时声明我想要在webpack配置中可用的模块就足够了,让ko需要它的依赖项因为它需要它。

知道如何做到这一点?

2 个答案:

答案 0 :(得分:0)

简短的回答是我还没有找到一种方法来动态地执行此操作。 这是另一种方法。

<强>的src /组件/输入/ Input.js

示例组件

import ko from 'knockout';
import FormComponent from '../../../classes/FormComponent';

class InputControl extends FormComponent {
  constructor(params) {
    super(params);
  }
}

ko.components.register('input-control', {
  viewModel: InputControl,
  template: require('./Input.html')
})

<强>的src /组件/ index.js

使用webpack内置的东西循环遍历每个组件文件夹来获取ko.components.register

const components = require.context('./', true, /\.js$/);

components.keys().forEach(function(component) {
  const componentName = component.substr(2);
  require('./' + componentName);
});

<强>的src / app.js

组件在applyBindings发生之前注册是很重要的,否则ko不会知道它们。

require("./components");

var PageModel = function() {...}
model = new PageModel();

ko.applyBindings(model);

基本上创建所有组件并一次性包含它们。适用于热模块更换和什么不适用。通常也很轻巧。

答案 1 :(得分:0)

您可以使用自定义组件加载程序https://knockoutjs.com/documentation/component-loaders.html

var myloader =  {
    loadComponent: function (name, componentConfig, callback) {
        if (!componentConfig.import) {
            callback(null);
            return;
        }


        componentConfig.import()
            // Using the defaultLoader so we can support the different component configs knockout supports by default
            .then(config => ko.components.defaultLoader.loadComponent(name, config, callback));
    }
}

并将其添加到淘汰赛装载机中。使用unshift,这是第一个加载程序成功

ko.components.loaders.unshift(myloader);

现在您的组件注册已更改为

ko.components.register('form-page', { import: () => import(/* webpackChunkName: "form-page" */'components/form-page/form') });

这利用了Webpack的lazy loading的优势。尽管请注意,动态导入需要一些其他的babel插件。

webpackChunkName注释告诉webpack如何命名其输出的js文件。