Regarding the missing "feature switch". Depending what you mean with that, but with proxy components you can pretty much achieve it quite easily.
/apps/myapp/proxy-components/component/v1/component.html
/apps/myapp/proxy-components/component/v2/component.html
/apps/myapp/proxy-components/component/v3/component.html
and then
/apps/myapp/components/component/ (with the resourceSuperType being either the v1, v2 or v3 component).
That's the approach suggested by the AEM Core Components, and it helps you to decouple the latest development version of components from the ones used by authors.
Splitting up the deployment into multiple packages which can evolve independently is a good approach. Of course should try to keep the dependencies very small, which is not always easy to make (assume that you have a complex JS/CSS frontend, which has some explicit but more implicit dependencies).
But at this point you should have automated testing in place, which should be able to provide the test-coverage of the package versions you want to deploy.
On an OSGI bundle level, the situation is different. Here you should focus in building internal APIs which you can version. Splitting API and implementation and applying semantic versioning is crucial here. Architect your APIs and don't let it just happen (as I have seen on many projects ...)
Jörg