◆ 最後に実行してくれるので DOM 構築後に実行するためのリスナ登録不要
◆ defer では無理だったインラインコードでもあとで実行される
◆ head/body タグ省略時で body の最後に script タグを書くのが難しい場合にも助かる

ただのスクリプトなら type を書かなくていいので わざわざ書くのは面倒です
だけど type="module" を書いておくべきだと思います

module

まず機能面で module を使うには書いておかないとダメです
import/export を使うには module であることが必須です

実行タイミング

また type="module" のスクリプトの実行は最後に行われます

head タグに書くと body 要素がないから body の最後に書く なんてことを考えなくてすみます
特に head/body タグを省略して body の中身がなにもない場合は head タグ中に script が書かれてると扱われて body がないケースがあります

<!doctype html>

<script>console.log(1)</script>

この script は head タグ中として処理され 実行中に body タグはありません

<!doctype html>

<body><script>console.log(1)</script></body>

このために body で囲むか

<!doctype html>

<div></div>
<script>console.log(1)</script>

body 中にしか配置できないタグを先に書いておく必要があります
必要なタグならこれでいいですが body タグ内で script タグを実行させるためにだけにいらないものを配置するのは良い方法とは言いづらいです

head タグ中で実行されても window.onload などリスナ登録すればいいだけとは思いますがそれも毎回になると面倒です
しなくていいなら せずに済ませたいものです

script タグでも defer を設定することで DOM 構築後に実行することは可能でした
しかしそれは別 URL からロードするための機能なので script タグ中に JavaScript を書いている場合には意味がなく即実行されました

module の場合はインラインスクリプトであっても DOM 構築後に実行してくれます

<!doctype html>

<script type="module">document.body.innerHTML = "1"</script>

これは問題なく動きます

スコープ

module の場合はスクリプトはグローバル空間で実行されません
トップレベルに変数を作ってもグローバル変数にはなりません

グローバルに起きたくないから無名関数の即時実行をする ということは不要になります

と言っても window のプロパティへ代入すればグローバル変数を作ったり編集したりすることは可能です

デメリット

一番感じるデメリットは type="module" 書くのが面倒 これだと思います

あとは強制 strict モード
あまり大きな違いはないものの 一部のワードがキーワードになって変数に使えなかったり いらない引数を捨てるために _ を 2 回引数名に使うとエラーになったりときどき鬱陶しく感じます

スコープの違いがデメリットになる場合もあります
グローバルにおいても困らないものはグローバルにあるほうがデバッグ時には楽です
コード自体をいじらなくとも devtools のコンソールだけでだいたいのことはできてしまいます

しかし グローバルから何も参照できない状態だとコンソールでできることも限られます
ライブラリがモジュール中から import される場合 自分でグローバルに公開しない限り グローバル空間で実行されるコンソールから参照できません
ちょっと動き試すときにも関数が使えなかったり デバッグ時の手間はけっこう増えます
例えば jQuery 使ってる人だと コンソールから $ で jQuery 使うことがあると思いますが グローバル変数じゃなくなるのでコンソールでは $ が使えなくなるというようなものです

devtools のコンソールでコードを実行空間をモジュール単位で変更できるようになればいいのですけどね