The biggest project I work on is Amethyst. What they do is divide their project into many local crates with one parent crate, so they have a way of decoupling and keeping every part small and clean. I really like that structure, because it makes sense and in the end, they can release one product without having to release the internal crates.
However, decoupling a game engine is easy and that approach might not be the right way for every project. For example, for my game, I don't have huge independent pieces of software. I have a lot of different systems, running side-by-side on the same ECS. So I use modules in order to decouple my code, which allows a tighter collaboration. For example, I can put the character code into a module and reference stuff in the monster module without making everything pub to the crate somehow. Things, like error handling and logging are easier that way, too.