Skip to content

Migrate from webpack/gulp to Astro#1195

Merged
ChronosSF merged 11 commits intovnextfrom
migrate-samples-browser-to-astro
Mar 24, 2026
Merged

Migrate from webpack/gulp to Astro#1195
ChronosSF merged 11 commits intovnextfrom
migrate-samples-browser-to-astro

Conversation

@dobromirts
Copy link
Copy Markdown
Contributor

@dobromirts dobromirts commented Mar 18, 2026

Closes #1194

Actions deploy workflow - https://github.com/IgniteUI/igniteui-actions/pull/48

Before merging:
Disable the existing Azure DevOps build/release pipeline for this repo
Merge IgniteUI/igniteui-actions#48 first — it adds the wc-samples-cd workflow that this pipeline dispatches to for staging and production deployments

1. Build system removal

  • Deleted browser/ directory (~80 files: webpack config, gulp tasks, karma config, babel config, EJS templates, and the compiled browser app entry point)
  • Deleted gulpfile.js, webpack.config.js, tsconfig.prod.json, tsconfig.test.json
  • Removed 30+ devDependencies from package.json (webpack, gulp, karma, babel, and related plugins)

2. Configuration

2.1. tsconfig.json

  • Now extends astro/tsconfigs/strict; removed manual compiler options that duplicated it

2.2. astro.config.mjs — new Astro + Vite configuration

  • output: 'static' — builds to dist/ as plain HTML + JS assets
  • base — configurable via BASE_PATH env variable for sub-path deployments (e.g. /webcomponents-demos)
  • trailingSlash: 'never' — matches IIS routing behaviour
  • stripSampleInstantiation() Vite plugin — strips the module-level new Sample(); from every sample src/index.ts at build time. Without this, Rollup code-splitting can place shared IgniteUI chunks inside a sample not loaded on the current page, causing that sample's constructor to fire against a missing DOM
  • inlineSampleCss() Vite plugin — converts local CSS/SCSS side-effect imports in sample files to ?inline + dynamic <style> injection. Prevents Rollup from emitting a shared CSS chunk that Vite would preload on every page touching the same shared chunk, leaking styles across unrelated samples
  • optimizeDeps.noDiscovery: true + explicit include list — stops esbuild from scanning source files during dev startup (the sample glob in [...slug].astro triggers CSS parse crashes); pre-bundles all igniteui-* packages explicitly for fast first load
  • manualChunks — gives every samples/**/src/index.ts its own named Rollup chunk (e.g. samples/grids--grid--overview), preventing Rollup from inlining all 800+ samples into one bundle (OOM)
  • scss.loadPaths — exposes node_modules/ to Sass so samples using @use 'igniteui-theming/sass/...' resolve correctly

2.3. New src/ files added

  • src/env.d.ts — Astro type references (/// <reference types="astro/client" />)
  • src/utils/samples.ts — build-time utilities: keyToSlug, slugToInfo, buildNavTree, extractSampleHtml, toTitleCase; used by all three pages at build time, never shipped to the browser
  • src/layouts/SampleLayout.astro — shared HTML shell for every page: loads fonts, the global stylesheet, the #nav-bar sidebar and #router-target content area; manages sidebar visibility via iframe detection and sessionStorage
  • src/components/NavSidebar.astro — renders the navigation tree (groups → components → samples) with expand/collapse and search filter
  • src/pages/index.astro — home page with hero, live search bar, and component cards grid
  • src/pages/[...slug].astro — catch-all dynamic route; generates one static page per sample using getStaticPaths(); injects the sample's HTML at build time and loads its JS chunk lazily at runtime

3. JS & CSS chunk isolation

With 800+ samples sharing the same IgniteUI libraries, Rollup's code-splitting creates shared chunks that can cause two classes of bugs if not handled:

JS constructor leakage — Rollup picks one sample chunk as the "host" for shared IgniteUI symbols. Any other sample that uses those symbols imports from that host chunk at runtime. If the host chunk contains a module-level new Sample(), that constructor fires immediately on import — even on pages where that sample's DOM does not exist — causing Cannot set properties of null errors.
Fix: stripSampleInstantiation() removes the trailing new ClassName(); from every samples/**/src/index.ts at build time. The [...slug].astro client script calls new module.Sample() explicitly after the dynamic import resolves, so instantiation only ever happens on the page that owns that sample's DOM.

CSS style leakage — Rollup emits a separate .css file for every CSS import it encounters inside a chunk. Vite's __vite__mapDeps then preloads those CSS files on every page that transitions through the same shared chunk — causing unrelated sample styles (colours, fonts, layout overrides) to appear on the wrong pages.
Fix: inlineSampleCss() rewrites every local CSS/SCSS side-effect import in sample files from import './index.css' to import __css from './index.css?inline' + a <style> element injected at runtime. Vite no longer emits a separate CSS chunk for it, so nothing leaks. The style is only added to the DOM when that specific sample's JS module actually runs.

3. README

  • Rewritten to reflect the Astro workflow (npm installnpm run devnpm run buildnpm run preview)
  • Removed all webpack/gulp/karma references

4. Build & Dev Server Performance

Command Time
npm run dev (cold start, until server ready) 17.7 s
npm run build (959 pages) 2 min 7 s

Build breakdown (npm run build)

Phase Time
Vite chunk compilation (800+ sample modules) ~109 s
Astro HTML generation (959 pages) ~10.7 s
Image optimisation ~0.1 s

@dobromirts dobromirts marked this pull request as ready for review March 23, 2026 14:13
@rkaraivanov rkaraivanov added the status: verified The PR is tested and ready for a merge label Mar 24, 2026
@ChronosSF ChronosSF merged commit 3218842 into vnext Mar 24, 2026
4 checks passed
@ChronosSF ChronosSF deleted the migrate-samples-browser-to-astro branch March 24, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: verified The PR is tested and ready for a merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace Webpack Samples Browser with Modern Astro/Vite Solution

4 participants