angularjstypescriptunit-testingangularjs-moduleangularjs-ngmock

Circular dependencies on angular modules using typescript


I'm facing this issue where i have 2 angular 1.5 modules that depend on each other, which is fine by angularjs, but when i import them using typescript & webpack, i get circular typescript-module dependencies and the modules are not loaded properly. I dont have circular dependencies in the angular services between the modules, therefor there should be no problem depending the angular-modules on each other.

//first.module.ts
import {SecondModule} from "second.module.ts";
let FirstModule = angular.module("firstModule",[SecondModule.name]);
export {FirstModule};

//second.module.ts
import {FirstModule} from "first.module.ts";
let SecondModule = angular.module("secondModule",[FirstModule.name]);
export {SecondModule};

In the example above, i get "cannot get 'name' of undefined" on the last line, since FirstModule is not exported yet.

One solution i saw online is just to not define the SecondModule as a dependency of FirstModule, but make them both dependencies of a parent module (my main app module), the problem is that i cant mock FirstModule using ngMock for unit testing - since it does not register SecondModule as a dependent sub-module. so i have to mock my whole main app which is big and messy.

Other solution i saw was to wrap the angular-modules with typescript classes, and put the angular module creation in the constructor of this class, so i can control when the module is created, but then i have to refactor my whole application to create objects of those wrapped modules, and i have no idea how will this affect writing unit tests using ngMock.

Are there any best practices for this situation?

Thanks!


Solution

  • You can export a string constant as the first thing in the file

    //first.module.ts
    export const prefixFirstModule = "prefixFirstModule";
    import {prefixSecondModule} from "second.module";
    export const FirstModule = angular.module(prefixFirstModule,[prefixSecondModule]);
    
    //second.module.ts
    export const prefixSecondModule = "prefixSecondModule";
    import {prefixFirstModule} from "first.module";
    export const SecondModule = angular.module(prefixSecondModule,[prefixFirstModule]);
    

    It's a bit of a pain, but as far as I'm aware it's the only way round the problem with the same support for tree shaking etc with your current module structure.