Skip to content

refactor: Migrate website build from Gulp to Vite#213

Merged
jevy merged 3 commits intomainfrom
website-vite-migration
Jan 29, 2026
Merged

refactor: Migrate website build from Gulp to Vite#213
jevy merged 3 commits intomainfrom
website-vite-migration

Conversation

@jevy
Copy link
Contributor

@jevy jevy commented Jan 29, 2026

Summary

  • Replaces the 272-line Gulp build system with Vite for faster, simpler website builds
  • Removes 17 gulp-related dev dependencies, adds only 2 (vite and vite-plugin-handlebars)
  • Uses vite-plugin-handlebars to maintain partial template support (header, footer, etc.)
  • Net reduction of ~7,700 lines (mostly gulpfile and package-lock.json)

Changes

  • vite.config.js: Multi-page app config with all HTML entry points and SCSS support
  • package.json: New scripts (dev, build, preview), updated dependencies
  • HTML files: Minor adjustments for Vite asset handling
  • postcss.config.js: Standalone PostCSS config for Tailwind

Test plan

  • Run npm run dev and verify hot reload works
  • Run npm run build and check dist/ output
  • Run npm run preview to test production build locally
  • Verify all pages render correctly (index, about, contact, etc.)

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 29, 2026

Deploying typestream with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1e3c33e
Status: ✅  Deploy successful!
Preview URL: https://504dd850.typestream.pages.dev
Branch Preview URL: https://website-vite-migration.typestream.pages.dev

View logs

@jevy jevy changed the title Migrate website build from Gulp to Vite refactor: Migrate website build from Gulp to Vite Jan 29, 2026
@jevy jevy requested a review from lucapette January 29, 2026 20:20
@claude
Copy link

claude bot commented Jan 29, 2026

PR #213 Review: Migrate website build from Gulp to Vite

Summary

This PR successfully modernizes the website build system by replacing a 272-line Gulp configuration with Vite. The migration removes 17 gulp-related dependencies and adds only 2 new ones, resulting in a net reduction of ~14,500 lines (mostly from package-lock.json simplification).

✅ Strengths

1. Excellent Build System Modernization

  • Vite provides significantly faster dev server with HMR (Hot Module Replacement)
  • Build times are dramatically improved with esbuild-powered bundling
  • The configuration is clean and maintainable (37 lines vs 272 lines)

2. Proper Multi-Page App Configuration

The vite.config.js correctly configures all HTML entry points:

input: {
  main: resolve(__dirname, "src/index.html"),
  about: resolve(__dirname, "src/about.html"),
  // ... all other pages
}

3. Template Support Maintained

Using vite-plugin-handlebars maintains the existing partial system (header, footer, etc.) which preserves the modular HTML structure.

4. Modern SCSS Configuration

scss: {
  api: "modern-compiler",
  silenceDeprecations: ["import"],
}

This uses the modern Sass compiler API and properly handles deprecation warnings.

5. Build Verification

✅ Build completes successfully in 2.73s
✅ All 8 HTML pages generated correctly
✅ Assets properly bundled and hashed

⚠️ Issues & Concerns

1. CRITICAL: Security Vulnerabilities

The npm install shows 13 vulnerabilities (3 moderate, 9 high, 1 critical):

Critical:

  • swiper@4.5.0 - Prototype Pollution vulnerability (GHSA-p3hc-fv2j-rp68)
    • Fix: Upgrade to swiper@6.5.1 or later (currently 12.1.0 available)

High Severity:

  • @iconscout/unicons - Depends on vulnerable svgo and nth-check
  • tar - Multiple path traversal vulnerabilities
  • nth-check - ReDoS vulnerability in CSS selector parsing

Recommended Actions:

npm install swiper@latest  # Fixes critical issue
npm audit fix              # Address other fixable issues

Consider replacing @iconscout/unicons with a more modern icon library or updating to a version that uses secure dependencies.

2. Deprecated Dependencies

The build shows several deprecation warnings:

  • glob@7.2.3 and glob@8.1.0 - Should use v9+
  • rimraf@3.0.2 - Should use v4+
  • wow.js@1.2.2 - Deprecated in favor of AOS (Animate On Scroll)
  • svgo@1.1.1 - No longer supported, should upgrade to v2.x.x

3. Missing .gitignore for Website

The website directory lacks a .gitignore file. Add:

node_modules/
dist/
.vite/

4. Potential Issue: vite-plugin-handlebars Version Conflict

