# Marko Linter ## Probable Errors ### Implicit change handler in rest attributes Bad: ```htmlembedded= <attrs/{ foo, ...others }/> <input #value:=foo> ``` Good: ```htmlembedded= <attrs/{ foo, fooChange, ...others }/> <input #value:=foo> ``` ### Defining the same attribute twice Bad: ```htmlembedded= <let/x=1 value=2/> <my-tag foo=defaultFoo ...others foo=overrideFoo/> ``` ### Dynamic tag string that refers to marko tag Bad: ```htmlembedded= // when `@ebay/ebayui-core` is installed <${input.condition ? "ebay-button" : "ebay-menu-button"}/> ``` Good: ```htmlembedded= import EbayButton from "<ebay-button>"; import EbayMenuButton from "<ebay-menu-button>"; <${input.condition ? EbayButton : EbayMenuButton}/> ``` ```htmlembedded= <${input.condition ? "button" : "a"}/> ``` ```htmlembedded= // strings can refer to web components // more specifically, as long as they don't resolve // to a marko component <${input.condition ? "paper-button" : "paper-menu-button"}/> ``` _could also create a tag lookup in dev mode to give runtime warnings when static analysis isn't possible_ ## Performance ### Async value passed to async attribute Bad: ```htmlembedded= <AsyncComponent foo=await barAsync/> ``` Good: ```htmlembedded= <SyncComponent foo=await barAsync/> <AsyncComponent foo=barSync/> ``` ## Opinions/Style ### Default attribute with named attributes Bad: ```htmlembedded= <attrs/{ default: foo, other }/> ``` Good: ```htmlembedded= <attrs/{ default: foo }/> ``` ### Use control directives Bad: ```htmlembedded= <input value=""/> <input type="checkbox" checked/> ``` Good: ```htmlembedded= <input #value=""/> <input type="checkbox" #checkedValue=.../> ``` ### Avoid shadowing Marko custom tags Bad: ```htmlembedded= <const/Foo = "div"/> <Foo/> // if there already exists a custom <Foo> tag ``` Bad: ``` app/ ├─ node_modules/ │ ├─ FooTaglib/ │ │ ├─ components/ │ │ │ ├─ Foo.marko ├─ components/ │ ├─ Foo.marko ```