I'm working on the hybrid angular web application. We did update the angular version and released it to our QA environment, everything went fine until we tried to release it to our other QA environment which is using docker. Angular build failed with the following error, indicating that two type definition packages are exporting the same types.

In this blog post, I will walk through the thought process that helped me debug this problem.

Locally on our windows laptop build works fine, azure windows pipelines work fine, but docker builds fail everywhere.

#12 87.41
#12 87.41 ERROR in node_modules/@types/googlemaps/reference/map.d.ts:1:1 - error TS6200: Definitions of the following identifiers conflict with those in another file: BicyclingLayer, Map, HYBRID, ROADMAP, SATELLITE, TERRAIN, MapTypeRegistry, TrafficLayer, TransitLayer
#12 87.41
#12 87.41 1 declare namespace google.maps {
#12 87.41   ~~~~~~~
#12 87.41
#12 87.41   node_modules/@types/google.maps/index.d.ts:18:1
#12 87.41     18 declare namespace google.maps {

From the error above we can see that there are two packages @types/googlemaps and @types/google.maps which provide the same type of definitions.

Thought process

We upgraded the angular major version, this resulted in a large portion of our other packages being upgraded as well. The first thought was that some have a new dependency, but this doesn't explain why our windows build agents can build successfully. When building on windows @types/google.maps package is not present in node_modules directory.

After some searching in the project, installed packages and online, still nothing. The next step that came to my mind is to check the docker file system for this mysterious package. With a few commands, I had docker up and running with the project inside it.

 docker build . -t ng-debug-build
 
 docker run -it ng-debug-build /bin/ash

This showed that docker indeed had @types/google.maps installed. Can npm packages have dependencies based on the operating system? New google quest was born and search continued. The answer is - no.

Well if we don't have it on windows build, we don't have it in our package.json, it must be installed by someone. Using bisection search on dependencies and devDependencies I was able to find that @typesmarkerclusterer package was installing additional dependencies when building project in docker.

I'm still not sure why we don't have issues on our windows azure build agent, it might be that we have some sort of cache that I'm not aware of.

The issue was that @types/google-map package changed its dependency. Our angular application has @types/googlemaps but when this package changed its dependence conflicts arose. @types/markerclustererplus has wildcard major version dependency on @types/google-maps, and this situation is a perfect example of why you shouldn't do that!

Solution

Since we are using yarn we override internal package versions. We simply rolled back to @types/google-maps version that uses same @types/googlemaps dependency.

    "resolutions": {
        "@types/markerclustererplus/**/@types/google-maps": "3.2.1"
    }

This is a perfect example demonstrating how careful you should be about versions that you specify in dependencies. Overall I'm pretty happy with this bug that we had, it led to great examples of bad code, helped me learn new things, such as resolutions, and showed that problem solving has room for improvement, since some steps took a bit longer than anticipated.