today a question was raised here and I don\'t have an evident answer.
Assume that we concatenate and minify all resource files (CSS and Javascript) and declare them
I've getting through this same problem. My solution which is opiniated and may not respond to your criterias :
When i package my front-app and my server-app, I share a configuration file containing the current version of the front-app.
Front side : 75% of my routes change implicitely call a Webservice (route change resolve). SO each time I call my server I include a custom HTTP header (or a GET/POST param) containing the client version of the front-app.
Server side : I compare the front-app version (the one in the browser of the user, loaded last time user refreshed/loaded the SPA) with the front-app version of the shared configuration file :
Then front side: I added a response Interceptor that intercepts any 418 error code and do a force-refresh of the whole app
That's it. Basically the event that "check" if the front-app version is the latest is a route change (that calls a WS via ajax). But you could add some infinite $interval calling a dedicated WS each 5 minutes or so... I can add some code if needed.
Hope this helps ;)