diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e617515 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,13 @@ +name: CI +on: + pull_request: + branches: + - main +jobs: + ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + - run: bun install + - run: bun ci diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 85e4e79..65c0de0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,8 +8,8 @@ jobs: runs-on: ubuntu-latest if: ${{ contains(github.event.head_commit.message, '[publish]') }} steps: - - uses: actions/checkout@v3 - - uses: oven-sh/setup-bun@v1 + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 - run: bun install - run: bun ci - uses: ArnaudBarre/npm-publish@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da8f78..4c15b12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # Changelog +## 0.4.10 + +- Support `function Foo() {}; export default React.memo(Foo)` (#46) (thanks @SukkaW!) + ## 0.4.9 -- Support `function Foo() {}; export default memo(Foo)` (fixes #44) +- Support `function Foo() {}; export default memo(Foo)` (fixes #44) (thanks @SukkaW!) ## 0.4.8 diff --git a/package.json b/package.json index 6ce9c0e..1caf7e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-react-refresh", - "version": "0.4.9", + "version": "0.4.10", "type": "module", "license": "MIT", "scripts": { diff --git a/src/only-export-components.test.ts b/src/only-export-components.test.ts index f949f73..a89591f 100755 --- a/src/only-export-components.test.ts +++ b/src/only-export-components.test.ts @@ -89,14 +89,26 @@ const valid = [ name: "export default memo function", code: "export default memo(function Foo () {});", }, + { + name: "export default React.memo function", + code: "export default React.memo(function Foo () {});", + }, { name: "export default memo function assignment", code: "const Foo = () => {}; export default memo(Foo);", }, + { + name: "export default React.memo function assignment", + code: "const Foo = () => {}; export default React.memo(Foo);", + }, { name: "export default memo function declaration", code: "function Foo() {}; export default memo(Foo);", }, + { + name: "export default React.memo function declaration", + code: "function Foo() {}; export default React.memo(Foo);", + }, { name: "export type *", code: "export type * from './module';", diff --git a/src/only-export-components.ts b/src/only-export-components.ts index 654d218..c94bcf1 100644 --- a/src/only-export-components.ts +++ b/src/only-export-components.ts @@ -157,10 +157,20 @@ export const onlyExportComponents: TSESLint.RuleModule< handleExportIdentifier(node.id, true); } } else if (node.type === "CallExpression") { - if ( - node.callee.type !== "Identifier" || - !reactHOCs.has(node.callee.name) - ) { + // we rule out non HoC first + if (node.callee.type !== "Identifier") { + // export default React.memo(function Foo() {}) + // export default Preact.memo(function Foo() {}) + if ( + node.callee.type === "MemberExpression" && + node.callee.property.type === "Identifier" && + reactHOCs.has(node.callee.property.name) + ) { + mayHaveReactExport = true; + } else { + context.report({ messageId: "anonymousExport", node }); + } + } else if (!reactHOCs.has(node.callee.name)) { // we rule out non HoC first context.report({ messageId: "anonymousExport", node }); } else if (