Skip to content

Commit

Permalink
Fix bundle issue [publish]
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBarre committed Dec 2, 2023
1 parent 9594a20 commit 8b7268a
Show file tree
Hide file tree
Showing 7 changed files with 760 additions and 447 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.cjs
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ["@arnaud-barre"],
};
Binary file modified bun.lockb
Binary file not shown.
22 changes: 13 additions & 9 deletions package.json
@@ -1,25 +1,29 @@
{
"name": "eslint-plugin-react-refresh",
"version": "0.4.5",
"type": "module",
"license": "MIT",
"scripts": {
"build": "scripts/bundle.ts",
"lint": "bun lint-ci --fix --cache",
"lint-ci": "eslint ./ --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"prettier": "bun prettier-ci --write",
"prettier-ci": "prettier --ignore-path=.gitignore --check '**/*.{ts,json,md,yml}'",
"ci": "tsc && bun prettier-ci && bun test && bun run build"
"ci": "tsc && bun lint-ci && bun prettier-ci && bun test && bun run build"
},
"peerDependencies": {
"eslint": ">=7"
},
"devDependencies": {
"@arnaud-barre/eslint-config": "^4.0.0",
"@arnaud-barre/tnode": "^0.19.2",
"@types/eslint": "^8.44.6",
"@types/node": "^20.8.7",
"@typescript-eslint/parser": "^6.9.0",
"@typescript-eslint/utils": "^6.9.0",
"bun-types": "^1.0.7",
"eslint": "^8.52.0",
"prettier": "^3.0.3",
"typescript": "^5.2.2"
"@types/eslint": "^8.44.8",
"@types/node": "^20.10.2",
"@typescript-eslint/parser": "^6.13.1",
"@typescript-eslint/utils": "^6.13.1",
"bun-types": "^1.0.15",
"eslint": "^8.55.0",
"prettier": "3.0.3",
"typescript": "~5.3"
}
}
62 changes: 31 additions & 31 deletions scripts/bundle.ts
@@ -1,45 +1,45 @@
#!/usr/bin/env tnode
import { rmSync, writeFileSync } from "fs";
import { execSync } from "child_process";
import { rmSync, writeFileSync } from "node:fs";
import { execSync } from "node:child_process";
import { build } from "esbuild";

import packageJSON from "../package.json";

rmSync("dist", { force: true, recursive: true });

