Your coworker's approach is actually quite reasonable and pragmatic.
For the sake of completeness I'll point out that putting too much in ready()
in the external JS file is a mistake. I started doing this once and ended up with a page load time of 500-1000ms with all this unnecessary JS code that was being executed. The external JS file(s) should be for declaring functions. The page itself should declare which of those things to actually run. This combines the best of minimal code execution and maximises caching (since the JS file is the same for all your pages).
At the top of the page you don't know what modules/components will be included in the document unless you declare it there as well, which (imho) is a worse case of repeating yourself.
The ideal approach would be some sort of multi-pass templating process that would allow included modules/components to trigger code that needs to be run and your template processor will combine all that and put it at the top of the page. I've actually written systems like this and it is quite doable but it's also more tedious.
You say it's messy but the other side of that coin is that when you look at a page it's easy to determine what code belongs to which module/component because they're adjacent. If you had a big blob of JS at the top of the page, how do you know what relates to what?
As long as you don't end up with dozens of script blocks I think your cowowrker's approach is fine. Any alternative needs to be just as clear and not execute more code than necessary.