Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Jul 18, 2025

Problem

HEAD requests to JavaScript files in the Vite dev server were returning incorrect Content-Type: text/html instead of text/javascript. This caused issues in environments where JavaScript file presence is checked via HEAD requests before loading, such as Module Federation setups.

Root Cause

The transform middleware only processed GET requests and immediately called next() for HEAD requests:

if (req.method !== 'GET' || knownIgnoreList.has(req.url!)) {
  return next()
}

This meant HEAD requests bypassed the transform middleware entirely and fell back to other middlewares that returned the default text/html content type.

Solution

1. Allow HEAD requests in transform middleware

Modified the HTTP method check to allow both GET and HEAD requests:

if ((req.method !== 'GET' && req.method !== 'HEAD') || knownIgnoreList.has(req.url!)) {
  return next()
}

2. Handle HEAD requests properly in send function

Updated the send function to handle HEAD requests by only sending headers without body content:

// For HEAD requests, don't send the body content
if (req.method === 'HEAD') {
  res.end()
} else {
  res.end(content)
}

Verification

  • HEAD requests to JS files now return Content-Type: text/javascript
  • HEAD requests return the same headers as GET requests but without body content ✅
  • All existing functionality remains intact ✅
  • Pattern follows existing codebase conventions (similar to htmlFallback middleware) ✅

Testing

Added comprehensive tests to verify:

  • HEAD requests are processed by transform middleware
  • Correct Content-Type headers are returned
  • HEAD requests have empty body while GET requests have content
  • Non-GET/HEAD requests are still rejected appropriately

Closes vitejs#20415


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI and others added 2 commits July 18, 2025 03:42
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] @vitejs/vite/issues/20415 Fix this issue. Make sure to write a test for it. The related line should be @vitejs/vite/files/packages/vite/src/node/server/middlewares/transform.ts fix: HEAD request Content-Type for JS files in transform middleware Jul 18, 2025
@Copilot Copilot AI requested a review from sapphi-red July 18, 2025 03:47
Copilot finished work on behalf of sapphi-red July 18, 2025 03:47
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
@Copilot Copilot AI requested a review from sapphi-red July 18, 2025 03:55
Copilot finished work on behalf of sapphi-red July 18, 2025 03:55
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
Copilot finished work on behalf of sapphi-red July 18, 2025 04:17
@Copilot Copilot AI requested a review from sapphi-red July 18, 2025 04:17
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jul 18, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • vite.dev
    • Triggering command: /home/REDACTED/.cache/playwright-bin/chromium_headless_shell-1181/chrome-linux/headless_shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-REDACTEDing --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --enable-automation --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --no-sandbox --no-sandbox --disable-setuid-sandbox --user-data-dir=/tmp/playwright_chromiumdev_profile-l2YqN9 --remote-debugging-pipe --no-startup-window (dns block)
    • Triggering command: /home/REDACTED/.cache/playwright-bin/chromium_headless_shell-1181/chrome-linux/headless_shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-REDACTEDing --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --enable-automation --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --no-sandbox --no-sandbox --disable-setuid-sandbox --user-data-dir=/tmp/playwright_chromiumdev_profile-ABag6x --remote-debugging-pipe --no-startup-window (dns block)
    • Triggering command: /home/REDACTED/.cache/playwright-bin/chromium_headless_shell-1181/chrome-linux/headless_shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-REDACTEDing --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --enable-automation --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --no-sandbox --no-sandbox --disable-setuid-sandbox --user-data-dir=/tmp/playwright_chromiumdev_profile-m4oOzk --remote-debugging-pipe --no-startup-window (dns block)
  • workers.cloudflare.com
    • Triggering command: node (vitest 1) (dns block)
    • Triggering command: node (vitest 3) (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@Copilot Copilot AI requested a review from sapphi-red July 18, 2025 04:30
Copilot finished work on behalf of sapphi-red July 18, 2025 04:30
@Copilot Copilot AI requested a review from sapphi-red July 18, 2025 05:00
@sapphi-red
Copy link
Owner

=> vitejs#20421

@sapphi-red sapphi-red closed this Jul 18, 2025
@sapphi-red sapphi-red deleted the copilot/fix-4698c672-67fb-40e7-af5b-229b906d1ae9 branch July 18, 2025 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HEAD request to .js files responds with incorrect Content-Type
2 participants