build({
await build({
bundle: true,
entryPoints: ["src/index.ts"],
outdir: "dist",
platform: "node",
target: "node14",
external: Object.keys(packageJSON.peerDependencies),
}).then(() => {
execSync("cp LICENSE README.md dist/");

writeFileSync(
"dist/package.json",
JSON.stringify(
{
name: packageJSON.name,
description:
"Validate that your components can safely be updated with fast refresh",
version: packageJSON.version,
author: "Arnaud Barré (https://github.com/ArnaudBarre)",
license: packageJSON.license,
repository: "github:ArnaudBarre/eslint-plugin-react-refresh",
main: "index.js",
keywords: [
"eslint",
"eslint-plugin",
"react",
"react-refresh",
"fast refresh",
],
peerDependencies: packageJSON.peerDependencies,
},
null,
2,
),
);
});

execSync("cp LICENSE README.md dist/");

writeFileSync(
"dist/package.json",
JSON.stringify(
{
name: packageJSON.name,
description:
"Validate that your components can safely be updated with fast refresh",
version: packageJSON.version,
author: "Arnaud Barré (https://github.com/ArnaudBarre)",
license: packageJSON.license,
repository: "github:ArnaudBarre/eslint-plugin-react-refresh",
main: "index.js",
keywords: [
"eslint",
"eslint-plugin",
"react",
"react-refresh",
"fast refresh",
],
peerDependencies: packageJSON.peerDependencies,
},
null,
2,
),
);
13 changes: 7 additions & 6 deletions src/only-export-components.test.ts
Expand Up @@ -117,6 +117,7 @@ const valid = [
},
{
name: "Component and template literal with allowConstantExport",
// eslint-disable-next-line no-template-curly-in-string
code: "const foo = 'world'; export const CONSTANT = `Hello ${foo}`; export const Foo = () => {};",
options: [{ allowConstantExport: true }],
},
Expand Down Expand Up @@ -216,7 +217,7 @@ const invalid = [
},
{
name: "export default compose",
code: `export default compose()(MainView);`,
code: "export default compose()(MainView);",
filename: "Test.jsx",
errorId: "anonymousExport",
},
Expand All @@ -232,21 +233,21 @@ const it = (name: string, cases: Parameters<typeof ruleTester.run>[2]) => {
test(name, () => {
ruleTester.run(
"only-export-components",
// @ts-ignore Mismatch between typescript-eslint and eslint
// @ts-expect-error Mismatch between typescript-eslint and eslint
onlyExportComponents,
cases,
);
});
};

valid.forEach(({ name, code, filename, options = [] }) => {
for (const { name, code, filename, options = [] } of valid) {
it(name, {
valid: [{ filename: filename ?? "Test.jsx", code, options }],
invalid: [],
});
});
}

invalid.forEach(({ name, code, errorId, filename, options = [] }) => {
for (const { name, code, errorId, filename, options = [] } of invalid) {
it(name, {
valid: [],
invalid: [
Expand All @@ -258,4 +259,4 @@ invalid.forEach(({ name, code, errorId, filename, options = [] }) => {
},
],
});
});
}
35 changes: 15 additions & 20 deletions src/only-export-components.ts
@@ -1,12 +1,12 @@
import { TSESLint } from "@typescript-eslint/utils";
import { TSESTree } from "@typescript-eslint/types";
import type { TSESLint } from "@typescript-eslint/utils";
import type { TSESTree } from "@typescript-eslint/types";

const possibleReactExportRE = /^[A-Z][a-zA-Z0-9]*$/;
const possibleReactExportRE = /^[A-Z][a-zA-Z0-9]*$/u;
// Starts with uppercase and at least one lowercase
// This can lead to some false positive (ex: `const CMS = () => <></>; export default CMS`)
// But allow to catch `export const CONSTANT = 3`
// and the false positive can be avoided with direct name export
const strictReactExportRE = /^[A-Z][a-zA-Z0-9]*[a-z]+[a-zA-Z0-9]*$/;
const strictReactExportRE = /^[A-Z][a-zA-Z0-9]*[a-z]+[a-zA-Z0-9]*$/u;

export const onlyExportComponents: TSESLint.RuleModule<
| "exportAll"
Expand Down Expand Up @@ -55,7 +55,7 @@ export const onlyExportComponents: TSESLint.RuleModule<
allowConstantExport = false,
checkJS = false,
allowExportNames,
} = context.options[0] || {};
} = context.options[0] ?? {};
const filename = context.getFilename();
// Skip tests & stories files
if (
Expand Down Expand Up @@ -97,9 +97,7 @@ export const onlyExportComponents: TSESLint.RuleModule<
nonComponentExports.push(identifierNode);
return;
}
if (allowExportNames?.includes(identifierNode.name)) {
return;
}
if (allowExportNames?.includes(identifierNode.name)) return;
if (
allowConstantExport &&
init &&
Expand Down Expand Up @@ -184,10 +182,7 @@ export const onlyExportComponents: TSESLint.RuleModule<
if (node.declaration.type === "Identifier") {
handleExportIdentifier(node.declaration);
}
if (
node.declaration.type === "ArrowFunctionExpression" &&
!node.declaration.id
) {
if (node.declaration.type === "ArrowFunctionExpression") {
context.report({ messageId: "anonymousExport", node });
}
} else if (node.type === "ExportNamedDeclaration") {
Expand All @@ -202,16 +197,18 @@ export const onlyExportComponents: TSESLint.RuleModule<
}
} else if (node.type === "FunctionDeclaration") {
handleLocalIdentifier(node.id);
} else if (node.type === "ImportDeclaration") {
if (node.source.value === "react") {
reactIsInScope = true;
}
} else if (
node.type === "ImportDeclaration" &&
node.source.value === "react"
) {
reactIsInScope = true;
}
}

if (checkJS && !reactIsInScope) return;

if (hasExports) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (mayHaveReactExport) {
for (const node of nonComponentExports) {
context.report({ messageId: "namedExport", node });
Expand All @@ -235,10 +232,8 @@ const reactHOCs = ["memo", "forwardRef"];
const canBeReactFunctionComponent = (init: TSESTree.Expression | null) => {
if (!init) return false;
if (init.type === "ArrowFunctionExpression") return true;
if (init.type === "CallExpression") {
if (init.callee.type === "Identifier") {
return reactHOCs.includes(init.callee.name);
}
if (init.type === "CallExpression" && init.callee.type === "Identifier") {
return reactHOCs.includes(init.callee.name);
}
return false;
};
Expand Down

0 comments on commit 8b7268a

Please sign in to comment.