angularangularjswebpack

Hybrid angularjs/angular app broken due to angular 13+ removal of deployURL


UPDATED 7/6/2023 as I believe I have determined the issue is due to the hybrid nature of my application and not just upgrading angular as I previously assumed.

I have a hybrid angular/angularjs app that currently builds all the client files into a /client/ directory.
All calls outside of that directory are handled by my back end. My current configuration uses deployUrl='/client/' to prefix all asset requests appropriately for that directory.

I am upgrading angular, and so deployUrl is now deprecated/removed, and I am trying to figure out how to make this continue to work.

I have tried setting my angular.json baseHref='/client/', like recommended here:
What is best way to go about replacing 'deployUrl' in angular.json for v13?

and that works fine for the assets, but it breaks the angularjs portion of the app. In particular, when angularjs $location attempts to parse the initial url, it gives an error. Ie, Assume the initial url is https:/example.com/home, when ajs tries to parse it, it throws this error:

Error: [$location:ipthprfx] Invalid url "https://example.com/home", missing path prefix "https://example.com/client/".

Which links to this error in the angular docs.

Apparently angularjs doesn't like the baseHref, which wasn't previously a problem as deployUrl didn't require a baseHref. However, now that I can't use it, I can't seem to do the workaround of setting baseHref either, since angularjs doesn't work well with it.

Any ideas how I can set up/build my app so that both the angular and angularjs portions work? (Yes, I would love to get rid of all the angularjs code, and we are doing so slowly, but we still have a lot of legacy code in ajs).


Solution

  • This is how I solved the problem. I'm sharing this in case anyone else finds it helpful. However, I should note that I can't fully recommend this solution, as $browser is technically a private AngularJS object, meaning it's not intended to be modified or adjusted, and it's also undocumented. That said, the solution worked for us, and we're comfortable with the potential risk of AngularJS changing something internally and causing issues, especially since there aren't many changes happening to AngularJS these days.

    I essentially overrode the default $browser.baseHref() method to return '/' instead of the value specified via <base href="..."/> in the index.html. This allowed me to still define a baseHref during the Angular build so that all client assets, resources, and scripts are located correctly, while preventing the AngularJS $location behavior and UI router from being confused by it.

    I added this to the app config section of my AngularJS bootstrap:

    $provide.decorator('$browser', ['$delegate', ($delegate) => {
    
      $delegate.baseHref = function replacementBaseHref() {
        return '/';
      };
    
      return $delegate;
    }]);