按需[延迟加载]模块的模式



在我的应用程序中,我需要加载模块,而不是在初始化阶段(通过在./modules/modules中枚举它们),而是在稍后根据某些条件(例如用户授权结果)按需加载。想象一下,我想为用户A提供计算器模块,为用户B设置文本编辑器模块。

为了简单起见,让我们以boilerplatejs为例应用程序,并假设sampleModule1sampleModule2将按需加载。

因此,我从src\modules\modules.js:中的初始加载序列中删除了模块

    return [
        require('./baseModule/module'),
        /*require('./sampleModule1/module'),
        require('./sampleModule2/module')*/
    ];

并将控件添加到摘要页面(src\modules\baseModules\landingPage\view.html)以按需加载它们:

<div>
    Congratulations! You are one step closer to creating your next large scale Javascript application!
</div>
<div>
    <select id="ModuleLoader">
        <option value="">Select module to load...</option>
        <option value="./modules/sampleModule1/module">sampleModule1</option>
        <option value="./modules/sampleModule2/module">sampleModule2</option>
    </select>
</div>

然后我修补src\modules\baseModules\module.js,将上下文传递给LandingPageComponent(由于某些原因,它不在原始源代码中):

        controller.addRoutes({
            "/" : new LandingPageComponent(context)
        });

最后将加载代码添加到src\modules\baseModules\landingPage\component.js:

            $('#ModuleLoader').on('change', function(){
                require([this.value], function(mod){
                    moduleContext.loadChildContexts([mod]);
                    alert('Module enabled. Use can now use it.');
                });
            });

这似乎奏效了,但这是最好的方法吗?

它是否正确处理上下文加载?

如何防止两次加载同一模块?

这里有聪明的思维。。过去几天,我也在努力改进BoilerplateJS,以将模块作为插件进行懒惰加载。我做了类似的事情,你可以访问POC代码:

https://github.com/hasith/boilerplatejs

在我做的POC中,我试图同时实现"延迟加载"+"可配置ui"。

  • 每个屏幕(称为应用程序)都是放置在布局上的组件(插件)的集合。这些应用程序定义只是从服务器API动态返回的JSON对象,或者静态定义为JSON文件(就像在POC中一样)。在POC中,应用程序定义存储在"/server/application"中。

  • 现在可以按照约定动态调用这些应用程序。例如,"/###/运输应用程序"将在"/server/application"中查找具有相同名称的应用程序定义。

  • 应用程序加载是通过我在"/modules/baseModule/appShell"中的一个新组件进行的。任何以"/###/"开头的内容都将被路由到此组件,然后它将尝试按约定从"/server/application"文件夹加载应用程序定义

  • 当"appShell"接收到应用程序定义(作为JSON)时,它也会尝试动态加载其中定义的组件(插件)。这些可插入组件放置在"src/plugins"中,也将按照约定加载。

示例应用程序定义如下所示:

{
    "application-id" : "2434",
    "application-name" : "Order Application",
    "application-layout" : "dummy-layout.css",
    "components" : [    
        {
            "comp-name" : "OrderDetails",
            "layout-position" : "top-middle"
        },
        {
            "comp-name" : "ShippingDetails",
            "layout-position" : "bottom-middle"
        }
    ]
}

该方法的优点如下:

  • 应用程序接口是组件驱动的,可在运行时进行配置
  • 根据用户角色等,可能会向用户发送不同的应用程序定义(后端逻辑)
  • 可以通过组合现有组件来动态创建应用程序
  • "框架"中不需要静态代码更改来添加新的应用程序或组件,因为加载是基于约定的

这些都是非常初步的想法。感谢您的反馈!

您可以通过对更改事件使用命名函数,并在执行该函数后解除绑定,来防止模块的多次加载。

相关内容

  • 没有找到相关文章

最新更新