The package.json specifies vite-plugin-handlebars@^2.0.0, but npm audit suggests downgrading to 1.5.0 to fix esbuild vulnerability. This creates a version conflict. Consider:

  • Testing with version 1.5.0 to see if it works
  • Or waiting for a patch in 2.x that updates esbuild

5. Asset Path Changes

The migration moves JavaScript files from src/assets/js/ to public/assets/js/. Verify that:

  • All script references in HTML are updated
  • Any CI/CD pipelines expecting old paths are updated
  • Documentation reflects new structure

6. Browser Compatibility

The browserslist config in package.json:

"browserslist": [
  "last 2 version",
  "> 2%"
]

Should be:

"browserslist": [
  "last 2 versions",  // 'versions' should be plural
  "> 2%"
]

7. No Tests

The migration doesn't include any tests to verify:

  • All pages render correctly
  • All assets load properly
  • Navigation works
  • Forms function (contact page)

Consider adding basic integration tests with Playwright or Cypress.

🔍 Code Quality

Good Practices Observed:

  • ✅ Clean separation of concerns (public vs src)
  • ✅ Proper PostCSS configuration
  • ✅ Modern ES modules ("type": "module")
  • ✅ devenv.nix updated with proper health checks

Areas for Improvement:

main.js global exports:

window.feather = feather;
window.tns = tns;
window.Tobii = Tobii;

This maintains compatibility with legacy scripts but creates global namespace pollution. Consider refactoring the legacy scripts in public/assets/js/ to use ES modules directly.

Hardcoded paths in vite.config.js:
Could use a helper function:

const pages = ['main', 'about', 'contact', 'error', 'integrations', 'privacy', 'terms', 'useCases'];
const input = Object.fromEntries(
  pages.map(name => [name, resolve(__dirname, `src/${name === 'main' ? 'index' : name}.html`)])
);

📊 Performance Considerations

Positive:

  • Vite's code splitting will improve load times
  • Asset hashing enables better caching
  • CSS is properly minified and optimized

Considerations:

  • The main CSS bundle is 539.84 kB (88.63 kB gzipped) - Consider:

    • Using PurgeCSS more aggressively
    • Lazy-loading non-critical CSS
    • Reviewing if all Tailwind components are needed
  • The main JS bundle is 137.35 kB (39.73 kB gzipped) - Reasonable size

🎯 Recommendations

Must Fix (Before Merge):

  1. Address critical security vulnerability in swiper package
  2. Add .gitignore for website directory
  3. Fix browserslist syntax (version → versions)

Should Fix (High Priority):

  1. Update deprecated dependencies (glob, rimraf, wow.js)
  2. Upgrade or replace @iconscout/unicons to fix high-severity vulnerabilities
  3. Resolve vite-plugin-handlebars version conflict

Nice to Have:

  1. Add basic integration tests for the website
  2. Refactor legacy JS to use ES modules instead of globals
  3. Document the new build system in a README
  4. Add CSS bundle size budget checks

🏁 Conclusion

This is a well-executed migration that significantly improves the build system. The Vite configuration is correct, the build works, and the developer experience will be much better.

However, the security vulnerabilities must be addressed before merging. The critical prototype pollution issue in swiper and the high-severity issues in dependencies pose real security risks.

Recommendation: Request changes to fix security issues, then approve.


Overall Assessment: Strong technical implementation marred by dependency security issues that need resolution.

- Upgrade swiper from 4.5.0 to ^11.0.0 (fixes critical prototype pollution vulnerability)
- Fix browserslist syntax: "version" → "versions" (plural)
- Add .vite/ to .gitignore for Vite cache directory
@claude
Copy link

claude bot commented Jan 29, 2026

Code Review: Gulp to Vite Migration

Summary

This is a solid refactoring that modernizes the build system. The migration from Gulp to Vite is well-executed with significant dependency reduction and cleaner configuration. Overall, this is a positive change that should improve developer experience.

✅ Strengths

  1. Massive Simplification

    • Reduced from 272 lines of Gulp config to 37 lines of Vite config
    • Removed 15 gulp-related dependencies, added only 2 (vite + vite-plugin-handlebars)
    • Much cleaner and more maintainable
  2. Modern Build System

    • Vite provides faster HMR and better dev experience
    • Modern ES modules throughout (main.js, vite.config.js, package.json)
    • Better asset handling out of the box
  3. Preserved Functionality

    • Handlebars partials support maintained via vite-plugin-handlebars
    • Multi-page app configuration looks correct
    • Tailwind/PostCSS integration properly configured
  4. Good Migration Practices

    • JavaScript files moved from src/assets/js to public/assets/js (appropriate for static assets)
    • Updated .gitignore with .vite/ cache directory
    • devenv.nix properly updated with new commands and readiness probes

