The way I have things now is that I have prototypes. A prototype has a name, a list of filled-out Components, and an optional parent prototype (so I have prototype inheritance, so to speak). From a prototype I can instantiate an entity (and that entity's Components will be cloned from the prototype's Components).
Talking about that, what do you say to game content? Like levels, etc...? What would you rather prefer, storing things like unit and tower "prototypes" as entity/components, or rather as seperate structs? As for the game level itself, I think it makes most sense to store that in entity/component - format, but I'm a bit unsure which would turn out to be the most usefull in the end (especially thinking about possibly larger projects):
In one of my projects (the smaller one), I have something like your "direct approach" above. Basically a text file that defines the level. It basically has a list of prototype names followed by relevant some values for them. It doesn't map at all to Components, so it isn't really a scalable solution, but it works for this small game. Each time I add a new Component, or some new functionality to an existing component, I also have to go change the level load/save code to figure out how I will express the new concept in the text file. So it's not a great solution, but it does allow me to make tweaks directly to the text file if I want (and I have some extra info in there that doesn't correspond to any entity/component).
In my other project (a much larger, open world type game), I have a complete in-game editor. The "levels" are saved in a non-readable binary format, which is basically just a dump of all the entities and their components. Then I simply reconstitute the level by deserializing it. I still use prototypes heavily (e.g. from within the in-game editor, for instance to create a new NPC or something). Prototypes also come into play when serializing/deserializing. For an entity, I don't serialize Components that are identical to one in its prototype (so each entity keeps track of the prototype it came from). This saves a bunch of space.
So, other than for static game content (terrain, rivers, etc...), the game world is basically just an initial save game (indistinguishable, actually). I don't know if this will turn out to be a good solution (the game isn't very far on), but it does make things easy. I do obviously have to be cognizant of keeping the "save game" working as I make changes to components during development. So each Component needs to be versioned.