Skip to content

fix(site): preserve directives when normalizing imports - #1930

Open
mihar-22 wants to merge 1 commit into
mainfrom
fix/1926-import-directives
Open

fix(site): preserve directives when normalizing imports#1930
mihar-22 wants to merge 1 commit into
mainfrom
fix/1926-import-directives

Conversation

@mihar-22

@mihar-22 mihar-22 commented Aug 3, 2026

Copy link
Copy Markdown
Member

Closes #1926

Summary

Preserve module directive prologues when consolidating imports so generated React source does not silently lose directives such as use client.

Changes

  • Emit directive prologues before normalized import groups
  • Preserve multiple directives even when a module has no imports
  • Replace the deprecated TypeScript import-clause check with phaseModifier
  • Add regression coverage for both directive shapes

Testing

  • pnpm -C site test (518 tests)
  • pnpm -C site ejected-skins
  • Generated ejected-skins.json is byte-for-byte unchanged
  • pnpm -C site astro check (0 errors)

Note

Low Risk
Scoped to the site import-normalization script and its tests; behavior fix for generated source with no auth or runtime security impact.

Overview
normalizeImports now keeps module directive prologues (e.g. 'use client') at the top of the file when it merges import lines, instead of dropping them during ejected-skin / generated React output.

Directive strings are collected while scanning the prologue, emitted ahead of the normalized import block (with a blank line between directives and imports), and still returned when there are no imports. Statement-level import type detection uses importClause.phaseModifier === ts.SyntaxKind.TypeKeyword instead of the deprecated isTypeOnly flag.

Regression tests cover directives above merged imports and multiple directives with no imports.

Reviewed by Cursor Bugbot for commit a53d24f. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview Aug 3, 2026 10:37pm

Request Review

@netlify