⚠️ Issues & Concerns

1. Module System Inconsistency (website/tailwind.config.js:83-86)

export default {
  // ...
  plugins: [
    require("@tailwindcss/forms")({  // ❌ CommonJS require in ES module
      strategy: "class",
    }),
    require("daisyui"),  // ❌ CommonJS require in ES module
  ],
};

Issue: Using require() in an ES module file (package.json has "type": "module"). This works but is inconsistent.

Fix: Convert to ES imports:

import tailwindForms from "@tailwindcss/forms";
import daisyui from "daisyui";

export default {
  // ...
  plugins: [
    tailwindForms({ strategy: "class" }),
    daisyui,
  ],
};

2. SCSS API Deprecation Warning (website/vite.config.js:32)

scss: {
  api: "modern-compiler",
  silenceDeprecations: ["import"],  // ⚠️ Silencing deprecations
}

Concern: While silenceDeprecations is a quick fix, it hides underlying issues. The @import deprecation in Sass is real - it will be removed in future versions.

Recommendation:

  • Document why this is needed (likely legacy @import statements in SCSS files)
  • Plan to migrate @import to @use/@forward in a follow-up PR
  • Add a TODO comment explaining this is temporary

3. Missing Build Verification

The test plan in the PR description lists verification steps but doesn't show they were completed. Before merging:

  • Verify npm run build completes successfully
  • Check that dist/ output matches production requirements
  • Verify all pages render correctly (especially partials like header/footer)
  • Test that asset paths resolve correctly in production build

4. Potential Bundle Size Concerns (website/src/main.js:14-21)

import feather from "feather-icons";
import { tns } from "tiny-slider";
import Tobii from "tobii";

window.feather = feather;
window.tns = tns;
window.Tobii = Tobii;

Concern: Importing entire libraries and attaching to window defeats tree-shaking benefits of modern bundlers.

Recommendation (for future PR):

  • Consider refactoring existing scripts to import only what they need
  • Or use dynamic imports for libraries only used on specific pages
  • This would reduce initial bundle size

🔒 Security

✅ No security issues identified:

  • No dangerous patterns (eval, dangerouslySetInnerHTML, etc.)
  • Dependencies are reputable and up-to-date
  • Build outputs properly ignored in .gitignore
  • No secrets or credentials in code

📊 Performance

Positive:

  • Vite's dev server will be significantly faster than Gulp+BrowserSync
  • HMR is more efficient than full page reloads
  • Modern bundling with Rollup

Neutral:

  • Production bundle size should be similar (same dependencies, different bundler)
  • The global library attachment pattern isn't optimal but won't affect production build much

🧪 Test Coverage

Missing: No automated tests for the build process. Consider adding:

  • A smoke test that runs npm run build in CI
  • Verification that all HTML entry points are generated
  • Check that critical assets are present in dist/

📝 Recommendations

Before merging:

  1. Fix the require() vs import inconsistency in tailwind.config.js
  2. Verify the build actually works (run all test plan steps)
  3. Add a TODO/comment about the SCSS deprecation silencing

Future improvements:

  1. Add build verification to CI/CD
  2. Plan SCSS @import@use migration
  3. Consider optimizing the global library imports for better tree-shaking

Conclusion

This is a high-quality refactoring that significantly improves the codebase. The issues identified are minor and can be addressed quickly. Once the module consistency fix is applied and the build is verified, this should be ready to merge.

Great work simplifying the build system! 🎉

…ecation

- Convert require() to ES imports for @tailwindcss/forms and daisyui
- Add TODO comment explaining why silenceDeprecations is needed for @import
@jevy jevy merged commit 645129f into main Jan 29, 2026
3 checks passed
@jevy jevy deleted the website-vite-migration branch January 29, 2026 20:34
@claude
Copy link

claude bot commented Jan 29, 2026

Technical Review: Gulp → Vite Migration

Summary

This is a well-executed migration that successfully modernizes the build system. However, there are critical runtime bugs that must be fixed before merge.

Impact: Net reduction of ~7,700 lines, 272-line Gulp config → 40-line Vite config, removes 15 dev dependencies.


🔴 Critical Issues (Must Fix)

1. Missing Library Imports - BREAKING BUG

Severity: CRITICAL

