{"id":13806995,"url":"https://github.com/kcmr/web-components-codemods","last_synced_at":"2025-04-12T11:20:36.326Z","repository":{"id":36939249,"uuid":"230902102","full_name":"kcmr/web-components-codemods","owner":"kcmr","description":"Codemods for Web Components. Breaking changes? Don't panic :)","archived":false,"fork":false,"pushed_at":"2025-03-13T15:03:57.000Z","size":447,"stargazers_count":8,"open_issues_count":36,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-26T06:04:49.082Z","etag":null,"topics":["cli","codemods","jscodeshift","web-components"],"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/kcmr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-30T11:15:42.000Z","updated_at":"2024-06-17T18:22:17.000Z","dependencies_parsed_at":"2024-01-28T12:23:56.959Z","dependency_job_id":"5d079658-51fa-4f49-b35a-092cd8aebe00","html_url":"https://github.com/kcmr/web-components-codemods","commit_stats":{"total_commits":112,"total_committers":6,"mean_commits":"18.666666666666668","dds":0.4553571428571429,"last_synced_commit":"716b879ae7f192020dc73be046299323399a5501"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kcmr%2Fweb-components-codemods","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kcmr%2Fweb-components-codemods/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kcmr%2Fweb-components-codemods/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kcmr%2Fweb-components-codemods/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kcmr","download_url":"https://codeload.github.com/kcmr/web-components-codemods/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248558123,"owners_count":21124223,"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":["cli","codemods","jscodeshift","web-components"],"created_at":"2024-08-04T01:01:19.141Z","updated_at":"2025-04-12T11:20:36.301Z","avatar_url":"https://github.com/kcmr.png","language":"JavaScript","funding_links":[],"categories":["Meta Frameworks"],"sub_categories":["Tools"],"readme":"# Web Components Codemods\n\n[![Build Status](https://travis-ci.com/kcmr/web-components-codemods.svg?branch=master)](https://travis-ci.com/kcmr/web-components-codemods)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![codecov](https://codecov.io/gh/kcmr/web-components-codemods/branch/master/graph/badge.svg)](https://codecov.io/gh/kcmr/web-components-codemods)\n![Dependency status](https://img.shields.io/david/kcmr/web-components-codemods.svg)\n\n[![NPM](https://nodei.co/npm/web-components-codemods.png?downloads=true\u0026downloadRank=true\u0026stars=true)](https://nodei.co/npm/web-components-codemods/)\n\nCodemods for Web Components.  \nBreaking changes? Don't panic :)\n\n## Table of contents\n\n- [Usage](#usage)\n  - [Using the included CLI](#using-the-included-cli)\n  - [Using jscodeshift](#using-jscodeshift)\n- [Available codemods](#available-codemods)\n  - [Replace attrs](#replace-attrs)\n  - [Replace block scope by IIFE](#replace-block-scope-by-iife)\n  - [Rename tag](#rename-tag)\n  - [LitElement to Lit imports](#litelement-to-lit-imports)\n- [Acknowledgments](#acknowledgments)\n\n## Usage\n\nThe available codemods can be run in two ways: by using the included CLI or running the transform scripts directly with jscodeshift.\n\n### Using the included CLI\n\nInstall this package globally:\n\n```bash\nnpm i -g web-components-codemods\n```\n\nRun the command in the directory you want to run a transform (the directory can be changed later):\n\n```bash\nkodemod\n```\n\nThe command will prompt you for the transform to run and all of its options.\n![kodemod CLI screenshot](https://raw.githubusercontent.com/kcmr/web-components-codemods/master/docs/images/kodemod-cli-screenshot.png)\n\nAlternatively, you can run a specific transform by running `kodemod \u003ctransform\u003e`.\n\nExample:\n\n```bash\nkodemod replace-attrs\n```\n\nAvailable transform commands (same as transform scripts):\n\n- [replace-attrs](#replace-attrs)\n- [block-scope-to-iife](#replace-block-scope-by-iife)\n- [rename-tag](#rename-tag)\n- [lit-element-to-lit-imports](#litelement-to-lit-imports)\n\n### Using jscodeshift\n\nInstall [jscodeshift](https://github.com/facebook/jscodeshift) globally:\n\n```bash\nnpm i -g jscodeshift\n```\n\nClone or download this repository:\n\n```bash\nnpx degit kcmr/web-components-codemods\n```\n\nRun `jscodeshift` passing the transform script with the `-t` option:\n\n```bash\njscodeshift target-dir/*.js -t web-components-codemods/\u003ctransform-script\u003e.js\n```\n\n## Available codemods\n\n### Replace attrs\n\nReplaces attributes in the specified tag inside a template literal tagged `html` (LitElement or lit-html).\n\n**Script**: `transforms/replace-attrs.js`\n\n**Options**\n\n| Name         | Default     | Type      | Description                                              |\n| ------------ | ----------- | --------- | -------------------------------------------------------- |\n| `--tag`      | `undefined` | `String`  | Tag name where the attributes will be replaced           |\n| `--attrs`    | `undefined` | `String`  | Stringified object with `{'old-attr': 'new-attr'}` pairs |\n| `--tabWidth` | `4`         | `Number`  | Number of spaces used per tab                            |\n| `--useTabs`  | `false`     | `Boolean` | Use tabs instead of spaces                               |\n\nExample input:\n\n```js\nclass MyComponent extends LitElement {\n  render() {\n    return html`\n      \u003csome-component\n        attr-one=\"value\"\n        attr-two=\"${expression}\"\n        .someProp=\"${expression}\"\n      \u003e\n      \u003c/some-component\u003e\n    `;\n  }\n}\n```\n\nCommand with options:\n\n```bash\njscodeshift input.js -t replace-attrs.js --tag=some-component --attrs='{\"attr-one\": \"foo\", \".someProp\": \".newProp\"}'\n```\n\nOutput:\n\n```diff\nclass MyComponent extends LitElement {\n  render() {\n    return html`\n      \u003csome-component\n-        attr-one=\"value\"\n+        foo=\"value\"\n        attr-two=\"${expression}\"\n-        .someProp=\"${expression}\"\n+        .newProp=\"${expression}\"\n      \u003e\n      \u003c/some-component\u003e\n    `;\n  }\n}\n```\n\n### Replace block scope by IIFE\n\nReplaces brackets used as scope in a file by an IIFE.\n\n**Script**: `transforms/block-scope-to-iife.js`\n\n**Options**: no options.\n\nExample input:\n\n```js\n{\n  const { Element } = Polymer;\n}\n```\n\nCommand with options:\n\n```bash\njscodeshift input.js -t block-scope-to-iife.js\n```\n\nOutput:\n\n```diff\n-{\n+(function() {\n  const { Element } = Polymer;\n+})();\n-}\n```\n\n### Rename tag\n\nRenames a tag name inside template literals and strings.\n\n**Script**: `transforms/rename-tag.js`\n\n**Options**\n\n| Name         | Default     | Type      | Description                   |\n| ------------ | ----------- | --------- | ----------------------------- |\n| `--oldTag`   | `undefined` | `String`  | Tag name to replace           |\n| `--newTag`   | `undefined` | `String`  | New tag name                  |\n| `--tabWidth` | `2`         | `Number`  | Number of spaces used per tab |\n| `--useTabs`  | `false`     | `Boolean` | Use tabs instead of spaces    |\n\nExample input:\n\n```js\nconst tpl = `\n  \u003csome-tag\u003e\n    \u003csome-tag-two\u003e\u003c/some-tag-two\u003e\n  \u003c/some-tag\u003e\n`;\ncustomElements.define('some-tag', SomeTag);\n```\n\nCommand with options:\n\n```bash\njscodeshift input.js -t rename-tag.js --oldTag=some-tag --newTag=new-tag\n```\n\nOutput:\n\n```diff\nconst tpl = `\n-  \u003csome-tag\u003e\n+  \u003cnew-tag\u003e\n    \u003csome-tag-two\u003e\u003c/some-tag-two\u003e\n-  \u003c/some-tag\u003e\n+  \u003c/new-tag\u003e\n`;\n-customElements.define('some-tag', SomeTag);\n+customElements.define('new-tag', SomeTag);\n```\n\n### LitElement to Lit imports\n\nUpdates the imports from `lit-element` to `lit` according to the [upgrade guide](https://lit.dev/docs/releases/upgrade/) of Lit 2.0\n\n**Script:** `transforms/lit-element-to-lit-imports.js`\n\n**Options:**\n\n| Name      | Default  | Type     | Description                      |\n| --------- | -------- | -------- | -------------------------------- |\n| `--quote` | `single` | `String` | Type of quote (single or double) |\n\nExample input:\n\n```js\nimport { css } from 'lit-element';\nimport { LitElement, html, property as foo, customElement } from 'lit-element';\nimport { repeat } from 'lit-html/directives/repeat.js';\nimport { ifDefined } from 'lit-html/directives/if-defined';\n```\n\nCommand with options:\n\n```bash\njscodeshift input.js -t lit-element-to-lit-imports.js\n```\n\nOutput:\n\n```diff\n-import { css } from 'lit-element';\n+import { css } from 'lit';\n-import { LitElement, html, property as foo, customElement } from 'lit-element';\n+import { LitElement, html } from 'lit';\n+import { property as foo, customElement } from 'lit/decorators.js';\n-import { repeat } from 'lit-html/directives/repeat.js';\n+import { repeat } from 'lit/directives/repeat.js';\n-import { ifDefined } from 'lit-html/directives/if-defined';\n+import { ifDefined } from 'lit/directives/if-defined';\n```\n\n## Acknowledgments\n\n**Inspiration**\n\n- [Fearless refactors con AST - Speaker Deck](https://speakerdeck.com/sanguino/fearless-refactors-con-ast)\n- [React Codemod](https://github.com/reactjs/react-codemod)\n\n**Resources**\n\n- [Write Code to Rewrite Your Code: jscodeshift](https://www.toptal.com/javascript/write-code-to-rewrite-your-code)\n- [jscodeshift API and demos](https://hackmd.io/@yQp_d2iwRF25H5YTCeWj0w/Hy8FL6IWZ?type=view#jscodeshift-draft)\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkcmr%2Fweb-components-codemods","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkcmr%2Fweb-components-codemods","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkcmr%2Fweb-components-codemods/lists"}