netlify Bot commented Aug 3, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit a53d24f
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/6a7117f94724470008164559
😎 Deploy Preview https://deploy-preview-1930--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html — no changes
Presets (7)
Entry Initial Lazy
/video (default) 53.76 kB 53.52 kB
/video (default + hls) 189.72 kB 53.52 kB
/video (minimal) 53.73 kB 53.52 kB
/video (minimal + hls) 189.69 kB 53.52 kB
/audio (default) 46.03 kB 53.52 kB
/audio (minimal) 42.47 kB 53.52 kB
/background 5.00 kB 53.52 kB
Media (12)
Entry Initial Lazy
/media/background-video 1.14 kB
/media/container 2.58 kB 53.52 kB
/media/dash-video 211.14 kB
/media/google-cast 6.46 kB
/media/hlsjs-video 137.92 kB
/media/mux-audio 138.88 kB
/media/mux-data 153.96 kB
/media/mux-video 139.06 kB
/media/native-hls-video 5.34 kB
/media/simple-hls-audio-only 19.92 kB
/media/simple-hls-video 24.27 kB
/media/vimeo-video 12.31 kB
Players (5)
Entry Initial Lazy
/video/player 8.98 kB 53.52 kB
/audio/player 6.20 kB 53.52 kB
/background/player 4.72 kB 53.52 kB
/live-video/player 8.39 kB 53.52 kB
/live-audio/player 6.21 kB 53.52 kB
Skins (30)
Entry Type Initial Lazy
/video/minimal-skin.css css 5.92 kB
/video/skin.css css 5.92 kB
/video/minimal-skin js 53.72 kB 53.52 kB
/video/minimal-skin.tailwind js 54.30 kB 53.52 kB
/video/skin js 53.87 kB 53.52 kB
/video/skin.tailwind js 54.60 kB 53.52 kB
/audio/minimal-skin.css css 4.11 kB
/audio/skin.css css 4.05 kB
/audio/minimal-skin js 42.45 kB 53.52 kB
/audio/minimal-skin.tailwind js 43.00 kB 53.52 kB
/audio/skin js 46.03 kB 53.52 kB
/audio/skin.tailwind js 46.51 kB 53.52 kB
/background/skin.css css 133 B
/background/skin js 1.14 kB
/live-video/minimal-skin.css css 5.92 kB
/live-video/skin.css css 5.92 kB
/live-video/minimal-skin js 49.99 kB 53.52 kB
/live-video/minimal-skin.tailwind js 50.51 kB 53.52 kB
/live-video/skin js 52.28 kB 53.52 kB
/live-video/skin.tailwind js 52.92 kB 53.52 kB
/live-audio/minimal-skin.css css 4.11 kB
/live-audio/skin.css css 4.05 kB
/live-audio/minimal-skin js 34.65 kB 53.52 kB
/live-audio/minimal-skin.tailwind js 34.08 kB 53.52 kB
/live-audio/skin js 38.41 kB 53.52 kB
/live-audio/skin.tailwind js 37.92 kB 53.52 kB
/global.css css 183 B
/shared.css css 104 B
/tailwind.css css 161 B
/skin-element js 1.46 kB
UI Components (39)
Entry Initial
/ui/airplay-button 2.57 kB
/ui/alert-dialog 2.89 kB
/ui/alert-dialog-close 2.56 kB
/ui/alert-dialog-description 2.51 kB
/ui/alert-dialog-title 2.53 kB
/ui/audio-track-radio-group 3.08 kB
/ui/buffering-indicator 2.78 kB
/ui/captions-button 2.68 kB
/ui/captions-radio-group 3.08 kB
/ui/cast-button 2.63 kB
/ui/compounds 3.28 kB
/ui/controls 3.01 kB
/ui/error-dialog 3.02 kB
/ui/fullscreen-button 2.63 kB
/ui/hotkey 2.60 kB
/ui/menu 3.04 kB
/ui/mute-button 2.70 kB
/ui/pip-button 2.60 kB
/ui/play-button 2.66 kB
/ui/playback-rate-button 2.71 kB
/ui/playback-rate-radio-group 2.85 kB
/ui/popover 3.22 kB
/ui/poster 2.42 kB
/ui/quality-radio-group 3.00 kB
/ui/seek-button 2.59 kB
/ui/seek-indicator 2.83 kB
/ui/seek-indicator-value 470 B
/ui/slider 3.04 kB
/ui/status-announcer 2.47 kB
/ui/status-indicator 2.64 kB
/ui/status-indicator-value 421 B
/ui/thumbnail 2.64 kB
/ui/time 3.01 kB
/ui/time-slider 3.04 kB
/ui/tooltip 3.00 kB
/ui/volume-indicator 2.54 kB
/ui/volume-indicator-fill 373 B
/ui/volume-indicator-value 426 B
/ui/volume-slider 3.04 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react — no changes
Presets (7)
Entry Initial Lazy
/video (default) 42.49 kB 53.52 kB
/video (default + hls) 177.04 kB 53.52 kB
/video (minimal) 42.75 kB 53.52 kB
/video (minimal + hls) 177.57 kB 53.52 kB
/audio (default) 34.68 kB 53.52 kB
/audio (minimal) 34.74 kB 53.52 kB
/background 581 B
Media (11)
Entry Initial
/media/background-video 394 B
/media/dash-video 209.54 kB
/media/google-cast 5.35 kB
/media/hlsjs-video 136.40 kB
/media/mux-audio 137.23 kB
/media/mux-data 152.93 kB
/media/mux-video 137.38 kB
/media/native-hls-video 3.54 kB
/media/simple-hls-audio-only 18.18 kB
/media/simple-hls-video 22.64 kB
/media/vimeo-video 10.46 kB
Skins (27)
Entry Type Initial Lazy
/tailwind.css css 161 B
/video/minimal-skin.css css 5.81 kB
/video/skin.css css 5.81 kB
/video/minimal-skin js 42.70 kB 53.52 kB
/video/minimal-skin.tailwind js 48.82 kB 53.52 kB
/video/skin js 42.43 kB 53.52 kB
/video/skin.tailwind js 48.61 kB 53.52 kB
/audio/minimal-skin.css css 3.97 kB
/audio/skin.css css 3.90 kB
/audio/minimal-skin js 34.66 kB 53.52 kB
/audio/minimal-skin.tailwind js 37.14 kB 53.52 kB
/audio/skin js 34.58 kB 53.52 kB
/audio/skin.tailwind js 38.96 kB 53.52 kB
/background/skin.css css 90 B
/background/skin js 272 B
/live-video/minimal-skin.css css 5.81 kB
/live-video/skin.css css 5.81 kB
/live-video/minimal-skin js 37.58 kB 53.52 kB
/live-video/minimal-skin.tailwind js 43.78 kB 53.52 kB
/live-video/skin js 37.55 kB 53.52 kB
/live-video/skin.tailwind js 43.81 kB 53.52 kB
/live-audio/minimal-skin.css css 3.97 kB
/live-audio/skin.css css 3.90 kB
/live-audio/minimal-skin js 25.04 kB 53.52 kB
/live-audio/minimal-skin.tailwind js 28.33 kB 53.52 kB
/live-audio/skin js 25.09 kB 53.52 kB
/live-audio/skin.tailwind js 28.52 kB 53.52 kB
UI Components (33)
Entry Initial
/ui/airplay-button 2.53 kB
/ui/alert-dialog 2.77 kB
/ui/audio-track 2.49 kB
/ui/buffering-indicator 2.64 kB
/ui/captions-button 2.59 kB
/ui/captions-radio-group 2.45 kB
/ui/cast-button 2.56 kB
/ui/controls 2.70 kB
/ui/error-dialog 2.64 kB
/ui/fullscreen-button 2.59 kB
/ui/gesture 2.59 kB
/ui/hotkey 2.54 kB
/ui/live-button 2.53 kB
/ui/menu 2.78 kB
/ui/mute-button 2.56 kB
/ui/pip-button 2.62 kB
/ui/play-button 2.57 kB
/ui/playback-rate 2.63 kB
/ui/playback-rate-button 2.60 kB
/ui/popover 3.28 kB
/ui/poster 2.66 kB
/ui/quality 2.45 kB
/ui/seek-button 2.53 kB
/ui/seek-indicator 2.80 kB
/ui/slider 2.62 kB
/ui/status-announcer 2.44 kB
/ui/status-indicator 2.48 kB
/ui/thumbnail 2.65 kB
/ui/time 2.44 kB
/ui/time-slider 2.65 kB
/ui/tooltip 3.26 kB
/ui/volume-indicator 2.47 kB
/ui/volume-slider 2.61 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core — no changes
Entries (75)
Entry Initial Lazy
. 11.46 kB
/dom 18.32 kB
/i18n 3.07 kB 53.52 kB
/i18n/locales/all 32.44 kB
/i18n/locales/ar 1.14 kB
/i18n/locales/az 1.04 kB
/i18n/locales/bg 1.21 kB
/i18n/locales/bn 1.23 kB
/i18n/locales/bs 951 B
/i18n/locales/ca 1.00 kB
/i18n/locales/cs 1022 B
/i18n/locales/cy 977 B
/i18n/locales/da 943 B
/i18n/locales/de 1.02 kB
/i18n/locales/el 1.40 kB
/i18n/locales/en 732 B
/i18n/locales/es 959 B
/i18n/locales/et 1019 B
/i18n/locales/eu 983 B
/i18n/locales/fa 1.14 kB
/i18n/locales/fi 997 B
/i18n/locales/fr 1.01 kB
/i18n/locales/gd 1.03 kB
/i18n/locales/gl 960 B
/i18n/locales/he 1.06 kB
/i18n/locales/hi 1.24 kB
/i18n/locales/hr 986 B
/i18n/locales/hu 1.02 kB
/i18n/locales/id 868 B
/i18n/locales/it 978 B
/i18n/locales/ja 1.12 kB
/i18n/locales/ko 1.08 kB
/i18n/locales/lt 986 B
/i18n/locales/lv 1.02 kB
/i18n/locales/mr 1.24 kB
/i18n/locales/nb 928 B
/i18n/locales/ne 1.23 kB
/i18n/locales/nl 967 B
/i18n/locales/nn 931 B
/i18n/locales/oc 1.01 kB
/i18n/locales/pl 1.06 kB
/i18n/locales/pt 988 B
/i18n/locales/pt-BR 988 B
/i18n/locales/pt-PT 953 B
/i18n/locales/ro 1.01 kB
/i18n/locales/ru 1.29 kB
/i18n/locales/sk 1.03 kB
/i18n/locales/sl 987 B
/i18n/locales/sr 1017 B
/i18n/locales/sv 962 B
/i18n/locales/te 1.26 kB
/i18n/locales/th 1.22 kB
/i18n/locales/tr 1.01 kB
/i18n/locales/uk 1.32 kB
/i18n/locales/vi 1.03 kB
/i18n/locales/zh 977 B
/i18n/locales/zh-CN 977 B
/i18n/locales/zh-TW 972 B
/i18n/text/airplay 101 B
/i18n/text/buttons 137 B
/i18n/text/captions 93 B
/i18n/text/cast 114 B
/i18n/text/common 90 B
/i18n/text/container 75 B
/i18n/text/errors 277 B
/i18n/text/fullscreen 98 B
/i18n/text/live 126 B
/i18n/text/menu 249 B
/i18n/text/pip 101 B
/i18n/text/playback 80 B
/i18n/text/seek 105 B
/i18n/text/slider 65 B
/i18n/text/status 222 B
/i18n/text/time 214 B
/i18n/text/volume 133 B
🏷️ @videojs/element — no changes
Entries (2)
Entry Initial
. 996 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Initial
. 1.39 kB
/html 696 B
/react 361 B
🔧 @videojs/utils — no changes
Entries (13)
Entry Initial
/array 104 B
/dom 3.16 kB
/events 319 B
/function 327 B
/i18n 44 B
/jwt 176 B
/object 505 B
/predicate 265 B
/percent 281 B
/string 239 B
/style 190 B
/time 900 B
/number 158 B
📦 @videojs/media — no changes
Entries (14)
Entry Initial
. 959 B
/dom/audio-host 1.11 kB
/dom/custom-media-element 2.09 kB
/dom/dash 208.99 kB
/dom/google-cast 4.06 kB
/dom/hls-js 136.00 kB
/dom/media-host 1.21 kB
/dom/media-played-ranges 576 B
/dom/mux 159.38 kB
/dom/native-hls 3.02 kB
/dom/simple-hls 22.09 kB
/dom/simple-hls-audio-only 17.73 kB
/dom/video-host 1.40 kB
/dom/vimeo 9.88 kB
📦 @videojs/spf — no changes
Entries (5)
Entry Initial
. 4.46 kB
/dom 6.50 kB
/hls 18.74 kB
/media-tracks 504 B
/background-video 13.42 kB

ℹ️ How to interpret

JS sizes are initial static graph totals (minified + brotli). Lazy dynamic chunks are shown separately when present.

Icon Meaning
No change
🔺 Increased ≤ 10%
🔴 Increased > 10%
🔽 Decreased
🆕 New (no baseline)

Run pnpm size locally to check current initial sizes.

@mihar-22
mihar-22 marked this pull request as ready for review August 3, 2026 22:49
@mihar-22
mihar-22 requested a review from decepulis August 3, 2026 22:50

@decepulis decepulis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me like half an hour to wrap my head around this. Like, what was this fixing if there was no change in ejected-skins.json? If the site was already correctly showing "use client" at the top of ejected skins?

But. I think I get it, now?

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.

Bug: Preserve Directives When Normalizing Imports

2 participants