class AssetPipeline::FrontLoader

Overview

The asset pipeline is responsible for loading assets from the import maps, asset loader and compiling styling.

Use the FrontLoader class to initialize and manage your asset pipeline as a whole.

How to use Import Maps

Using import maps is simple. A default "application" import map is created when a AssetPipeline::FrontLoader is initialized:

front_loader = AssetPipeline::FrontLoader.new
import_map = front_loader.get_import_map
import_map.add_import("someClass", "your_file.js")
front_loader.render_import_map_tag # Generates the import map tag and any module preload directives

You can also specify the name of your import map by initializing the with an import map

front_loader = AssetPipeline::FrontLoader.new(import_map: AssetPipeline::ImportMap.new(name: "my_import_map"))
import_map = front_loader.get_import_map("my_import_map") # You must specify the import map by the name you created
import_map.add_import("someClass", "your_file.js")
front_loader.render_import_map_tag("my_import_map") # You must specify the name of the import map by the name you created

If you need to create multiple import maps, the initializer can take a block:

front_loader = AssetPipeline::FrontLoader.new do |import_maps|
  import_map1 = AssetPipeline::ImportMap.new
  import_map1.add_import("stimulus", "https://cdn.jsdelivr.net/npm/[email protected]/+esm", preload: true)

  import_map2 = AssetPipeline::ImportMap.new("admin_area")
  import_map2.add_import("alpine", "https://cdn.jsdelivr.net/npm/[email protected]/+esm")

  import_maps << import_map1
  import_maps << import_map2
end

front_loader.render_import_map_tag               # Renders the import_map1 using the default "application" name
front_loader.render_import_map_tag("admin_area") # Renders the import_map2. Tip: only 1 import map should be on a page

Read more about the ImportMap class to know all of your options, including the 'preload' and 'scope' feature.

Defined in:

asset_pipeline.cr

Constructors

Instance Method Summary

Constructor Detail

def self.new(js_source_path : Path = Path.new("src/app/javascript"), js_output_path : Path = Path.new("public/assets/"), import_maps : Array(ImportMap) = [] of ImportMap, clear_cache_upon_change : Bool = true) #

The default initializer for the FrontLoader class.


[View source]
def self.new(js_source_path : Path = Path.new("src/app/javascript"), js_output_path : Path = Path.new("public/assets/"), import_map : ImportMap = ImportMap.new, clear_cache_upon_change : Bool = true) #

[View source]
def self.new(js_source_path : Path = Path.new("src/app/javascript/"), js_output_path : Path = Path.new("public/assets"), clear_cache_upon_change : Bool = true, &) #

Initialize the asset pipeline with the given block.

The block is the import maps that will be used by the asset pipeline.

Set clear_cache_upon_change to false to disable automatic clearing of the output path before generating new cached files. By default, cache clearing is enabled to prevent accumulation of old cached files.


[View source]

Instance Method Detail

def analyze_code_complexity(custom_js_block : String) #

Analyzes code complexity and provides organization suggestions

Returns metrics about the JavaScript code including:

  • lines: Number of non-empty lines
  • functions: Number of function definitions
  • classes: Number of class definitions
  • event_listeners: Number of event listener registrations
  • suggestions: Array of code organization recommendations
complexity = front_loader.analyze_code_complexity(large_javascript_block)
puts "Lines: #{complexity[:lines]}"
puts "Suggestions: #{complexity[:suggestions]}"

[View source]
def analyze_javascript_dependencies(custom_js_block : String, import_map_name : String = "application") : Hash(Symbol, Array(String)) #

Analyzes JavaScript dependencies in a custom code block

Returns a hash containing:

  • :external - Array of detected external library names (e.g., ["jquery", "lodash"])
  • :local - Array of detected local module names (e.g., ["MyClass", "UtilityHelper"])
  • :suggestions - Array of human-readable import suggestions
analysis = front_loader.analyze_javascript_dependencies("$('.modal').show(); MyClass.init();")
puts analysis[:external]    # => ["jquery"]
puts analysis[:local]       # => ["MyClass"]
puts analysis[:suggestions] # => ["Add to import map: import_map.add_import(...)"]

[View source]
def framework_capabilities #

Returns information about supported frameworks and their capabilities

front_loader.framework_capabilities
# => {
#   "supported_frameworks" => ["stimulus"],
#   "registry_summary" => {...}
# }

