Makes the props contract between <.vue> and defineProps<T>() red before production.
The single source of truth is the Vue component's defineProps<T>(). A Mix compiler turns
every .vue file into assets/vue/contract.json (one JSON-Schema subset per component,
regenerated whenever a .vue/.ts source changes); this module checks the Elixir side
against it twice:
- at compile time, in
~Hand in the module's.heexfiles: every literal<.vue v-component="X" ...>(and every<.X>shortcut) must pass exactly the propsXdeclares — missing required prop, undeclared prop, unknown or ambiguous component name areCompileErrors; - at render time (dev and test), in
vue/1: the encoded props must match the nested schema — renamed key inside a list item, string instead of number, unexpectednullraiseArgumentErrorwith the JSON path. Off inprod.
Setup
# mix.exs
{:live_vue_contract, "~> 0.3"},
compilers: [:live_vue_contract, :phoenix_live_view] ++ Mix.compilers()
# lib/my_app_web.ex, in html_helpers, replacing `use LiveVue` and `use LiveVue.Components`
use LiveVueContract
$ npm install -D vue-component-meta typescriptThen mix compile writes assets/vue/contract.json — commit it, so CI and Docker builds
without node still get the compile-time check.
Options
shared_props: true— compile templates throughLiveVue.SharedPropsView(injectsv-socketandconfig :live_vue, :shared_props) instead of the plain~H.shortcuts: false— do not define<.ComponentName>functions.
Config
config :live_vue_contract,
vue_root: ["assets/vue"], # where the components live (like LiveVue.Components)
watch: [], # extra globs that regenerate the contract (prop types are tracked)
contract: "assets/vue/contract.json",
tsconfig: "tsconfig.json",
validate: Mix.env() != :prod, # render-time validation; :warn = log instead of raise
strict: false # extra nested keys: warning (false) or error (true)
Summary
Functions
~H that compiles as usual and then checks every <.vue> tag against the contract.
Drop-in for LiveVue.vue/1 that validates the props against the contract first.
Functions
~H that compiles as usual and then checks every <.vue> tag against the contract.
Drop-in for LiveVue.vue/1 that validates the props against the contract first.