Search code examples
javascriptangularjsbabeljses6-module-loader

Exporting angularjs module as es6 module


You are supposed to wrap angularjs modules in an IIFE according to the styleguide, which we use

https://github.com/johnpapa/angular-styleguide/tree/master/a1#iife

my-dir.js

(function() {
    'use strict';

    angular
        .module('my.dir', [])
        .controller('MyDirController', MyDirController),
        .directive('my-dir', MyDirDirective);

    function MyDirController() {

    }

    function MyDirDirective() {
        return {
            restrict: 'E',
            controller: MyDirController
        }
    }
})();

app.js

(function() {
    'use strict';
    angular
        .module('app', ['my.dir'])
})();

But as we are now using webpack to bundle es6 modules. How are we supposed to use this IIFE and export? We can't do export default angular.module('my-dir', []) as export must be a top-level command. Also, we should just be returning a string of the name of the module? So that it can be included as a require in the app module. What is best practice?

This works, but you have to retype the module name, and seems a bit messy having the export outside the IIFE (Which I assume has to be the case)

(function() {
    angular.module('my.dir', [])
        .controller('MyDirController', MyDirController)
        .directive('my-dir', MyDirDirective);

    function MyDirDirective(appPath) {
        return {
            restrict: 'E',
            scope: {},
            bindToController: {},
            controllerAs: '$ctrl',
            template: '<div ng-bind="$ctrl.msg"></div>',
            controller: MyDirController
        };
    }

    function MyDirController() {
        var self = this;
        self.msg = "Hello World";
    }
})();
export default 'my.dir'

Solution

  • After moving to modules, the new structure has become

    app.js

    import myDir from './my-dir.js'
    
    angular.module('app', [myDir.name]);
    

    my-dir.js

    // import template from './my-dir.html'; // Can use this with template property
    
    export default angular.module('my.dir', [])
        .controller('MyDirController', MyDirController)
        .directive('my-dir', MyDirDirective);
    
    function MyDirDirective() {
        return {
            restrict: 'E',
            scope: true,
            bindToController: {},
            controllerAs: '$ctrl',
            template: '<div ng-bind="$ctrl.msg"></div>',
            controller: MyDirController
        };
    }
    
    function MyDirController() {
        const self = this;  // Not needed if using arrow functions
        self.msg = "Hello World";
    }
    

    The IIFE is no longer needed as now everything is by default a module if always using any kind of javascript module system