{"id":43496035,"url":"https://github.com/michaelolof/vue-literal-compiler","last_synced_at":"2026-02-03T10:37:14.671Z","repository":{"id":33969429,"uuid":"163998510","full_name":"michaelolof/vue-literal-compiler","owner":"michaelolof","description":"A Vue Compiler that allows you compile your string literals to render functions at build time and write components in SFC paradigm","archived":false,"fork":false,"pushed_at":"2023-01-07T02:42:49.000Z","size":1103,"stargazers_count":155,"open_issues_count":13,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-04T00:56:41.594Z","etag":null,"topics":["single-file-component","template-literals","type-safety","typescript","vue","vue-components","vue-loader","vue-template-compiler","vue-template-loader"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/michaelolof.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-03T16:41:56.000Z","updated_at":"2025-03-31T13:23:32.000Z","dependencies_parsed_at":"2023-01-15T03:41:20.635Z","dependency_job_id":null,"html_url":"https://github.com/michaelolof/vue-literal-compiler","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/michaelolof/vue-literal-compiler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvue-literal-compiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvue-literal-compiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvue-literal-compiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvue-literal-compiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaelolof","download_url":"https://codeload.github.com/michaelolof/vue-literal-compiler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvue-literal-compiler/sbom","scorecard":{"id":641427,"data":{"date":"2025-08-11","repo":{"name":"github.com/michaelolof/vue-literal-compiler","commit":"53f606bd3da6897f8399f786ca7101e1a80f426a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.3,"checks":[{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"54 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-vh7m-p724-62c2","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-g6ww-v8xp-vmwg","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-566m-qj78-rww5","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-h9rv-jmmf-4pgx","Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-g3ch-rx76-35fx","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T10:53:00.355Z","repository_id":33969429,"created_at":"2025-08-21T10:53:00.355Z","updated_at":"2025-08-21T10:53:00.355Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29041777,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T10:09:22.136Z","status":"ssl_error","status_checked_at":"2026-02-03T10:09:16.814Z","response_time":96,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["single-file-component","template-literals","type-safety","typescript","vue","vue-components","vue-loader","vue-template-compiler","vue-template-loader"],"created_at":"2026-02-03T10:37:14.024Z","updated_at":"2026-02-03T10:37:14.658Z","avatar_url":"https://github.com/michaelolof.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vue Literal Compiler\nA simple stand in replacement for the default vue-template-compiler that allows you write Vue Templates, Scoped CSS, Custom Blocks and Scripts in SFC format all in your JavaScript/TypeScript files.\n\n## Preview \n![alt-text](https://github.com/michaelolof/vue-literal-compiler/blob/master/images/vue-vs-lit-preview.png?raw=true)\n\n## Motivation\n* Maintain the SFC paradigm. Write all your Templates, Styles and Scripts in one file (JavaScript/TypeScript)\n* Compiles your literal templates into render functions at compile time rather than at runtime.\n* Provide Support for CSS in JavaScript/TypeScript.\n* Provide Support for Scoped CSS\n* Provide support for SASS, SCSS, LESS etc. using the lang attribute.\n* Provide Support for Custom Blocks in JavaScript/TypeScript.\n* Provide Support for lintable typesafe templates using Functional Templates\n\n## Change Log\n  - ### v 1.2.6\n    - Added Support for Type Safe `v-for` bindings.\n  - ### v 1.2.5\n    - Opening and Closing Style Tags `\u003cstyle\u003e\u003c/style\u003e` are now optional. (They will be global by default)\n    - Added Support for Functional Templates.\n\n## See Working Examples\n* [Vue Literal Compiler Sample](https://github.com/michaelolof/vue-literal-compiler-sample)\n\n## Get Started\n- ### [Installation](#installation)\n- ### [API](#api)\n- ### [Painless Migration / Testing](#painless-migration-testing)\n- ### [Why `.lit.*` files?](#why-lit-files)\n- ### [Type Safe Bindings vs Type Safe Templates.](#type-bindings-vs-type-templates)\n\n\n## \u003ca name=\"installation\"\u003eInstallation\u003c/a\u003e\n\n1.  Install Vue Literal Compiler\n```\n  npm install --save-dev vue-literal-compiler\n```\n\n2.  Include it in your webpack.config.js vue-loader options.\n```js\n{\n  test: /\\.lit\\.ts$/,\n  loader: 'vue-loader',\n  options: {\n    compiler: require(\"vue-literal-compiler\"),\n  }\n},\n```\n3.  Add an additional Vue Loader Configuration. This is to appease VueLoaderPlugin and prevent it from squawking. See issue https://github.com/vuejs/vue-loader/issues/1238\n```js\n{\n  test: /\\.vue$/,\n  loader: \"vue-loader\"\n},\n  \n{\n  test: /\\.lit\\.ts$/,\n  loader: 'vue-loader',\n  options: {\n    compiler: require(\"vue-literal-compiler\"),\n    loaders: {\n      'scss': 'vue-style-loader!css-loader!sass-loader',\n      'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',\n    }\n  }\n},\n```\n\n4.  Finally since we're using plain TypeScript / JavaScript files rather than .vue files, ts-loader or babel will attempt to parse our files. We have to stop this.\\\nSo in ts-loader's config we do this.\n\n```js\n{\n  test: /\\.tsx?/,\n  loader: 'ts-loader',\n  exclude: [ /node_modules/, /\\.lit.ts$/ ],\n  options: {\n    appendTsSuffixTo: [/\\.vue$/],\n  }\n},\n```\n\n## \u003ca name=\"api\"\u003eAPI\u003c/a\u003e\nWIth `.vue` files we're used to putting our html, css (sass, less etc) and scripts (javascript or typescript) all in one file. It gave us the ability to reason about our components as a single unit in a single location.\\\nThis is also very possible with Vue Literal Compiler.\n\n### Templates\nSo with a `.vue` file we can define our templates like this:\n```html\n\u003ctemplate\u003e\n  \u003cdiv class=\"app\"\u003e\n    \u003ch1\u003e {{ greeting }} \u003c/h1\u003e\n    \u003cbutton @click=\"sayHi()\"\u003e\u003c/button\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\nThe same template in a plain javascript/typescript file will look like this.\n```ts\n/** @VueLiteralCompiler Template */\nconst template = `\n  \u003cdiv class=\"app\"\u003e\n    \u003ch1\u003e {{ greeting }} \u003c/h1\u003e\n    \u003cbutton @click=\"sayHi()\"\u003e\u003c/button\u003e\n  \u003c/div\u003e\n`;\n```\nNotice you don't need the template tag to define a template.\\\nIf we wanted to support multiple languages just like in `.vue` files, we simply add the template tag back with a lang atrribute.\n```ts\n/** @VueLiteralCompiler Template */\nconst template = `\n  \u003ctemplate lang=\"jade\"\u003e\n    div\n      p {{ greeting }} World!\n      other-component\n    \u003c/div\u003e\n  \u003c/template\u003e  \n`;\n```\n### Fat Arrow Templates\nA Fat arrow template is one which accepts one parameter (the instance of your vue component) and returns a string (the template literal)\\\nTo use a fat arrow template simply change the template variable from a string to a function that takes one parameter and returns a string.\\\n**NOTE - You must use a fat arrow. Regular functions will not work**\n```ts\n/** @VueLiteralCompiler Template */\nconst template = app =\u003e `\n  \u003cdiv class=\"app\"\u003e\n    \u003ch1\u003e ${ app.greeting } \u003c/h1\u003e\n    \u003cbutton @click=\"sayHi()\"\u003e\u003c/button\u003e\n  \u003c/div\u003e\n`;\n```\nNotice you can easily switch between using string literals variable encapsulation `\u003ch1\u003e app.greeting \u003c/h1\u003e` and your regular vue template style `\u003cbutton @click=\"sayHi()\"\u003e\u003c/button\u003e`\\\nIt just works.\\\nTo support intellisense and code refractoring support in TypeScript, just type hint app\n```ts\nconst template = (app:App) =\u003e `\n  \u003cdiv class=\"app\"\u003e\n    \u003ch1\u003e ${ app.greeting } \u003c/h1\u003e\n    \u003cbutton @click=\"${ app.sayHi() }\"\u003e\u003c/button\u003e\n  \u003c/div\u003e\n`;\n```\nAt this point `app.greeting` and `app.sayHi()` is now type safe.\\\n\\\nTo support syntax highlighting for VSCode simply install an extension like vscode-lit-html and tag your string literals as defined by the installed extension.\n\n### Styles\nStyles are defined in `.vue` files using a style tag\n```html\n\u003cstyle\u003e\n  .p {\n    font-size: 2em;\n    text-align: center;\n  }\n\u003c/style\u003e\n```\nTo do the same using a Vue Literal Compiler:\n```ts\n/** @VueLiteralCompiler Styles */\nconst styles = `\n  \u003cstyle\u003e\n    .p {\n      font-size: 2em;\n      text-align: center;\n    }\n  \u003c/style\u003e\n`;\n```\nTo Support scoped styles, preprocessor support or multiple styles.\n```ts\n/** @VueLiteralCompiler Styles */\nconst styles = `\n  \u003cstyle scoped lang=\"scss\"\u003e\n    .p {\n      font-size: 2em;\n      text-align: center;\n      \n      \u0026 span {\n        font-weight: bold;\n      }\n    }\n  \u003c/styles\u003e\n\n  \u003cstyle\u003e\n    body {\n      background-color: gray;\n    }\n  \u003c/style\u003e\n`;\n```\nThe opening and closing style tags can also be optional\n```ts\n/** @VueLiteralCompiler Styles */\nconst styles = `\n  .p {\n    font-size: 2em;\n    text-align: center;\n  }\n`;\n```\nOptional Style Tags are global by default.\n\n### Custom Blocks\nA custom block in a `.vue` file would look this:\n```html\n\u003ccustom-block\u003e\n  \u003ch1\u003eHello World\u003c/h1\u003e\n  \u003cp\u003eJust make sure things work.\u003c/p\u003e\n\u003c/custom-block\u003e\n\n\u003canother-custom-block\u003e\n  \u003cp\u003eThis is how we rock\u003c/p\u003e\n\u003c/another-custom-block\u003e\n```\nThe same with Vue Literal Compiler will look like this.\n```ts\n/** @VueLiteralCompiler Custom Block */\nconst customBlock = `\n  \u003ccustom-block\u003e\n    \u003ch1\u003eHello World\u003c/h1\u003e\n    \u003cp\u003eJust make sure things work.\u003c/p\u003e\n  \u003c/custom-block\u003e\n`;\n\n/** @VueLiteralCompiler Custom Block */\nconst anotherCustomBlock = `\n  \u003canother-custom-block\u003e\n    \u003cp\u003eThis is how we rock\u003c/p\u003e\n  \u003c/another-custom-block\u003e\n`;\n```\n\n## \u003ca name=\"painless-migration-testing\"\u003ePainless Migration / Testing\u003c/a\u003e\nOne of the immediate advantages of Vue Literal Compiler is the painless interoperability with existing `.vue` code base. You can use Vue Literal Compiler (`.lit.*`) side by side with your existing `.vue` **today**. To do that simply modify your webpack.config.js\n```js\n{\n  test: /\\.tsx?/,\n  loader: 'ts-loader',\n  exclude: [ /node_modules/, /\\.lit.ts$/ ],\n  options: {\n    appendTsSuffixTo: [/\\.vue$/],\n  }\n},\n{ \n  test: /\\.vue$/, \n  loader: 'vue-loader' \n  options: {\n    loaders: {\n      // Since sass-loader (weirdly) has SCSS as its default parse mode, we map\n      // the \"scss\" and \"sass\" values for the lang attribute to the right configs here.\n      // other preprocessors should work out of the box, no loader config like this necessary.\n      'scss': 'vue-style-loader!css-loader!sass-loader',\n      'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',\n    }\n  }\n},\n{\n  test: /\\.lit\\.ts$/,\n  loader: 'vue-loader',\n  options: {\n    compiler: require(\"vue-literal-compiler\"),\n    loaders: {\n      // Since sass-loader (weirdly) has SCSS as its default parse mode, we map\n      // the \"scss\" and \"sass\" values for the lang attribute to the right configs here.\n      // other preprocessors should work out of the box, no loader config like this necessary.\n      'scss': 'vue-style-loader!css-loader!sass-loader',\n      'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',\n    }\n  }\n},\n```\nAt this point migrating your code base from `.vue` to `.lit.ts` or `.lit.js` is just a matter of copying and pasting your templates, styles and scripts respectively.\n\n## \u003ca name=\"why-lit-files\"\u003eWhy `.lit.*` files?\u003c/a\u003e\nWhile Vue Literal Compiler doesn't discriminate against file extension types (Whatever test case you put in your webpack config is what the compiler will use.) There are some reasons you might want to use .lit.* files over .vue.* files though.\n### 1. Standards\nFirst Vue Literal Compiler doesn't care what file type you use. But standards are important.\n### 2. Interoperability with exisiting `.vue` files\nUsing  `.vue.ts` or `.vue.js` with an existing code base of `.vue` files can cause unexpected errors due to name clashes. This is due to the way `vue-loader` and `ts-loader` work internally. To avoid this when working with an existing codebase of `.vue` files, just use a different file type aside from `.vue.ts` or `.vue.js`. \n\n## \u003ca name=\"type-bindings-vs-type-templates\"\u003eType Safe Bindings vs Type Safe Templates\u003c/a\u003e\nWith Fat Arrow Templates and Variable Encapsulations **your bindings are type safe**. This is a different approach from DSLs like JSX/TSX which promises typesafe templates. \n\n\nWith type safe bindings we can maintain the regular vue syntax we are used to (i.e `v-show` or `v-if` instead of `teniary`, `v-for` instead of `map(...)`, `@click` etc.) and still get complete type safety.\n\n**Basic Data Binding:**\n\nNormal Vue syntax:\n```\n\u003cspan\u003eMessage: {{ msg }}\u003c/span\u003e\n```\nType Safe Alternative:\n```\n\u003cspan\u003eMessage: ${ app.msg }\u003c/span\u003e\n```\n\\\n**Attribute Data Bindings**\n\nNormal Vue Syntax:\n```\n\u003cdiv v-bind:id=\"dynamicId\"\u003e\u003c/div\u003e\n\n\u003cbutton v-bind:disabled=\"isButtonDisabled\"\u003eButton\u003c/button\u003e\n```\nType Safe Alternative:\n```\n\u003cdiv v-bind:id=\"${ app.dynamicId }\"\u003e\u003c/div\u003e\n\n\u003cbutton v-bind:disabled=\"${ app.isButtonDisabled }\"\u003eButton\u003c/button\u003e\n```\n\\\n**Using JavaScript Expressions**\n\nNormal Vue Syntax:\n```html\n{{ number + 1 }}\n\n{{ ok ? 'YES' : 'NO' }}\n\n{{ message.split('').reverse().join('') }}\n\n\u003cdiv v-bind:id=\"'list-' + id\"\u003e\u003c/div\u003e\n\n\u003cform v-on:submit.prevent=\"onSubmit\"\u003e ... \u003c/form\u003e\n\n\u003ca @click=\"doSomething\"\u003e ... \u003c/a\u003e\n```\n\nType Safe Alternative:\n```ts\n${ app.number + 1 }\n\n${ app.ok ? 'YES' : 'NO' }\n\n${ app.message.split('').reverse().join('') }\n\n\u003cdiv v-bind:id=\"${ 'list-' + app.id }\"\u003e\u003c/div\u003e\n\n\u003cform v-on:submit.prevent=\"${ app.onSubmit }\"\u003e ... \u003c/form\u003e\n\n\u003ca @click=\"${ app.doSomething() }\"\u003e ... \u003c/a\u003e\n```\n\\\n**Class And Style Bindings**\n\nNormal Vue Syntax:\n```html\n\u003cdiv v-bind:class=\"{ active: isActive, 'text-danger': hasError }\"\u003e\u003c/div\u003e\n\n\u003cdiv v-bind:class=\"[ activeClass, errorClass ]\"\u003e\u003c/div\u003e\n\n\u003cdiv v-bind:class=\"[ isActive ? activeClass : '', errorClass ]\"\u003e\u003c/div\u003e\n\n\u003cdiv v-bind:class=\"[ { active: isActive }, errorClass ]\"\u003e\u003c/div\u003e\n\n\u003cdiv v-bind:style=\"{ color: activeColor, fontSize: fontSize + 'px' }\"\u003e\u003c/div\u003e\n```\nType Safe Alternative:\n```ts\n\u003cdiv v-bind:class=\"${{ active: app.isActive, 'text-danger': app.hasError }}\"\u003e\u003c/div\u003e\n\n\u003cdiv v-bind:class=\"${[ app.activeClass, app.errorClass ]}\"\u003e\u003c/div\u003e\n\n\u003cdiv v-bind:class=\"${[ app.isActive ? app.activeClass : '', app.errorClass ]}\"\u003e\u003c/div\u003e\n\n\u003cdiv v-bind:class=\"${[ { active: app.isActive }, app.errorClass ]}\"\u003e\u003c/div\u003e\n\n\u003cdiv v-bind:style=\"${{ color: app.activeColor, fontSize: app.fontSize + 'px' }}\"\u003e\u003c/div\u003e\n```\n\\\n**List Rendering**\n\nList Rendering are sort of an edge case when it comes to type safety due to the way they are declared. (`v-for`s in Vue are not exactly JavaScript compliant.)\n\nA typical Vue List would look like this:\n```html\n\u003cul id=\"example-1\"\u003e\n  \u003cli v-for=\"item in items\"\u003e\n    {{ item.message }}\n  \u003c/li\u003e\n\u003c/ul\u003e\n```\nFollowing our normal convention, the Fat Arrow alternative should typically look like this:\n```ts\n\u003cul id=\"example-1\"\u003e\n  \u003cli v-for=\"${ app.item in app.items }\"\u003e\n    ${ app.item.message }\n  \u003c/li\u003e\n\u003c/ul\u003e\n```\nUnfortunately this would throw a compile time error in TypeScript saying `app.item` is not found.\n\nTo get around this error we need to do two things.\n\nFirst Create a Template Addon Interface\n```ts\ninterface TemplateAddOn {\n  _item: typeof App.prototype.items[0]\n}\n``` \nThen in the Fat Arrow Template:\n```ts\nconst template = (app:App \u0026 TemplateAddOn) =\u003e `\n  \u003cul id=\"example-1\"\u003e\n    \u003cli v-for=\"${ \u003cany\u003e app._item in app.items }\"\u003e\n      ${ app._item.message }\n    \u003c/li\u003e\n  \u003c/ul\u003e`\n```\nNow `app._item` is now recognized.\\\nThe underscore in `app._item` is just there to indicate to you that it is an addon and not part of your original component. (Feel free to use whatever you want.)\\\nThe cast to any however is necessary if `app._item` is not of type `number`, `string` or `symbol`.\\\n\n**Only `\u003cany\u003e` casts are supported by the compiler.**\n\nOther examples of type safe lists:\n```ts\n\u003cul id=\"example-2\"\u003e\n  \u003cli v-for=\"${ \u003cany\u003e (app._item, app._index) in app._items }\"\u003e\n    ${ app.parentMessage } - ${ app._index } - ${ app._item.message }\n  \u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cdiv v-for=\"${ \u003cany\u003e (app._value, app._key, app._index) in app.object }\"\u003e\n  ${ app._index }. ${ app._key }: ${ app._value }\n\u003c/div\u003e\n```\n ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelolof%2Fvue-literal-compiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaelolof%2Fvue-literal-compiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelolof%2Fvue-literal-compiler/lists"}