[View source]
def generate_dependency_report(custom_js_block : String, import_map_name : String = "application") : String #

Generates a comprehensive development report for JavaScript analysis

This method provides detailed information about:

  • Detected dependencies (external and local)
  • Code complexity metrics
  • Import suggestions
  • Code organization recommendations

Useful for development and debugging to understand what the dependency analyzer detected.

report = front_loader.generate_dependency_report(my_javascript_code)
puts report

[View source]
def generate_file_version_hash(import_map_name : String = "application") #

Generates the file hash and appends it to the file name. :nodoc:


[View source]
def get_dependency_suggestions(custom_js_block : String, import_map_name : String = "application") : Array(String) #

Gets import suggestions for detected but missing dependencies

Analyzes the JavaScript block and returns suggestions for dependencies that are used in the code but not present in the import map.

suggestions = front_loader.get_dependency_suggestions("moment().format('YYYY-MM-DD')")
puts suggestions # => ["Add to import map: import_map.add_import("moment", "https://...")"]

[View source]
def get_import_map(name : String = "application") : AssetPipeline::ImportMap #

Gets the import map with the given name.

Default name is "application".


[View source]
def import_maps : Array(ImportMap) #

[View source]
def import_maps=(import_maps : Array(ImportMap)) #

[View source]
def render_framework_script(framework_name : String, custom_js_block : String = "", import_map_name : String = "application") : String #

Renders a framework-specific initialization script using the framework registry

This method provides a generic interface for rendering framework-specific scripts based on the registered framework renderers. It automatically detects and uses the appropriate renderer for the specified framework.

front_loader.render_framework_script("stimulus", "// Custom code", "application")
front_loader.render_framework_script("alpine", "// Alpine setup", "application")

The framework_name specifies which framework renderer to use (e.g., "stimulus", "alpine"). The custom_js_block parameter contains any custom JavaScript code to include. The import_map_name specifies which import map to use (defaults to "application").

Returns an empty string if the framework is not registered.


[View source]
def render_import_map_as_file(name : String = "application") : String #

Returns the url to the import_map.json file that has been generated

Warning: currently there is minimal browser support for this part of the spec. Please test thoroughly before using this approach.


[View source]
def render_import_map_tag(name : String = "application") : String #

Returns the named import map JSON as a rendered, non-minified, string.


[View source]
def render_initialization_script(custom_js_block : String = "", import_map_name : String = "application") : String #

Renders a general JavaScript initialization script with imports and custom code

This method generates a complete <script type="module"> tag containing:

  • Import statements based on the specified import map
  • Custom JavaScript initialization code
front_loader.render_initialization_script("console.log('App initialized');", "application")

The custom_js_block parameter contains any custom JavaScript code to include in the script. The import_map_name specifies which import map to use for generating imports (defaults to "application").


[View source]
def render_initialization_script_with_analysis(custom_js_block : String = "", import_map_name : String = "application") : String #

Renders a JavaScript initialization script with dependency analysis and warnings

This enhanced version includes comments about potentially missing dependencies to assist with development. It analyzes the custom JavaScript block and provides warnings about external libraries or local modules that may need to be added to the import map.

front_loader.render_initialization_script_with_analysis("$('#app').fadeIn();", "application")
# Includes comment: "// WARNING: Add to import map: import_map.add_import("jquery", "...")"

The custom_js_block parameter contains any custom JavaScript code to analyze and include.


[View source]
def render_stimulus_initialization_script(custom_js_block : String = "", import_map_name : String = "application") : String #

Renders a Stimulus-specific initialization script with automatic controller detection

This method generates a complete <script type="module"> tag containing:

  • Stimulus core imports (@hotwired/stimulus)
  • Automatic controller imports based on import map entries
  • Stimulus application initialization and controller registration
  • Custom JavaScript initialization code (with automatic filtering of redundant code)
front_loader.render_stimulus_initialization_script("// Custom initialization code", "application")

The renderer automatically:

  • Detects controller classes from import map entries ending in "Controller"
  • Generates proper controller registrations with kebab-case identifiers
  • Filters out duplicate import and registration statements from custom code
  • Sets up the Stimulus application with proper startup sequence

The custom_js_block parameter contains any custom JavaScript code to include. The import_map_name specifies which import map to use (defaults to "application").


[View source]