Skip to content

Vite plugin for enhanced:img prepends unnecessary empty script elements, breaks markdown tooling #14060

@morungos

Description

@morungos

Describe the bug

There's a small but irritating issue in the Vite plugin for enhanced:img. Basically, if you use enhanced:img in a Markdown file, it inserts an empty script element before front matter in the documents, which then breaks front matter behaviours. Usually this wipes front matter and drops it into the body. This happens if you try using a Markdown transformer before Svelte (which I am, because mdsvex breaks with enhanced:img -- very possibly in a related way). But anyway, Vite is the issue here.

The relevant lines are from [packages/enhanced-img/src/index.js](https://github.com/sveltejs/kit/blob/1164ffa83d7b4812c812e4e2d6f63e7b1ea1ef98/packages/enhanced-img/src/vite-plugin.js#L166), as follows:

// add imports
let text = '';
if (imports.size) {
	for (const [path, import_name] of imports.entries()) {
		text += `\timport ${import_name} from "${path}";\n`;
	}
}

if (ast.instance) {
	// @ts-ignore
	s.appendLeft(ast.instance.content.start, text);
} else {
	s.prepend(`<script>${text}</script>\n`);
}

Since this is Vite, there's no guarantee this is fully HTML yet, and won't later be transformed. In practice, if the text/imports are empty (they usually are), there's no need to prepend an empty script element. This is true almost all of the time for optimizable images. i.e., the last line could read:

} else if (text) {
	s.prepend(`<script>${text}</script>\n`);
}

Reproduction

Should not be necessary since the issue is clearer in the code than a reproduction, but if I must I will.

Logs

System Info

System:
    OS: macOS 15.5
    CPU: (8) arm64 Apple M1 Pro
    Memory: 86.50 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.19.4 - ~/.nvm/versions/node/v20.19.4/bin/node
    Yarn: 1.22.22 - /opt/homebrew/bin/yarn
    npm: 10.8.2 - ~/.nvm/versions/node/v20.19.4/bin/npm
    pnpm: 10.13.1 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 138.0.7204.169
    Edge: 131.0.2903.112
    Safari: 18.5
    Safari Technology Preview: 26.0
  npmPackages:
    @sveltejs/adapter-auto: ^6.0.1 => 6.0.1 
    @sveltejs/adapter-static: ^3.0.8 => 3.0.8 
    @sveltejs/enhanced-img: ^0.7.0 => 0.7.0 
    @sveltejs/kit: ^2.22.0 => 2.25.1 
    @sveltejs/vite-plugin-svelte: ^6.0.0 => 6.1.0 
    svelte: ^5.0.0 => 5.36.10 
    vite: ^7.0.4 => 7.0.5

Severity

annoyance

Additional Information

The suggested remedy (only prepending when required) will still cause issues, but in much rarer circumstances. It might be that when there's no AST instance, no scripts should be prepended at all. I don't know the innards of the parser well enough to be competent on that one.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions