Skip to content

Remove compiled CSS file from version control #3773

@liberaldev

Description

@liberaldev

The repository currently tracks a compiled CSS file (stylesheets/compiled.css) in version control. This goes against best practices for managing build artifacts in VCS.

Current Situation

  • stylesheets/compiled.css is committed to the repository
  • This file is generated by the Tailwind CSS build process (as documented in README: npm run build-css)
  • The file contains ~6,800 lines of generated CSS code
  • The file is likely committed because jekyll serve requires it to be present for the site to display correctly

Why This Is Problematic

  1. Merge Conflicts: Contributors working on different style changes will frequently encounter merge conflicts in this large generated file
  2. Repository Bloat: Every CSS change creates large diffs that inflate repository size over time
  3. Review Difficulty: Pull request reviews become harder as generated code obscures the actual changes
  4. Build Process Confusion: Having the compiled file in VCS can lead to confusion about whether manual or automated builds are being used
  5. Maintenance Overhead: The file can easily become out of sync with the source files
  6. Inconsistent State: Developers might forget to rebuild CSS after pulling changes, leading to style mismatches

Options Considered

There are three approaches to solve this issue:

Option 1: Simple . gitignore Approach (Quick Fix)

Pros: Simple, no dependencies, fast rebuild times
Cons: Developers must manually run npm run watch-css or npm run build-css before jekyll serve

  1. Add to .gitignore:

    # Compiled CSS
    stylesheets/compiled.css
  2. Update development workflow in README:

    # Build CSS first
    npm run build-css
    
    # Or use watch mode in a separate terminal
    npm run watch-css
    
    # Then run Jekyll
    bundle exec jekyll serve
  3. Update CI/CD:

    • Ensure npm run build-css runs before Jekyll build in deployment pipeline

Option 2: Jekyll PostCSS v2 Integration (#3776)

Pros: Seamless integration, single command workflow
Cons: Requires additional gem dependency

Integrate PostCSS directly into Jekyll using the jekyll-postcss-v2 gem. This plugin automatically processes CSS during Jekyll builds, so developers can simply run bundle exec jekyll serve without needing to manually build CSS.

Note: Previously, due to limitations with Jekyll's incremental build system, it was necessary to run bundle exec jekyll serve without the --incremental flag to ensure CSS changes were detected and rebuilt, leading to longer rebuild times. However, this limitation can be resolved by developing a plugin—see _plugins/tailwind_incremental_fix.rb in the intergrate-postcss branch of liberaldev/www.ruby-lang.org for an example implementation. With such a plugin, CSS changes become detectable during incremental builds. Nevertheless, please note that after CSS changes, it may take a moment for the changes to be reflected when serving the site, as the build process still takes time to regenerate affected pages.

Why Option 2 may be suitable: This approach provides a clean, single-command workflow that avoids repository bloat and merge conflicts. By developing a suitable plugin (as shown in the example implementation, the incremental build limitation can be addressed. For projects where CSS processing is the primary concern, Option 2 offers significant benefits in terms of maintainability and contributor experience.

Option 3: JavaScript Build Tool Integration

Pros: Modern tooling, fast rebuilds, advanced features (HMR, tree-shaking, etc.)
Cons: Significantly increased complexity, additional tooling dependencies, steeper learning curve

Integrate a JavaScript build tool like Vite or Webpack to handle asset processing. This can be done either through Jekyll plugins (jekyll-vite, jekyll-webpack) or by directly integrating these tools into the build pipeline.

This approach provides the most powerful and flexible asset pipeline but adds substantial complexity to the project. It's typically overkill for sites that only need CSS processing, but may be worth considering if the project requires advanced JavaScript bundling or other modern build features.

Recommended Implementation Path

Given the trade-offs, here's what each option offers:

  • Option 1: Simpler setup, faster rebuild times during development (with npm run watch-css running separately), minimal changes to existing workflow
  • Option 2 (Recommended): Offers a clean workflow, helps avoid merge conflicts and repository bloat, and allows incremental build issues with CSS to be resolved by developing a plugin (see example implementation in the integrate-postcss branch of liberaldev/www.ruby-lang.org). This approach may be well-suited for contributors seeking a maintainable, streamlined development process.
  • Option 3: Most powerful tooling with advanced features, but significantly increases project complexity

The team should evaluate based on their priorities:

  • Choose Option 1 if development speed and simplicity are priorities
  • Choose Option 2 if single-command workflow and avoiding repository bloat are more important
  • Choose Option 3 if the project needs advanced build features beyond CSS processing

All three options successfully address the core issue of removing compiled CSS from version control.

Implementation Steps

Option 1

  1. Add stylesheets/compiled.css to .gitignore
  2. Remove the file from git tracking: git rm --cached stylesheets/compiled.css
  3. Update README to clarify development workflow:
    • Run npm run build-css before first jekyll serve
    • Or use npm run watch-css in a separate terminal for automatic rebuilds
  4. Ensure CI/CD pipeline runs npm run build-css before Jekyll build
  5. Test thoroughly in development and production
  6. Notify contributors of the change

Option 2

  1. Install and configure jekyll-postcss-v2 gem
  2. Configure PostCSS to use Tailwind (ensure postcss.config.js includes the Tailwind plugin)
  3. Add empty Front Matter to the CSS entry point (the source file with @tailwind directives) so Jekyll processes it:
    ---
    ---
    @tailwind base;
    @tailwind components;
    @tailwind utilities;
  4. Develop a plugin to ensure incremental builds correctly process CSS changes (see _plugins/tailwind_incremental_fix.rb in the integrate-postcss branch of liberaldev/www.ruby-lang.org)
  5. Remove stylesheets/compiled.css
  6. Update README with new simplified workflow
  7. Test thoroughly in development and production
  8. Notify contributors of the change

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions