> the technical and organisational measures you need in place to do it safely are an extra step you need to take whereas with microservices they're built in
They aren't built in, it's just that the need for them is impossible to ignore. Developers (and management) can't help but recognize and respect modularity in microservices because the separation of services and the APIs between them make the modularity obvious. When the separation between modules only exists in code, and even then only when seen through the eyes of someone who understands the modular architecture of the codebase, it is easily ignored, inevitably forgotten, and might as well not exist at all.
Module is not just code in a separate file. Litmus test: if you cannot have two modules be written in separate languages - you don't have modules. M
If all modules have to be deployed using the same build even though different build of the modules would have been API compatible - you don't have modules.
That sounds way too strict to me. A C++ app might use the C++ ABI to communicate with its modules, which would preclude writing them in any other language without jumping through too many hoops. But that's an ABI constraint and says nothing about the actual modularity of the application.
IMO a module is defined as something that has a self-contained API, and versioning rules for that API if the module is evolving.
They aren't built in, it's just that the need for them is impossible to ignore. Developers (and management) can't help but recognize and respect modularity in microservices because the separation of services and the APIs between them make the modularity obvious. When the separation between modules only exists in code, and even then only when seen through the eyes of someone who understands the modular architecture of the codebase, it is easily ignored, inevitably forgotten, and might as well not exist at all.