Search code examples
angularjscodemirroroclazyload

`serie: true` cannot ensure loading order of modules


I want to load CodeMirror by ocLazyLoad. Since xml.min.js, htmlmixed.min.js, css.min.js, etc. all need codemirror.min.js to be loaded before them. I try to use serie: true to make sure the loading order:

$ocLazyLoadProvider.config({
    debug: true,
    serie: true,
    modules: [{ 
        name : 'codeMirror1', 
        files: [
            "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/codemirror.min.css",
            "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/codemirror.min.js"
    ]},{
        name : 'codeMirror2',
        files: [
            "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/xml/xml.min.js",
            "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/htmlmixed/htmlmixed.min.js",
            "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/css/css.min.js",
            "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/javascript/javascript.min.js",
            "https://cdnjs.cloudflare.com/ajax/libs/angular-ui-codemirror/0.3.0/ui-codemirror.min.js"
    ]}]
});

$stateProvider
    .state('site', {
        abstract: true,
        template: '<ui-view/>',
        resolve: {
            loadSiteCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
                return $ocLazyLoad.load(['codeMirror1', 'codeMirror2'])
            }]
        },
    })

However, the above code still returns:

angular.js:13920 ocLazyLoad.fileLoaded https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/codemirror.min.css
xml.min.js:1 Uncaught ReferenceError: CodeMirror is not defined
    at xml.min.js:1
    at xml.min.js:1
(anonymous) @ xml.min.js:1
(anonymous) @ xml.min.js:1
angular.js:13920 ocLazyLoad.fileLoaded https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/xml/xml.min.js
htmlmixed.min.js:1 Uncaught ReferenceError: CodeMirror is not defined
    at htmlmixed.min.js:1
    at htmlmixed.min.js:1
(anonymous) @ htmlmixed.min.js:1
(anonymous) @ htmlmixed.min.js:1
angular.js:13920 ocLazyLoad.fileLoaded https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/htmlmixed/htmlmixed.min.js
css.min.js:1 Uncaught ReferenceError: CodeMirror is not defined
    at css.min.js:1
    at css.min.js:1
(anonymous) @ css.min.js:1
(anonymous) @ css.min.js:1
angular.js:13920 ocLazyLoad.fileLoaded https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/css/css.min.js
javascript.min.js:1 Uncaught ReferenceError: CodeMirror is not defined
    at javascript.min.js:1
    at javascript.min.js:1
(anonymous) @ javascript.min.js:1
(anonymous) @ javascript.min.js:1
angular.js:13920 ocLazyLoad.fileLoaded https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/javascript/javascript.min.js
angular.js:13920 ocLazyLoad.fileLoaded https://cdnjs.cloudflare.com/ajax/libs/angular-ui-codemirror/0.3.0/ui-codemirror.min.js
angular.js:13920 ocLazyLoad.componentLoaded (3) ["ui.codemirror", "constant", "uiCodemirrorConfig"]
angular.js:13920 ocLazyLoad.componentLoaded (3) ["ui.codemirror", "directive", "uiCodemirror"]
angular.js:13920 ocLazyLoad.moduleLoaded ui.codemirror
angular.js:13920 ocLazyLoad.fileLoaded https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/codemirror.min.js

Does anyone know what's wrong?


Solution

  • The problem is that you are adding the serie option to the provider configuration object, which is ignored since it will get the config for each module and load them in parallel anyways. Basically that option needs to be present on every module which scripts need to be loaded in order.

    A quick solution for you is to make use of promises to make sure modules are loaded in order. Since the load() call returns a promise, we can execute a second load after that:

    $ocLazyLoadProvider.config({
        debug: true,
        modules: [{ 
            name : 'codeMirror1', 
            files: [
                "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/codemirror.min.css",
                "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/codemirror.min.js"
        ]},{
            name : 'codeMirror2',
            files: [
                "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/xml/xml.min.js",
                "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.36.0/mode/htmlmixed/htmlmixed.min.js",
                ...
        ]}]
    });
    
    ...
    loadSiteCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
        return $ocLazyLoad.load(['codeMirror1']).then(function() {
          return $ocLazyLoad.load(['codeMirror2'])
        });
    }]
    ...
    

    Check this plunker for a working example of this.

    Alternatively, since CodeMirror supports module loaders and ocLazyLoad plays nicely with requireJS you might be interested on trying it. You would set requireJS as the loader for modules on ocLazyLoad and, when loading the modules that depend on CodeMirror, it would make sure they were already loaded (meaning you wouldn't need to do things in series).