[3.9.1] Crash related to <Text>
mjmasn opened this issue · comments
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
andarr.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)
I got the same issue using the latest version
Same issue when I use @react-native-community/eslint-config@2.0.0
which depends on eslint-plugin-react-native@3.10.0
.
Adding eslint-disable
in the file doesn't fix it, so I had to add the file to .eslintignore
. Fortunately it was only a single small file for us.
+1
eslint error:
`> eslint "**/*.{js,ts,tsx}" -o ./eslint-report.txt
Oops! Something went wrong! :(
ESLint: 7.13.0
Error: Couldn't find a Program
Occurred while linting /Volumes/T7 Touch/code/react-native-mb-ui/example/src/views/actionsheet/view.tsx:59`
actionsheet/view.tsx:59
<Text onPress={() => setCustomCloseExtra(false)}>取消</Text>
Can confirm this happened to me on a larger project. Version 3.10.0
produces the Error: Couldn't find a Program
. Downgrading to 3.8.1
fixes this issue (for the time being).
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>
Came up with a workaround
"rules": {
"react-native/no-raw-text": "off",
},
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
Have the same issue with "eslint-plugin-react-native": "^3.10.0"
, when trying to replace
<SomeComponent prop={array.reduce((acc, item) => [...acc, processItem(item)], [])} />
with
const prop = useMemo(
() =>
array.reduce(
(acc, item) => [
...acc,
processItem(item)
],
[]
),
[array]
);
// ...
<SomeComponent prop={prop} />
Disabled this rule for now, waiting for a proper solution.
This is still present in 3.11.0.
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>;
To fix this issue, you should define the prop before passing it, like so:
@VincentJouanne This doesn't work with useCallback hook though
Still getting this issue on:
eslint 7.14.0
eslint-plugin-react-native: 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>;
no help if I need to pass an arg, sadly
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>;
no help if I need to pass an arg, sadly
what do you mean by that?
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>;
no help if I need to pass an arg, sadly
what do you mean by that?
const onPressButton = id => foo(id)
....
{ myButtons.map((text,id)=><Button onPress={()=>onPressButton(id)}>{text}</Button>) }
ETA: I have worked out a work-around for this - a curried function:
const onPressButton = id => () => foo(id) <--- notice extra () =>
....
{ myButtons.map((text,id)=><Button onPress={onPressButton(id)}>{text}</Button>) }
I had this problem with the code below
<Text>
Something?{' '}
<TouchableOpacity
onPress={() => fun()}
>
<Text>
Something
</Text>
</TouchableOpacity>
</Text>
I have no idea why, I just tweaked the text to this and the error went away.
<Text>
<Text>Something? </Text>
<TouchableOpacity
onPress={() => fun()}
>
<Text>
Something
</Text>
</TouchableOpacity>
</Text>
Might be related to some structure of nested text RN elements in my case.
@hsource still exists
@hsource still exists
That shouldn't be right! What error message are you seeing? If you'd like to test with a build, you can also do yarn add hsource/eslint-plugin-react-native#v4.0.0-wanderlog.2
to use the patched version
Thanks! I'll try it out.
Basically the linter doesn't detect a custom component
For those interested, here is my brief explanation about this issue: #314 (comment)
The problem still exists in v4.0.0
. Have to temporarily turn the rule off
Had the same problem, fixed it by assigning the value to a constant. Simplified example:
Didn't work:
function displaySomething() { return ( <Text>functionThatReturnsAName(id)</Text> )}
Works:
function displaySomething() { const name = functionThatReturnsAName(id) return ( <Text>{name}</Text> )}
Not sure if this is helpful for anyone but worked for me and it is prettier imo.
Any timeline on the possibility of the PR that fixes it being merged?
Still present in!
eslint: 8.35.0
eslint-plugin-react: 7.32.2
eslint-plugin-react-native: 4.0.0
Having this issue as well...
My config:
eslint@8.44.0
eslint-plugin-react@7.32.2
eslint-plugin-react-native@4.0.0
The error:
$ eslint .
Oops! Something went wrong! :(
ESLint: 8.44.0
Error: Couldn't find a Program
Occurred while linting /home/vibia/platform/services/app-on-site/apps/expo/app/paper/paper.tsx:62
Rule: "react-native/no-raw-text"
at Scope.getProgramParent (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/scope/index.js:753:11)
at Scope.crawl (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/scope/index.js:665:32)
at Scope.init (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/scope/index.js:655:12)
at NodePath.setScope (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/path/context.js:120:61)
at NodePath.setContext (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/path/context.js:132:8)
at NodePath.pushContext (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/path/context.js:189:8)
at TraversalContext.visitQueue (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/context.js:78:14)
at TraversalContext.visitSingle (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/context.js:65:19)
at TraversalContext.visit (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/context.js:109:19)
at traverseNode (/home/vibia/platform/services/app-on-site/node_modules/eslint-plugin-react-native/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed.
Exit code: 2