{"id":20881303,"url":"https://github.com/peakchen90/babel-plugin-react-directives","last_synced_at":"2025-10-29T21:43:19.791Z","repository":{"id":35149894,"uuid":"211678886","full_name":"peakchen90/babel-plugin-react-directives","owner":"peakchen90","description":"A babel plugin that provides some directives for react(JSX), similar to directives of vue.","archived":false,"fork":false,"pushed_at":"2025-01-23T06:07:48.000Z","size":2102,"stargazers_count":97,"open_issues_count":7,"forks_count":14,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-09T02:17:33.947Z","etag":null,"topics":["babel-plugin","directive","jsx-directive","react","react-directive","v-for","v-if","v-model","v-show","x-for","x-if","x-model","x-show"],"latest_commit_sha":null,"homepage":"https://peakchen90.github.io/babel-plugin-react-directives","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/peakchen90.png","metadata":{"files":{"readme":"README.ZH-CN.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-09-29T14:51:59.000Z","updated_at":"2025-08-01T21:27:27.000Z","dependencies_parsed_at":"2025-02-24T03:21:01.482Z","dependency_job_id":null,"html_url":"https://github.com/peakchen90/babel-plugin-react-directives","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/peakchen90/babel-plugin-react-directives","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peakchen90%2Fbabel-plugin-react-directives","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peakchen90%2Fbabel-plugin-react-directives/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peakchen90%2Fbabel-plugin-react-directives/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peakchen90%2Fbabel-plugin-react-directives/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peakchen90","download_url":"https://codeload.github.com/peakchen90/babel-plugin-react-directives/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peakchen90%2Fbabel-plugin-react-directives/sbom","scorecard":{"id":725772,"data":{"date":"2025-08-11","repo":{"name":"github.com/peakchen90/babel-plugin-react-directives","commit":"e8e333cf69aa3cd6fdf6944f40632339dd902cf1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2,"checks":[{"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/26 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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"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":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 4 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"12 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"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-22T12:45:19.912Z","repository_id":35149894,"created_at":"2025-08-22T12:45:19.912Z","updated_at":"2025-08-22T12:45:19.912Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281705786,"owners_count":26547506,"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","status":"online","status_checked_at":"2025-10-29T02:00:06.901Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["babel-plugin","directive","jsx-directive","react","react-directive","v-for","v-if","v-model","v-show","x-for","x-if","x-model","x-show"],"created_at":"2024-11-18T07:24:26.462Z","updated_at":"2025-10-29T21:43:19.734Z","avatar_url":"https://github.com/peakchen90.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# babel-plugin-react-directives\n一个给react (任何 JSX ) 提供一些类似 vue 指令的 Babel 转换插件。现在你可以在 [playground](https://peakchen90.github.io/babel-plugin-react-directives/) 上在线尝试。\n\n[![Travis (.org) branch](https://img.shields.io/travis/peakchen90/babel-plugin-react-directives/master.svg)](https://travis-ci.com/github/peakchen90/babel-plugin-react-directives)\n[![Codecov](https://img.shields.io/codecov/c/github/peakchen90/babel-plugin-react-directives.svg)](https://codecov.io/gh/peakchen90/babel-plugin-react-directives)\n![node](https://img.shields.io/node/v/babel-plugin-react-directives.svg)\n[![npm](https://img.shields.io/npm/v/babel-plugin-react-directives.svg)](https://www.npmjs.com/package/babel-plugin-react-directives)\n[![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/peakchen90/babel-plugin-react-directives/blob/master/LICENSE)\n\n\u003e [**English document**](./README.md)\n\n## 目录\n- [开始使用](#toc-usage)\n  - [安装](#toc-installation)\n  - [添加配置 .babelrc](#toc-configuring)\n  - [插件options](#toc-plugin-options)\n- [指令](#toc-directives)\n  - [x-if](#toc-directives-x-if)\n  - [x-else-if 和 x-else](#toc-directives-x-else-if-and-x-else)\n  - [x-show](#toc-directives-x-show)\n  - [x-for](#toc-directives-x-for)\n  - [x-class](#toc-directives-x-class)\n- [相关资源](#toc-related-packages)\n- [已知问题](#toc-known-issues)\n- [更新日志](#toc-changeloog)\n- [许可证](#toc-license)\n\n## \u003cspan id=\"toc-usage\"\u003e开始使用\u003c/span\u003e\n\n需要 **node v10.0.0** 或者更高版本，**babel v7.0.0** 或者更高版本\n\n### \u003cspan id=\"toc-installation\"\u003e安装\u003c/span\u003e\n使用 npm:\n```bash\nnpm install --save-dev babel-plugin-react-directives\nnpm install --save react-directives-runtime\n```\n\n使用 yarn:\n```bash\nyarn add --dev babel-plugin-react-directives\nyarn add react-directives-runtime\n```\n\n### \u003cspan id=\"toc-configuring\"\u003e添加配置 `.babelrc`\u003c/span\u003e\n```json\n{\n  \"plugins\": [\n    \"react-directives\"\n  ]\n}\n```\n\n### \u003cspan id=\"toc-plugin-options\"\u003e插件options\u003c/span\u003e\n\n```json\n{\n  \"plugins\": [\n    [\n      \"react-directives\",\n      {\n        \"prefix\": \"x\"\n      }\n    ]\n  ]\n}\n```\n\n- `prefix`: 指令的 props 前缀，默认值: \"x\"，用法示例: `x-if`\n\n## \u003cspan id=\"toc-directives\"\u003e指令\u003c/span\u003e\n\n### \u003cspan id=\"toc-directives-x-if\"\u003ex-if\u003c/span\u003e\n如果 `x-if` 的值为**真值**，则将渲染此元素，否则不渲染。\n\n**例子:**\n```jsx harmony\nconst foo = \u003cdiv x-if={true}\u003etext\u003c/div\u003e\n```\n\n**转换成:**\n```jsx harmony\nconst foo = true ? \u003cdiv\u003etext\u003c/div\u003e : null\n```\n\n### \u003cspan id=\"toc-directives-x-else-if-and-x-else\"\u003ex-else-if 和 x-else\u003c/span\u003e\n在 `x-else-if` 的同一层级元素必须有相对应的 `x-if`，如果 `x-if` 的值是**假值**，并且 `x-else-if` 的值是**真值**，则它将被渲染。\n\n在 `x-else` 的同一层级元素必须有相对应的 `x-if` 或 `x-else-if`，当 `x-if` 或者 `x-else-if` 都是**假值**时，它将被渲染。\n\n**例子:**\n```jsx harmony\nconst foo = (\n  \u003cdiv\u003e\n    \u003cp x-if={data === 'a'}\u003eA\u003c/p\u003e\n    \u003cp x-else-if={data === 'b'}\u003eB\u003c/p\u003e\n    \u003cp x-else-if={data === 'c'}\u003eC\u003c/p\u003e\n    \u003cp x-else\u003eD\u003c/p\u003e\n  \u003c/div\u003e\n)\n```\n\n**转换成:**\n```jsx harmony\nconst foo = (\n  \u003cdiv\u003e\n    {data === 'a'\n      ? \u003cp\u003eA\u003c/p\u003e\n      : data === 'b'\n        ? \u003cp\u003eB\u003c/p\u003e\n        : data === 'c'\n          ? \u003cp\u003eC\u003c/p\u003e\n          : \u003cp\u003eD\u003c/p\u003e\n    }\n  \u003c/div\u003e\n)\n```\n\n### \u003cspan id=\"toc-directives-x-show\"\u003ex-show\u003c/span\u003e\n\n`x-show` 通过 `style` prop 的 `display` 属性来控制元素的显示或隐藏，如果 `x-show` 的值是**假值**，则设置 `style.display = \"none\"`，否则不设置。\n\n**例子:**\n```jsx harmony\nconst foo = \u003cdiv x-show={true}\u003etext\u003c/div\u003e\n```\n\n**转换成:**\n```jsx harmony\nconst foo = (\n  \u003cdiv style={{\n    display: true ? undefined : \"none\"\n  }}\u003etext\n  \u003c/div\u003e\n)\n```\n\n当然，它也会通过调用 [mergeProps 方法](./runtime/merge-props.js) 合并其他 `style` props，例如：\n```jsx harmony\nconst foo = (\n  \u003cdiv\n    style={{ color: 'red' }}\n    x-show={true}\n    {...extraProps}\u003e\n    text\n  \u003c/div\u003e\n)\n```\n\n将被转换成:\n```jsx harmony\nconst foo = (\n  \u003cdiv\n    {...extraProps}\n    style={{\n      ...mergeProps.call(this, \"style\", [\n        { style: { color: 'red' } },\n        extraProps\n      ]),\n      display: true ? undefined : \"none\"\n    }}\u003etext\n  \u003c/div\u003e\n)\n```\n\n### \u003cspan id=\"toc-directives-x-for\"\u003ex-for\u003c/span\u003e\n使用 `x-for` 遍历数组生成元素。\n\n绑定的值应该像这样: `(item, index) in list`\n- `list`: 遍历的目标数组\n- `item`: 当前的值\n- `index`: 当前的索引 (可选)\n\n**提示**: 如果你在项目中使用了 [**ESLint**](https://eslint.org)，也许会提示你: `item` 和 `index` 是未定义的变量，请安装 [**eslint-plugin-react-directives**](https://github.com/peakchen90/eslint-plugin-react-directives) 来解决这个问题\n\n**例子:**\n```jsx harmony\nconst foo = (\n  \u003cul\u003e\n    \u003cli\n      x-for={item in list}\n      key={item.id}\u003e{item.name}\n    \u003c/li\u003e\n  \u003c/ul\u003e\n)\n```\n\n**转换成:**\n```jsx harmony\nconst foo = (\n  \u003cul\u003e\n    {list.map(item =\u003e (\n      \u003cli key={item.id}\u003e{item.name}\u003c/li\u003e\n    ))}\n  \u003c/ul\u003e\n)\n```\n\n另外请注意，如果与 `x-if` 一起使用，则 `x-for` 拥有更高的优先级，例如：\n```jsx harmony\nconst foo = (\n  \u003cul\u003e\n    \u003cli\n      x-for={item in list}\n      x-if={item.name === 'alice'}\n      key={item.id}\u003e{item.name}\n    \u003c/li\u003e\n  \u003c/ul\u003e\n)\n```\n\n将被转换成:\n```jsx harmony\nconst foo = (\n  \u003cul\u003e\n    {list.map(item =\u003e (\n      item.name === 'alice'\n        ? \u003cli key={item.id}\u003e{item.name}\u003c/li\u003e\n        : null\n    ))}\n  \u003c/ul\u003e\n)\n```\n\n### \u003cspan id=\"toc-directives-x-class\"\u003ex-class\u003c/span\u003e\n\n`x-class` 通过 [classnames](https://github.com/JedWatson/classnames) 有条件的生成 className, 这对于动态生成 className 非常有用。\n用法与 [classnames](https://github.com/JedWatson/classnames) 相同，绑定值将作为参数传给 [`classNames`](https://github.com/JedWatson/classnames#usage) 方法。\n\n**例子:**\n```jsx harmony\nconst foo = \u003cdiv x-class={{ abc: true, def: false }}\u003e\n```\n\n**转换成:**\n```jsx harmony\nconst foo = \u003cdiv className={classNames({ abc: true, def: false })}\u003e\n// className=\"abc\"\n```\n**提示**: `classNames` 方法引用于 [runtime/classnames.js](./runtime/classnames.js).\n\n当然，它也将合并其他的 `className` props, 例如:\n```jsx harmony\nconst foo = \u003cdiv x-class={{ abc: true, def: false }} className=\"xyz\"\u003e\n```\n\n将被转换成:\n```jsx harmony\nconst foo = \u003cdiv className={classNames([\"xyz\", { abc: true, def: false }])}\u003e\n// className=\"xyz abc\"\n```\n\n`x-class` 也可以与 [css-modules](https://github.com/css-modules/css-modules) 一起使用，例如：\n```jsx harmony\nimport styles from './style.css';\n\nconst foo = (\n  \u003cdiv\n    className={styles.foo}\n    x-class={{\n      [styles.bar]: true,\n      [styles.qux]: false\n    }}\n  /\u003e\n)\n```\n\n## \u003cspan id=\"toc-related-packages\"\u003e相关资源\u003c/span\u003e\n- [eslint-plugin-react-directives](https://github.com/peakchen90/eslint-plugin-react-directives)\n\n\n## \u003cspan id=\"toc-known-issues\"\u003e已知问题\u003c/span\u003e\n- 在 Typescript 中使用 `x-for` 时，绑定的值 `item` 会报一个错误。临时的解决方案是，在使用前先声明变量 `item`，\n  例如: `declare let item: any`. **不推荐在 Typescript 中使用 `x-for`**.\n\n\n## \u003cspan id=\"toc-changeloog\"\u003e更新日志\u003c/span\u003e\n查看更多信息: [CHANGELOG](./CHANGELOG.md)\n\n\n## \u003cspan id=\"toc-license\"\u003e许可证\u003c/span\u003e\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeakchen90%2Fbabel-plugin-react-directives","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeakchen90%2Fbabel-plugin-react-directives","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeakchen90%2Fbabel-plugin-react-directives/lists"}