eslint-plugin-react-native: [3.9.1] Crash related to

Hey! 👋

I’m getting Error: Couldn't find a Program after upgrading this package from 3.8.1 to 3.9.1.

Bit of a contrived example below, but seems to reliably trigger the issue and was just about the smallest repro I could manage to find. Not able to post the actual code we’re using I’m afraid but it’s essentially rendering something like:

Total: 12.34

Seems to be something to do with nested text that has a function defined somewhere inside. In our case there’s a reducer for calculating a total.

Some notes:

  • Using a named fn instead of the arrow fn still crashes - i.e. arr.reduce(function add(acc, value) { return acc + value }, 0)
  • Replacing the reducer callback with something else like a string prevents the crash - i.e. arr.reduce('blah', 0) (obviously invalid code though)
  • Defining the reducer callback outside of the JSX also prevents the crash - i.e. const add = (acc, value) => acc + value and arr.reduce(add, 0) <- looks like this is a reasonable workaround for now…

Repro code:

const Comp = () => {
    return (
        <Text>
            <Text>Text</Text> {fn(() => {})}
        </Text>
    )
}
> eslint .


Oops! Something went wrong! :(

ESLint: 7.8.1

Error: Couldn't find a Program
Occurred while linting /Users/REDACTED/REDACTED/REDACTED.tsx:XX
    at Scope.getProgramParent (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/scope/index.js:813:11)
    at Scope.registerBinding (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/scope/index.js:574:25)
    at Scope.crawl (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/scope/index.js:729:14)
    at Scope.init (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/scope/index.js:709:12)
    at NodePath.setScope (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/path/context.js:131:30)
    at NodePath.setContext (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/path/context.js:147:8)
    at NodePath.pushContext (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/path/context.js:213:8)
    at TraversalContext.visitQueue (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/context.js:100:14)
    at TraversalContext.visitMultiple (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/context.js:79:17)
    at TraversalContext.visit (/Users/REDACTED/REDACTED/node_modules/@babel/traverse/lib/context.js:138:19)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 36
  • Comments: 31 (2 by maintainers)

Commits related to this issue

Most upvoted comments

Came up with a workaround 😄

"rules": {
  "react-native/no-raw-text": "off",
},

This is still present in 3.11.0.

Really appreciate the amount of attention this gets from the maintainers.

The minimum conditions to reproduce this linting crash are: => Having a component with a function passed as a prop AND any kind of children.

So, the minimal reproducible example is the following one:

<MyComponent myFunctionProp={() => {}}>my children</MyComponent>;

To fix this issue, you should define the prop before passing it, like so:

const myFunction = () => {};
<MyComponent myFunctionProp={myFunction}>my children</MyComponent>;

Still getting this issue on:

eslint 7.14.0 eslint-plugin-react-native: 3.11.0

😕

Any timeline on the possibility of the PR that fixes it being merged?

Is this ever going to be fixed? This is a major issue.

#314 should fix this

I’m also getting this error with both arrow functions on onPress and the Text issue. It happens while coding on VSCode by showing a popup with text “ESLint: Couldn’t find a Program Occurred while linting…” and also when trying to commit via precommit hooks.

Package.json:

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "cross-env COMPONENT_LIBRARY_DEVELOPMENT=false expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "fix": "yarn fix:eslint && yarn fix:prettier",
    "fix:eslint": "eslint \"{src}/**/*.{ts,tsx,js,jsx}\" --fix",
    "fix:prettier": "prettier \"{src}/**/*.{ts,tsx,js,jsx,json}\" --write --config ./.prettierrc.json --ignore-path ./.prettierignore",
    "lint": "eslint --config .eslintrc.json --ignore-path .eslintignore",
    "test": "jest --watchAll",
    "storybook": "start-storybook -p 7007",
    "prestorybook": "rnstl",
    "start:component-library": "cross-env COMPONENT_LIBRARY_DEVELOPMENT=true expo start",
    "build-storybook": "build-storybook",
    "build-static-webapp": "cross-env COMPONENT_LIBRARY_DEVELOPMENT=true expo build:web"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@expo/vector-icons": "^12.0.0",
    "@react-native-community/masked-view": "0.1.10",
    "@react-navigation/bottom-tabs": "5.11.2",
    "@react-navigation/native": "~5.8.10",
    "@react-navigation/stack": "~5.12.8",
    "cross-env": "^7.0.3",
    "expo": "~40.0.0",
    "expo-asset": "~8.2.1",
    "expo-constants": "~9.3.0",
    "expo-firebase-recaptcha": "^1.3.0",
    "expo-font": "~8.4.0",
    "expo-linking": "~2.0.0",
    "expo-splash-screen": "~0.8.0",
    "expo-status-bar": "~1.0.3",
    "expo-web-browser": "~8.6.0",
    "firebase": "^8.3.1",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-dotenv": "^2.5.3",
    "react-native-gesture-handler": "~1.8.0",
    "react-native-safe-area-context": "3.1.9",
    "react-native-screens": "~2.15.0",
    "react-native-web": "~0.13.12",
    "react-native-webview": "^11.3.1",
    "styled-components": "^5.2.1"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0",
    "@commitlint/config-conventional": "^9.0.1",
    "@storybook/addon-a11y": "^6.1.21",
    "@storybook/addon-actions": "^5.3",
    "@storybook/addon-knobs": "^5.3",
    "@storybook/addon-links": "^5.3",
    "@storybook/addon-ondevice-actions": "^5.3.23",
    "@storybook/addon-ondevice-knobs": "^5.3.25",
    "@storybook/react-native": "^5.3.25",
    "@storybook/react-native-server": "^5.3.23",
    "@testing-library/react-native": "^7.2.0",
    "@types/jest": "^26.0.21",
    "@types/react": "~16.9.35",
    "@types/react-native": "~0.63.2",
    "@types/react-test-renderer": "^17.0.1",
    "@types/styled-components": "^5.1.9",
    "@types/styled-components-react-native": "^5.1.1",
    "@typescript-eslint/eslint-plugin": "^3.4.0",
    "@typescript-eslint/parser": "^3.4.0",
    "babel-loader": "^8.2.2",
    "eslint": "^6.6.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-better-styled-components": "^1.1.2",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-prettier": "^3.1.4",
    "eslint-plugin-react": "^7.23.1",
    "eslint-plugin-react-hooks": "^4.0.6",
    "eslint-plugin-react-native": "^3.10.0",
    "eslint-plugin-sort-destructure-keys": "^1.3.5",
    "eslint-plugin-typescript-sort-keys": "^1.2.0",
    "husky": "^4.2.5",
    "jest-expo": "~40.0.0",
    "lint-staged": "^10.2.11",
    "prettier": "^2.0.5",
    "react-native-storybook-loader": "^2.0.2",
    "react-test-renderer": "^17.0.2",
    "typescript": "~4.0.0"
  },
  "private": true,
  "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "lint-staged": {
    "src/**/*.{js,jsx,ts,tsx}": [
      "eslint --config .eslintrc.json --ignore-path .eslintignore --fix",
      "prettier --write --config .prettierrc.json --ignore-path .prettierignore",
      "git add"
    ]
  },
  "config": {
    "react-native-storybook-loader": {
      "searchDir": [
        "./src/components"
      ],
      "pattern": "**/__stories__/*.story.tsx",
      "outputFile": "./src/storybook/storyLoader.js"
    }
  }
}

.eslintrc.json

{
  "env": {
    "browser": true,
    "react-native/react-native": true,
    "commonjs": true,
    "node": true,
    "es6": true
  },
  "extends": [
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:import/typescript",
    "plugin:prettier/recommended",
    "prettier/@typescript-eslint"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 2020,
    "project": ["./tsconfig.json"],
    "sourceType": "module"
  },
  "plugins": [
    "@typescript-eslint",
    "better-styled-components",
    "import",
    "prettier",
    "react",
    "react-hooks",
    "react-native",
    "sort-destructure-keys",
    "typescript-sort-keys"
  ],
  "rules": {
// Bunch of rules that I won't add

Using node v14.16.0

Same issue here with eslint-plugin-react-native@3.10.0 when trying to use a arrow function inside JSX:

<Button onPress={() => functionWithuseCallback(true)}>Click me</Button>