Vite Ruby

repository·main·Indexed 23 days ago

https://github.com/elmassimo/vite_ruby

Libraries to integrate Vite into Ruby web frameworks including Rails, Hanami, and Rack. It provides an unbundled development server for fast starts and hot reloading, along with optimized production bundling. The ecosystem includes framework-specific gems like vite_rails and vite_hanami, as well as plugins such as vite-plugin-ruby and vite-plugin-rails.

Tokens
25.5K
Snippets
82
Records
194
Agent score
76%

What's inside vite_ruby

  1. What is Vite Ruby?

    main

    Vite Ruby is an umbrella project that provides full Vite.js integration for Ruby web applications. It bridges the gap between Vite's modern frontend tooling and Ruby's web conventions.

    It consists of several components depending on your framework:

    • vite_rails: Provides functionality similar to webpacker for Rails applications, but with significantly less configuration overhead.
    • vite_ruby: The core package for plain Rack applications when using HTML entrypoints.
    • Framework-specific integrations: Includes support for Hanami, Padrino, and Jekyll.

    By using Vite Ruby, you get the benefits of Vite (fast dev server, instant HMR, and optimized production bundling) while following standard Ruby application structures.

  2. Understand Vite smart output behavior

    main

    The vite_javascript_tag helper provides 'Smart Output' by automatically injecting <link> tags for styles or other entries imported within the specified JavaScript file.

    Production/Build Behavior

    When running against built assets, a single JavaScript tag will expand to include necessary preloads and stylesheets:

    <script src="/vite/assets/application.a0ba047e.js" type="module" crossorigin="anonymous"/>
    <link rel="modulepreload" href="/vite/assets/example_import.8e1fddc0.js" as="script" type="text/javascript" crossorigin="anonymous">
    <link rel="stylesheet" media="screen" href="/vite/assets/application.cccfef34.css">

    Development Behavior

    When the development server is running, these extra tags are omitted because Vite handles dependency loading dynamically via the client:

    <script src="/vite/assets/application.js" type="module" crossorigin="anonymous"/>
    = vite_javascript_tag 'application'
  3. Deployment and asset precompilation with Vite Ruby

    main

    Vite Ruby is designed for seamless deployment. It integrates with the standard Ruby asset pipeline processes:

    • assets:precompile Integration: Rake tasks for building Vite assets are automatically integrated with the standard assets:precompile command. This ensures that when you run your deployment precompile step, Vite assets are built alongside your other assets.
    • Auto-build for Integration Tests: When the Vite development server is not running (e.g., during CI or integration testing), Vite Ruby automatically detects changes and recompiles assets for you, ensuring tests run against the latest asset state.
  4. Understand Entrypoints and automatic detection

    main

    Vite Ruby automatically detects files located within the entrypointsDir (configured via entrypointsDir) and treats them as application entrypoints (for SPAs or specific pages) to be bundled by Vite.

    By default, files inside ~/{assets,fonts,icons,images}/**/* are also bundled as entrypoints, allowing them to be referenced via tag helpers. If you need to define entrypoints manually, use the additionalEntrypoints configuration key.

    app/frontend: sourceCodeDir
      ├── entrypoints: entrypointsDir
      │   # only Vite entry files here
      │   │── application.js
      │   └── typography.css
      │── components:
      │   └── App.vue
      │── channels:
      │   │── index.js
      │   └── chat.js
      │── stylesheets:
      │   └── my_styles.css
      └── images:
          └── logo.svg
  5. Understand Vite smart output for entrypoints

    main

    The vite_javascript_tag helper features 'smart output'. In production, it automatically injects <link rel="modulepreload"> tags for any styles or other entrypoints imported within the specified script. This ensures dependencies are loaded efficiently.

    In development, these extra tags are omitted because Vite handles dependency loading via the dev server.

  6. Understand Smart Output for JavaScript entrypoints

    main

    The vite_javascript helper uses 'Smart Output' to automatically inject necessary tags for styles or other entries imported within a script.

    • In Production/Build mode: It will output the main <script> tag along with <link rel="modulepreload"> for imports and <link rel="stylesheet"> for any CSS imported by the JS.
    • In Development mode: These extra tags are omitted because the Vite dev server handles dependency loading automatically.
    <%= vite_javascript 'application' %>
  7. How to bundle sidecar assets for components

    main

    When using libraries like ViewComponent, you may want to keep JS and CSS files within the same folder as the component (sidecar assets). There are two primary patterns for this:

    1. Import every component via Glob Imports

    This is the simplest method. You use Vite's import.meta.glob to import all component files into a single entrypoint (like application.js). This is ideal if you have a small number of components or if all components should be available on every page.

    2. One entrypoint per component

    To bundle each component independently, add the component file pattern to additionalEntrypoints in your configuration. This allows you to reference specific components using tag helpers.

    Important: If you use sidecar assets in app/components/**/*, you must add app/components/**/* to watchAdditionalPaths to ensure the build triggers when component files change.

    // app/frontend/entrypoints/application.js
    import.meta.glob('../../components/**/*_component.js', { eager: true })
  8. Understand the 'Batteries Included' approach of vite-plugin-rails

    main

    While vite-plugin-ruby provides minimal configuration, vite-plugin-rails follows a Rails-like philosophy by including several plugins by default:

    • Compression: Automatically generates gzip and brotli assets.
    • Environment: Exposes env vars via import.meta.env.
    • Full Reload: Automatically reloads the browser when server-side templates change.
    • Stimulus HMR: Enables Hot Module Replacement for Stimulus controllers.
    • Subresource Integrity (SRI): Automatically calculates cryptographic hashes for JS and CSS assets.

    If you require finer-grained control and want to manually add only specific plugins, use vite-plugin-ruby instead.

  9. Automatic entrypoint detection in Vite Ruby

    main
    Vite Ruby simplifies asset management by automatically detecting your entrypoints. Instead of manual configuration, you simply place your JavaScript or TypeScript entrypoint files under the app/frontend/entrypoints directory. The library will automatically configure these files as Vite entrypoints.
  10. The two components of Vite Ruby

    main

    Vite Ruby is composed of two distinct parts that serve different roles in the development and production lifecycles:

    1. vite-plugin-ruby: A Vite plugin that configures Vite for Ruby applications. It handles the setup of entrypoints, directories (like publicDir), and other configuration options (like assetHost).
    2. vite_ruby: A Ruby gem that acts as the glue between your Rack application and Vite.

    Lifecycle usage:

    • Development & Deployment: Both Vite.js and the plugin are used.
    • Production: The plugin and Vite.js are not used once the app is live; instead, the vite_ruby gem is used to serve the precompiled assets from the public folder.
  11. Configure Source Maps and Output Directory behavior

    main

    Vite Ruby has specific defaults for production to align with Rails patterns:

    1. Source Maps: Enabled by default in production. To disable them, set build.sourcemap: false in vite.config.ts.
    2. Emptying Output Dir: emptyOutDir is disabled by default in production to support deployments that don't use a CDN (preventing downtime by keeping old assets). To enable it, set build.emptyOutDir: true in vite.config.ts.
    // vite.config.ts
    export default defineConfig({
      build: { sourcemap: false },
    })
    
    // vite.config.ts
    export default defineConfig({
      build: { emptyOutDir: true },
    })
  12. Understand the motivation behind Vite Ruby

    main

    Vite Ruby was created to solve the limitations of Webpack-based asset pipelines (like Webpacker) in Ruby on Rails applications.

    Key improvements include:

    • Faster Development Cycles: Unlike Webpack, which requires bundling the entire application before startup, Vite Ruby leverages Vite's architecture which uses native ESM to process files on demand. This ensures that startup time and Hot Module Replacement (HMR) speeds remain fast even as the application grows.
    • Reduced Complexity: It aims to avoid the heavy dependency chains and complex configuration requirements often associated with Webpack and Webpacker.
    • Developer Experience: It provides a balance between strong out-of-the-box conventions and the flexibility to tweak or opt-out of configurations as needed.