Are there technical solutions you've seen/implemented/read about to solve these issues?There is no silver bullet but from my experience these things let you to maintain (and modify) project more easily:
1. Separation of concerns
We have an incomplete schema for our API, it's mostly stable but some changes will happen
It's better to create some specialized service/module to connect with backend API end-points than have something like
$.get('/get/user/' + id)
spread across the project. If you follow SoC, when backend API changes you have to update only one file.
2. Modularize
If you have proper modularization (achieved by proper design or/and incremental refactoring) you can make global changes very quickly (you have to update just one module to apply changes everywhere) but you can also make local changes also quickly (you just have to decide what submodules you have to use in your parent module). If you treat project not as a monolith but as a interconnected set of decoupled components/modules developing is like building with Lego bricks.
3. Refactor constantly
Is there some code that can be written better? Refactor. Avoid unnecessary complexity. Simple and succinct code is easier to maintain and modify. And make your code reusable.
4. File/directory structure based on components rather than filetype.
I never understood why so many people create directories like “controllers”, “directives”, javascripts”, “stylesheets”. The truth is that if you work on some part of your code you will usually edit all of these files. And you end up jumping over 3-4 different directories to make very small change. Directory structure based on components / views / modules / other logical part of project / seems to be better than put 10 files in one directory only because they all have .js or .css extension.
5. keep third part library code separate (if possible).
For example you need to inject some third party slider/carousel/chart etc. on one of sub-sites. It's better to make directive for this and insert 1 line of directive <my-slider> than just throw some 20 lines of code in your HTML and JS. Imagine that you need to change library X to library Y. Wrappers/adapters add some additional layer of complexity but I think that outcome is still positive in many cases.