{"id":13826958,"url":"https://github.com/egoist/lit-vue","last_synced_at":"2025-04-09T23:15:11.204Z","repository":{"id":45274966,"uuid":"164230230","full_name":"egoist/lit-vue","owner":"egoist","description":"🔥 Vue SFC goodies directly in JavaScript files.","archived":false,"fork":false,"pushed_at":"2021-12-25T14:38:24.000Z","size":197,"stargazers_count":240,"open_issues_count":5,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-09T23:15:03.787Z","etag":null,"topics":["i-hope-it-works-for-you","sfc","vue","webpack"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/egoist.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-05T16:07:27.000Z","updated_at":"2025-02-28T03:02:39.000Z","dependencies_parsed_at":"2022-09-14T05:02:01.257Z","dependency_job_id":null,"html_url":"https://github.com/egoist/lit-vue","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Flit-vue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Flit-vue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Flit-vue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Flit-vue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/egoist","download_url":"https://codeload.github.com/egoist/lit-vue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248125591,"owners_count":21051770,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["i-hope-it-works-for-you","sfc","vue","webpack"],"created_at":"2024-08-04T09:01:47.458Z","updated_at":"2025-04-09T23:15:11.080Z","avatar_url":"https://github.com/egoist.png","language":"JavaScript","funding_links":["https://patreon.com/egoist","https://www.patreon.com/egoist"],"categories":["JavaScript"],"sub_categories":[],"readme":"# lit-vue\n\n[![NPM version](https://badgen.net/npm/v/lit-vue)](https://npmjs.com/package/lit-vue) [![NPM downloads](https://badgen.net/npm/dm/lit-vue)](https://npmjs.com/package/lit-vue) [![CircleCI](https://badgen.net/circleci/github/egoist/lit-vue/master)](https://circleci.com/gh/egoist/lit-vue/tree/master) [![donate](https://badgen.net/badge/support%20me/donate/ff69b4)](https://patreon.com/egoist) [![chat](https://badgen.net/badge/chat%20on/discord/7289DA)](https://chat.egoist.moe)\n\n**Please consider [donating](https://www.patreon.com/egoist) to this project's author, [EGOIST](#author), to show your ❤️ and support.**\n\n## Motivation\n\n- Use all Vue SFC features in JavaScript / TypeScript files\n- Type-safe Vue templates ([#1](https://github.com/egoist/lit-vue/issues/1))\n\nCombine `vue-loader` and `lit-vue/loader` to make the dream come to reality.\n\n## Install\n\n```bash\nyarn add lit-vue --dev\n```\n\n## Example\n\nPreviously you can use `.vue` single-file component like this:\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv\u003e\n    \u003ch1\u003ehello\u003c/h1\u003e\n    \u003chr /\u003e\n    \u003cbutton @click=\"inc\"\u003e{{ count }}\u003c/button\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n  data() {\n    return {\n      count: 0\n    }\n  },\n  methods: {\n    inc() {\n      this.count++\n    }\n  }\n}\n\u003c/script\u003e\n\n\u003cstyle scoped\u003e\nh1 {\n  color: red;\n}\n\u003c/style\u003e\n```\n\nNow with `lit-vue` you can use `.js` and `.ts` extensions:\n\n```js\nimport { html } from 'lit-vue'\n\nhtml`\n  \u003ctemplate\u003e\n    \u003cdiv\u003e\n      \u003ch1\u003ehello\u003c/h1\u003e\n      \u003chr /\u003e\n      \u003cbutton @click=\"inc\"\u003e{{ count }}\u003c/button\u003e\n    \u003c/div\u003e\n  \u003c/template\u003e\n\n  \u003cstyle scoped\u003e\n    h1 {\n      color: red;\n    }\n  \u003c/style\u003e\n`\n\nexport default {\n  data() {\n    return {\n      count: 0\n    }\n  },\n  methods: {\n    inc() {\n      this.count++\n    }\n  }\n}\n```\n\n\u003cdetails\u003e\u003csummary\u003eYou might need to configure the ESLint rule: no-unused-expressions\u003c/summary\u003e\u003cbr\u003e\n\nESLint might complain about the the \u003ccode\u003ehtml\u0026#x60;\u0026#x60;\u003c/code\u003e expression not being used when you enabled the rule: [no-unused-expressions](http://eslint.cn/docs/rules/no-unused-expressions), there're three ways to solve it:\n\n1. Disable this rule for tagged template expression in your ESLint config\n\n```json\n{\n  \"rules\": {\n    \"no-unused-expressions\": [\"error\", { \"allowTaggedTemplates\": true }]\n  }\n}\n```\n\n2. Or export it\n\n```js\nexport const template = html`\n  \u003ctemplate\u003e\n    \u003cdiv\u003e{{ count }}\u003c/div\u003e\n  \u003c/template\u003e\n`\n```\n\nYou can just assign it to a variable and export it, though the exported variable will never be used. The return value of `html` tag is always undefined.\n\n3. Or use it as component option\n\n```js\nconst template = html`\n  \u003ctemplate\u003e\n    \u003cdiv\u003e{{ count }}\u003c/div\u003e\n  \u003c/template\u003e\n`\n\nexport default {\n  template,\n  data() {\n    return {\n      count: 0\n    }\n  }\n}\n```\n\nSimilar to #2, this may look more natural because `template` is a legit Vue component option.\n\n\u003c/details\u003e\n\n## How to use\n\n### Use with webpack\n\n```js\nmodule.exports = {\n  module: {\n    rules: [\n      {\n        // Match .js .ts files\n        test: [/\\.[jt]s$/],\n        // Exclude .vue.js .vue.ts files\n        // Since we want lit-vue to transform them into Vue SFC instead\n        exclude: [/\\.vue.[jt]s/]\n        loader: 'babel-loader' // Use your desired loader\n      },\n      // Handle .vue.js .vue.ts with lit-vue/loader and vue-loader\n      {\n        test: [/\\.vue.[jt]s$/],\n        use: [\n          'vue-loader',\n          'lit-vue/loader'\n        ]\n      },\n      // This rule is also necessary even if you don't directly use .vue files\n      {\n        test: /\\.vue$/,\n        loader: 'vue-loader'\n      }\n    ]\n  }\n}\n```\n\nThat's it, [all the goodies](https://vue-loader.vuejs.org/) of `.vue` SFC are available in your `.vue.js` and `.vue.ts` files now!\n\n### Optional `\u003ctemplate\u003e` element\n\n`\u003ctemplate\u003e` inside `html` is optional:\n\n```js\nhtml`\n  \u003ch1\u003ehello\u003c/h1\u003e\n`\n\n// or\n\nhtml`\n  \u003ctemplate\u003e\n    \u003ch1\u003ehello\u003c/h1\u003e\n  \u003c/template\u003e\n`\n```\n\nWhen using templates without `\u003ctemplate\u003e` tag, you have to use `\u003ccustom-block\u003e` element to define custom blocks:\n\n```js\nhtml`\n  \u003ch1\u003ehello\u003c/h1\u003e\n\n  \u003ccustom-block name=\"i18n\"\u003e {\"en\": {}} \u003c/custom-block\u003e\n`\n\n// or\n\nhtml`\n  \u003ctemplate\u003e\n    \u003ch1\u003ehello\u003c/h1\u003e\n  \u003c/template\u003e\n\n  \u003ci18n\u003e {\"en\": {}} \u003c/i18n\u003e\n`\n```\n\nAnd in fact even the whole Vue template is optional in `html` tag, you can just use `\u003cstyle\u003e` and custom blocks with render function instead:\n\n```js\nimport Vue from 'vue'\nimport Component from 'vue-class-component'\nimport { html } from 'lit-vue'\n\nhtml`\n  \u003cstyle scoped\u003e\n    .msg {\n      color: red;\n    }\n  \u003c/style\u003e\n`\n\n@Component({\n  props: {\n    name: String\n  }\n})\nexport default class Welcome extends Vue {\n  // computed\n  get message() {\n    return 'hello ' + this.name\n  }\n\n  render() {\n    return \u003cdiv class=\"msg\"\u003e{this.message}\u003c/div\u003e\n  }\n}\n```\n\n### Syntax higlighting\n\nTo highlight the code inside `html` template tag, you can use following editor plugins:\n\n- VSCode: [lit-html](https://marketplace.visualstudio.com/items?itemName=bierner.lit-html)\n- Something is missing? Send a PR to add it here!\n\n## Contributing\n\n1. Fork it!\n2. Create your feature branch: `git checkout -b my-new-feature`\n3. Commit your changes: `git commit -am 'Add some feature'`\n4. Push to the branch: `git push origin my-new-feature`\n5. Submit a pull request :D\n\n## Author\n\n**lit-vue** © EGOIST, Released under the [MIT](./LICENSE) License.\u003cbr\u003e\nAuthored and maintained by EGOIST with help from contributors ([list](https://github.com/egoist/lit-vue/contributors)).\n\n\u003e [Website](https://egoist.sh) · GitHub [@EGOIST](https://github.com/egoist) · Twitter [@\\_egoistlily](https://twitter.com/_egoistlily)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegoist%2Flit-vue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegoist%2Flit-vue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegoist%2Flit-vue/lists"}