Class: Lilac::CLI::PageCompiler
- Inherits:
-
Object
- Object
- Lilac::CLI::PageCompiler
- Defined in:
- lib/lilac/cli/build/page_compiler.rb
Overview
Compiles one source pages/*.html file into a dist HTML, given the
build-level BuildContext. Handles:
- page-inline `<script type="text/ruby">` extraction
- page-inline `<X data-component=...>` synthesis (Nokogiri pass)
- data-use=X reference scanning
- per-target / per-delivery dispatch (4 combos: full×inline,
full×bundle, compiled×inline, compiled×bundle — including the
chained .mrb boot module for compiled×bundle×page-inline)
The outer Builder.build constructs the context once and invokes
compile(page_path) for each page; the compiler itself holds no
build-level state. See ADR-29 for the data-component / data-use
split and decisions §20.6 for the Lilac.start placement rationale.
Defined Under Namespace
Classes: Injection
Constant Summary collapse
- DATA_USE_PATTERN =
Matches
data-use="X"/data-use='X'attribute values on any element. We don't need to know which tag carries the attribute — just collect the referenced component names so the build can bundle their templates + scripts into the page. %r{ \bdata-use\s*=\s*(?:"([^"]+)"|'([^']+)') }x
Instance Method Summary collapse
- #compile(page_path) ⇒ Object
-
#initialize(context) ⇒ PageCompiler
constructor
A new instance of PageCompiler.
Constructor Details
#initialize(context) ⇒ PageCompiler
Returns a new instance of PageCompiler.
48 49 50 51 52 53 |
# File 'lib/lilac/cli/build/page_compiler.rb', line 48 def initialize(context) @ctx = context @scripts_assembler = ComponentScriptsAssembler.new( template_cache: context.template_cache ) end |
Instance Method Details
#compile(page_path) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/lilac/cli/build/page_compiler.rb', line 55 def compile(page_path) html = File.read(page_path) # Inline `<script type="text/ruby">` blocks in the page itself are # surfaced to the injection step so they're not silently dropped on # the compiled target. The tags themselves stay in the dist HTML # for both targets: # - target=full — the runtime parser evaluates them in place # via `vm.evalScript` # - target=compiled — the wasm has no parser so the tags are # dead text (browser ignores `text/ruby`), but they remain # so "view source" works, and features like the 7guis # `source-display` mirror still find the page's Ruby. Size # cost is marginal (a few KB, fully compressible) and the # `.mrb` value prop (no parser in wasm) is unaffected extracted = SFC.extract_inline_ruby_scripts(html, path: page_path) page_inline_scripts = extracted[:scripts] # Page-inline `<X data-component="...">` elements are folded into # the same pipeline that handles `.lil` components: we register # an in-memory `SFC::Component` for each (snapshot of the # element's outer HTML). data-each rows stay IN-PLACE (the runtime # scanner snapshots the live innerHTML and clones per item), and # runtime resolves `refs.lilN` positionally, so nothing else # about the page markup needs to change. components, html, used_inline, synthesized_names = synthesize_page_inline_components( html, page_path: page_path ) # R4: page-inline script classes that collide with `.lil`-derived # class names (project-global) are flagged here. Done AFTER # synthesize_page_inline_components so synthesized in-memory # components (which carry no script) don't trigger false positives, # but BEFORE build_injection so the user sees a structured error # instead of a downstream mrbc failure. @ctx.build_linter.check_class_name_collisions!(page_inline_scripts, components, synthesized_names, page_path) used = used_inline.dup # Page references to components via data-use="X" — the runtime # injects markup from the matching <template>...<div data-component="X"> # definition that build_injection emits below. We only need to # record each X in `used` so its template + script land in the # injection bundle. html.scan(DATA_USE_PATTERN) do |dq, sq| name = dq || sq unless components.key?(name) raise Builder::Error, "Unknown component referenced by data-use=#{name.inspect} in #{page_path} " \ "(no components/#{name}.lil and no page-inline data-component=#{name.inspect})" end used << name end html = if @ctx.delivery == :bundle inject_bundle_page(html, page_path, used, components, page_inline_scripts: page_inline_scripts, synthesized_names: synthesized_names) else inject_inline_page(html, page_path, used, components, page_inline_scripts: page_inline_scripts, synthesized_names: synthesized_names) end File.write(output_path_for(page_path).tap { |p| FileUtils.mkdir_p(File.dirname(p)) }, html) end |