When were import maps ever necessary? Pretty much every Deno project I've seen uses `deps.ts`. Only reason for import maps most of the time is for vanity module names, unless I'm mistaken.
Isn't that exactly what a deps file does? Technically it's code, but it's serving the same purpose of keeping the URLs in one place. It seems like the only unique function that import maps serve in Deno is so that, instead of importing from "./deps.ts", you're importing from arbitrary identifiers. Which is fine, but I wouldn't say that import maps are ever needed in Deno. It was always possible to organize dependencies in a TS/JS file and import from its module.
The issue is that being code it's turing complete and not parsable by other tooling easily. Having it in a config format (yaml, json, etc.) is easier for other tooling to inspect.
One of the reasons behind ES module syntax was to make imports/exports statically analyzable. Sure, it's technically simpler and more portable to use JSON, but a tool that fits all more use cases isn't necessarily the best tool for the most common use cases. Given that all import maps are just maps of names to URLs, I see no reason why a JS module couldn't be trivially parsed to inspect what URLs are being imported and what identifiers are being exported.
This doesn't take into account how much tooling is not written in JS. There are lots of ecosystem tools implemented in rust, C++, bash, python, etc. that parse dependencies for things like CVE checking, version bumping, dependency graph analysis, etc. that don't want to have to implement a full JS runtime to get the list of deps. Python has requirements.txt and pyproject.toml, Rust has config.toml, etc. many languages keep their project metadata and dependencies in config formats instead of code for good reasons.