`<script type=importmap>` is always wrongly placed closely before `<script type=module>` when building
Describe the bug
when using transformIndexHtml to move the <script type=module> to body, vite always place the importmap closely before the "module" on build, but all the generated <link rel=modulepreload> still be in <head> and be resolved before importmap, which result in an error An import map is added after module script load was triggered , the modulepreload scripts fail too
the index.html template
after vite build the final index.html
Reproduction
https://stackblitz.com/edit/vitejs-vite-kp7bg1e8?file=index.html,vite.config.ts,src%2Fsum.ts,dist%2Findex.html&terminal=dev
Steps to reproduce
run npm run build or yarn build and the dist/index.html be like the pic below.
when it runs, the modulepreload be resolved before the importmap , so we get an error An import map is added after module script load was triggered, the sum.js also fails
System Info
System:
OS: Windows 11 10.0.26100
CPU: (18) x64 Intel(R) Core(TM) Ultra 5 125H
Memory: 19.33 GB / 31.61 GB
Binaries:
Node: 24.5.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.22 - C:\Program Files\nodejs\yarn.CMD
npm: 11.5.1 - C:\Program Files\nodejs\npm.CMD
Browsers:
Internet Explorer: 11.0.26100.1882
Used Package Manager
npm
Logs
No response
Validations
- [x] Follow our Code of Conduct
- [x] Read the Contributing Guidelines.
- [x] Read the docs.
- [x] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [x] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- [x] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [x] The provided reproduction is a minimal reproducible example of the bug.
Seems like it's because Vite expects the module script to always be in the head and not moved to the body. We could make sure if it's moved we still keep the importmap script in the head.
But also, why are you moving the module script to the body? It affects Interaction to Next Paint (INP) as the script is now fetched later.