The files public/assets/js/plugins.init.js and public/assets/js/app.js reference multiple libraries that aren't imported or made globally available:

Missing from src/main.js:

  • Gumshoe (used in app.js:183)
  • WOW (used in app.js:190)
  • Swiper (used in plugins.init.js:344)
  • Shuffle (used in plugins.init.js:573)
  • datepicker (used in plugins.init.js:558-559)
  • ClassicEditor (used in plugins.init.js:656)
  • AOS (used in plugins.init.js:666)
  • particlesJS (used in plugins.init.js:849)
  • Choices (used in plugins.init.js:965-980)

Impact: Pages using these features will throw ReferenceError: [Library] is not defined

Fix for src/main.js:

import feather from "feather-icons";
import { tns } from "tiny-slider";
import Tobii from "tobii";
import Gumshoe from "gumshoejs";
import WOW from "wow.js";
import Swiper from "swiper";
import Shuffle from "shufflejs";
import datepicker from "js-datepicker";
import Choices from "choices.js";

// Import required CSS
import "swiper/css";
import "choices.js/public/assets/styles/choices.min.css";
import "js-datepicker/dist/datepicker.min.css";
import "animate.css"; // For WOW.js

// Make globally available
window.feather = feather;
window.tns = tns;
window.Tobii = Tobii;
window.Gumshoe = Gumshoe;
window.WOW = WOW;
window.Swiper = Swiper;
window.Shuffle = Shuffle;
window.datepicker = datepicker;
window.Choices = Choices;

2. __dirname Not Available in ES Modules

Severity: HIGH
Location: vite.config.js:13-26

The config uses __dirname which isn't available when "type": "module" is set in package.json.

Fix:

import { fileURLToPath } from "url";
import { dirname } from "path";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export default defineConfig({
  // ... rest of config
});

⚠️ High Priority Issues

3. Duplicate JavaScript Files

Severity: MEDIUM

The same JavaScript files exist in both:

  • public/assets/js/ (3 files)
  • src/assets/js/ (3 files)

Action needed: Document why both exist, or delete from src/assets/js/ to avoid confusion.

4. Missing CSS Imports

Several libraries need CSS that isn't imported:

  • swiper → needs swiper/css
  • choices.js → needs styles
  • js-datepicker → needs styles
  • animate.css → needed for WOW.js

5. Pre-existing Bug in plugins.init.js

Location: public/assets/js/easy_background.js (via plugins.init.js:715)

// Current (incorrect):
if (toRotate === "undefined") {

// Should be:
if (typeof toRotate === "undefined") {

Not introduced by this PR, but worth fixing while refactoring.


🟡 Code Quality Suggestions

6. Hardcoded HTML Paths

All 8 HTML entry points are manually listed in vite.config.js. Consider dynamic discovery:

import { readdirSync } from "fs";

const htmlFiles = readdirSync("src")
  .filter(file => file.endsWith(".html"))
  .reduce((acc, file) => {
    const name = file === "index.html" ? "main" : file.replace(".html", "");
    acc[name] = resolve(__dirname, `src/${file}`);
    return acc;
  }, {});

7. Bundle Size Optimization

Consider:

  • Code splitting per page
  • Lazy loading libraries only used on specific pages
  • Tree shaking (currently defeated by global exports)

✅ What's Working Well

  1. ✅ Clean Vite configuration
  2. ✅ Proper Tailwind/PostCSS integration
  3. ✅ SCSS with modern compiler API
  4. ✅ Multi-page setup correctly configured
  5. ✅ Handlebars partials via vite-plugin-handlebars
  6. ✅ Excellent devenv.nix with readiness probes
  7. ✅ Consistent ES modules (after fixes)

🧪 Testing Checklist

Before merging, verify:

  • npm install succeeds
  • npm run build succeeds
  • npm run preview runs without errors
  • All 8 pages load without console errors
  • Image sliders work (tiny-slider, Swiper)
  • Gallery filtering works (Shuffle)
  • Form dropdowns work (Choices)
  • Scroll animations work (WOW/AOS)
  • Lightbox works (Tobii)
  • Icons render (feather-icons)
  • Navigation highlighting works (Gumshoe)

Final Recommendation

REQUEST CHANGES - The Vite configuration is solid, but missing library imports will cause runtime failures. Once the critical issues are fixed, this will be a significant improvement.

Estimated fix time: 30-60 minutes

Great work on the migration! The new setup is much cleaner and more maintainable than the Gulp configuration. 🚀

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.

1 participant