Class: ViteRuby::Manifest

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/vite_ruby/manifest.rb

Overview

Public: Registry for accessing resources managed by Vite, using a generated manifest file which maps entrypoint names to file paths.

Example:

lookup_entrypoint('calendar', type: :javascript)
=> { "file" => "/vite/assets/calendar-1016838bab065ae1e314.js", "imports" => [] }

NOTE: Using ‘“autoBuild”: true` in config/vite.json file will trigger a build on demand as needed, before performing any lookup.

Instance Method Summary collapse

Constructor Details

#initialize(vite_ruby) ⇒ Manifest

Returns a new instance of Manifest.



13
14
15
16
# File 'lib/vite_ruby/manifest.rb', line 13

def initialize(vite_ruby)
  @vite_ruby = vite_ruby
  @build_mutex = Mutex.new if config.auto_build
end

Instance Method Details

#import_chunks_for(entry, seen_filenames: Set.new) ⇒ Object

Internal: Recursively collects all imported chunks for a given entry. Returns chunks in dependency-first order (deepest imports first), deduped.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/vite_ruby/manifest.rb', line 27

def import_chunks_for(entry, seen_filenames: Set.new)
  chunks = []

  entry["imports"]&.each do |chunk|
    filename = chunk["file"]
    next if seen_filenames.include?(filename)
    seen_filenames.add(filename)

    chunks.concat(import_chunks_for(chunk, seen_filenames: seen_filenames))
    chunks << chunk
  end

  chunks
end

#path_for(name, **options) ⇒ Object

Public: Returns the path for the specified Vite entrypoint file.

Raises an error if the resource could not be found in the manifest.



21
22
23
# File 'lib/vite_ruby/manifest.rb', line 21

def path_for(name, **options)
  lookup!(name, **options).fetch("file")
end

#react_preamble_codeObject

Public: Source script for the React Refresh plugin.



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/vite_ruby/manifest.rb', line 78

def react_preamble_code
  if dev_server_running?
    <<~REACT_PREAMBLE_CODE
      import RefreshRuntime from '#{prefix_asset_with_host("@react-refresh")}'
      RefreshRuntime.injectIntoGlobalHook(window)
      window.$RefreshReg$ = () => {}
      window.$RefreshSig$ = () => (type) => type
      window.__vite_plugin_react_preamble_installed__ = true
    REACT_PREAMBLE_CODE
  end
end

#react_refresh_preambleObject

Public: The content of the preamble needed by the React Refresh plugin.



67
68
69
70
71
72
73
74
75
# File 'lib/vite_ruby/manifest.rb', line 67

def react_refresh_preamble
  if dev_server_running?
    <<~REACT_REFRESH
      <script type="module">
        #{react_preamble_code}
      </script>
    REACT_REFRESH
  end
end

#refreshObject

Public: Refreshes the cached mappings by reading the updated manifest files.



57
58
59
# File 'lib/vite_ruby/manifest.rb', line 57

def refresh
  @manifest = load_manifest
end

#resolve_entries(*names, **options) ⇒ Object

Public: Returns scripts, imported modules, and stylesheets for the specified entrypoint files.



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/vite_ruby/manifest.rb', line 44

def resolve_entries(*names, **options)
  entries = names.map { |name| lookup!(name, **options) }
  script_paths = entries.map { |entry| entry.fetch("file") }

  imports = dev_server_running? ? [] : entries.flat_map { |entry| import_chunks_for(entry) }
  {
    scripts: script_paths,
    imports: imports.filter_map { |entry| entry.fetch("file") }.uniq,
    stylesheets: dev_server_running? ? [] : (entries + imports).flat_map { |entry| entry["css"] }.compact.uniq,
  }
end

#vite_client_srcObject

Public: The path from where the browser can download the Vite HMR client.



62
63
64
# File 'lib/vite_ruby/manifest.rb', line 62

def vite_client_src
  prefix_asset_with_host("@vite/client") if dev_server_running?
end