At first, I felt this was an issue. However, I no longer feel this way: Even in "real", situations can occur which can and do trample crops. This ranges from combat to trespassers taking a "shortcut" through a farm field.
Instead, what I believe the issue is:
Villagers themselves should attempt to avoid actions that would trample crops in normal circumstances. A villager being chased by a zombie, for example, is not going to stop and consider if his running away will trample crops; He is going to run for his life! This is the same reason am iron golem will not wait for a zombie to move to a clear spot before trying to engage the zombie in combat.
There are two immediate "fixes" I can imagine:
(1): Re-arrange generated farms to place the composter either on a block not direcly adjacent to farmland, or lower the composter by one block so villagers will not "jump down" to get off the composter.
And/or (2): Check at an appropriate place in the villager movement code if the next move might trample crops, and choose an alternate route/movement if it might. This way, the check can be skipped if the villager is "fleeing in terror and does not care about crops". It would also affect them if, for example, a tree had spawned in such a way that the leaves become another possible place to "leap down" upon crops.
Requesting to re-open this issue. As of version 1.19 release, this is still an issue. Specific details:
When cloning a region (with move), certain attached items get destroyed and drop as items (or drop their contents, in the case of chests) at the original location. The blocks are still cloned successfully at the target location. That is, for example, chests get re-created at the target with their contents intact – but the contents also drop at the original location. In effect, it creates duplicates. This also happens with doors, beds, etc. They get cloned, but also drop as items in the original location (I assume because the supporting/attached blocks are now destroyed).
My guess is that when the clone command executes, it creates a copy of the cloned blocks at the target location, then destroys the blocks at the source location. But instead of complete destruction, including contents of chests, or attached/supported items, the code treats it like the player destroyed the item. Thus, it executes the code to drop container contents, drop supported/attached items (torches, signs, etc), and so on. This is likely due to block update mechanics.
What should happen is that the code for destroying each block should first check any attached/supported/contained items, and destroy them before destroying itself.
I have also noted similar behavior when using something like "fill ~1 ~1 ~ ~1 ~2 ~ minecraft:oak_door[facing=north,hinge=right]". Instead of properly filling the lower and upper halfs, it fills the incorrect half(s) and immediate drops as an item on the next block update.
This also occurs when "clearing" an area, such as "fill ~ ~ ~ ~8 ~8 ~8 minecraft:air replace". Blocks such as doors, containers, signs, etc, all drop as items when their respective supporting/attached/containing blocks are replaced with air. That is, it acts nearly the same as if the final part of the command was "destroy" instead of "replace".