Skip to content

Post processing CommonJS modules

sebez edited this page Nov 20, 2014 · 1 revision

Motivation

In order to add cross-cutting concerns behaviours to an application components, we need to access the CommonJS modules list once they are defined.

This allows to change the behaviour of the modules from the outside of their definition, keeping a clean separation of concerns between specific implementation and generic cross-cutting concerns, like logging, monitoring, security, exception handling, etc.

Context

We need to use a module to change the modules beahviour.

In CommonsJS, the module list is not available inside a module definition function, so we can't directly use it in a module.

Solution

In the global require variable published by CommonJS, we can call list() to obtains the module list.

This is visible in the code generated by brunch plugins when compiling the javascript modules, which is similar to this brunch plugin.

To make the module list available to a CommonJS module, we need to inject it from the outside via an init function.

In the SPA main html page :

    <script>
        (function () {
            require('initialize').init(
                require.list()
            );
        })();
    </script>

We call the init method of the initialize module, and inject the require.list() result as a parameter.

We can then use the list in the module definition.

For instance, we can display the list of the modules in the console :

var initialize = {

        init: function init(moduleList) {
            $(function () {
                
                console.debug("Defined modules : " + moduleList.length);
                _.each(moduleList, function (moduleName) {
                    console.debug("Module " + moduleName);
                });

                /* ... */

                /* Initialize application. */
                application.initialize();
            });
        }
    };

    module.exports = initialize;

Extract of the result in chrome console :

Defined modules : 68
Module application
Module aspects/index
Module config/domain/index
Module config/entityDefinition/index
Module config/entityDefinition/index/referentiel
Module config/entityDefinition/message
Module config/index
Module config/initializer/ajax_initializer
Module config/initializer/autocomplete_initializer
Module config/initializer/backbone_plugin_initializer
Module config/initializer/fmk_initializer
Module config/initializer/i18n_initializer
Module config/initializer/jquery_plugin_initializer
Module config/initializer/logger_initializer
...

Once we have access to the modules list, we can require them to change their behaviour.

Clone this wiki locally