Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking change from 7.25.1 to 7.25.2: incorrect no-unused-vars error #3080

Closed
mrtnzlml opened this issue Sep 21, 2021 · 13 comments
Closed

Breaking change from 7.25.1 to 7.25.2: incorrect no-unused-vars error #3080

mrtnzlml opened this issue Sep 21, 2021 · 13 comments

Comments

@mrtnzlml
Copy link
Contributor

Hello! 👋 I think the problem I am going to describe is because of this PR: #3070 (cc @alanorozco).

Basically, after upgrading eslint-plugin-react from 7.25.1 to 7.25.2 (patch release), we started getting the following error in many files:

error: 'fbt' is defined but never used (no-unused-vars) at src/abacus-backoffice/src/products/ProductAddons.js:5:10:
  3 | import { graphql, useLazyLoadQuery } from '@adeira/relay';
  4 | import { Note, Entity, EntityField, Money, Badge, LayoutBlock } from '@adeira/sx-design';
> 5 | import { fbt } from 'fbt';
    |          ^
  6 | import React, { type Node } from 'react';
  7 | 
  8 | import refineSupportedCurrencies from '../refineSupportedCurrencies';

I guess it's because FBT is a bit strange React citizen and the looks like this:

import fbt from 'fbt';

export default MyComponent() {
  return (
    <Whatever>
      <fbt desc="…">text</fbt>
    </Whatever>
  );
}

But unfortunately, after the aforementioned PR, fbt is no longer being taken into account and no-unused-vars rule throws an error.

Thanks for having a look! 😎 What would be the right way how to fix this issue?

@ljharb
Copy link
Member

ljharb commented Sep 21, 2021

This is actually correct - lowercase tag names, by jsx spec, never point to a value, and only are used as HTML tags.

In other words, if you delete that import, your code should work identically.

@mrtnzlml
Copy link
Contributor Author

mrtnzlml commented Sep 21, 2021

I understand what you are saying. Unfortunately, FBT is a bit weird and doesn't work without the import. For example, I deleted it from the file I mentioned in my issue above and this is what the FBT Collect script throws:

[file="src/products/ProductAddons.js"]:
	Error: /adeira/universe/src/abacus-backoffice/src/products/ProductAddons.js: Line 36 Column 9: fbt is not bound. Did you forget to require('fbt')?
---
fbt("There are no product add-ons yet.", "empty product add-ons message")
---
    at REDACTED
    ^

Error: Failed in 1 file(s).

Removing the import makes the translations broken. 😞

EDIT: the same happens in runtime, not only when collecting the translations. So the whole application doesn't work without the import.

@ljharb
Copy link
Member

ljharb commented Sep 21, 2021

Right, but what if you do import 'fbt'; - ie, a side-effecting import, without any unused bindings?

kodiakhq bot pushed a commit to adeira/universe that referenced this issue Sep 21, 2021
This reverts 3b83b6b because version
7.25.2 causes issues with FBT tags, see: jsx-eslint/eslint-plugin-react#3080
adeira-github-bot pushed a commit to adeira/eslint-config-adeira that referenced this issue Sep 21, 2021
This reverts 3b83b6b3ec610b5d240b933be4c953e5d0e62733 because version
7.25.2 causes issues with FBT tags, see: jsx-eslint/eslint-plugin-react#3080

adeira-source-id: c30973cfbb659a5c7327e8c66ec7c2d662b84bb5
@mrtnzlml
Copy link
Contributor Author

Right, but what if you do import 'fbt'; - ie, a side-effecting import, without any unused bindings?

That, unfortunately, doesn't work either:

Screen Shot 2021-09-21 at 9 29 08

@ljharb
Copy link
Member

ljharb commented Sep 21, 2021

Hmm - does that mean you’re using a non-standard jsx transform?

@mrtnzlml
Copy link
Contributor Author

I am afraid that's exactly how FBT works, yes. Say we have the following minimal example:

import fbt from 'fbt';
function MyComponent() {
  return <fbt desc="…">test</fbt>;
}

It would result in the following code only with @babel/plugin-transform-react-jsx:

import fbt from 'fbt';

function MyComponent() {
  return /*#__PURE__*/React.createElement("fbt", {
    desc: "\u2026"
  }, "test");
}

However, together with babel-plugin-fbt, you get this:

import fbt from 'fbt';

function MyComponent() {
  return fbt._("__FBT__{\"type\":\"text\",\"jsfbt\":\"test\",\"desc\":\"\u2026\",\"project\":\"\"}__FBT__");
}

As described here: https://facebook.github.io/fbt/docs/transform

@ljharb
Copy link
Member

ljharb commented Sep 22, 2021

In that case, i think just like this plugin had “jsx uses react” as a rule, that marks things as used, fbt needs its own rule for this also (not inside this plugin, I’d think).

It should be pretty easy to modify the jsx-uses-react rule for fbt, though.

@mrtnzlml
Copy link
Contributor Author

There is an easy solution/workaround for FBT users: set varsIgnorePattern of no-unused-vars rule to ignore fbt. For example:

'no-unused-vars': [
  ERROR,
  {
    args: 'after-used',
    ignoreRestSiblings: true,
    varsIgnorePattern: '^fbt$', // <<< THIS
  },
],

@ljharb from the aforementioned solutions, which one do you think is the way to go?

  • update no-unused-vars rule configuration as I showed here
  • create a new rule for FBT inspired by jsx-uses-react or jsx-uses-vars (outside of this plugin)
  • update jsx-uses-react or jsx-uses-vars in this repo to take FBT into account

@ljharb
Copy link
Member

ljharb commented Sep 22, 2021

The first option is the simplest, but would cause problems if that variable name was used in your codebase for something different. This risk might be acceptable inside a company's app.

The second and third options would provide the most value for fbt users (not that i think there's many outside of facebook).

By doing the third option, this repo would have to start taking a dev dependency on fbt and start using the jsx transform, in order to test it. The second option seems more "granular" to me.

@mrtnzlml
Copy link
Contributor Author

Thanks for the useful comments @ljharb. Do you think this issue is worth closing? There is an existing workaround and the number of affected users is probably quite low. Moreover, the BC break is because of fbt oddities.

mrtnzlml added a commit to adeira/universe that referenced this issue Sep 22, 2021
This change updates `eslint-plugin-react` to the latest version 7.26.0
and workarounds `fbt` oddities discovered in the previous version (jsx-eslint/eslint-plugin-react#3080).
I added 2 fixtures to make sure `no-unused-vars` rule works as expected
with FBT.

Additionally, it removes unused suppression comments that were also fixed
in previous React plugin version (jsx-eslint/eslint-plugin-react#3063).

Changelog: https://github.com/yannickcr/eslint-plugin-react/blob/eeb0144f14aa972f533e2ef0b094f6742d63c492/CHANGELOG.md#7260---20210920
mrtnzlml added a commit to adeira/universe that referenced this issue Sep 22, 2021
This change updates `eslint-plugin-react` to the latest version 7.26.0
and workarounds `fbt` oddities discovered in the previous version (jsx-eslint/eslint-plugin-react#3080).
I added 2 fixtures to make sure `no-unused-vars` rule works as expected
with FBT.

Additionally, it removes unused suppression comments that were also fixed
in previous React plugin version (jsx-eslint/eslint-plugin-react#3063).

Changelog: https://github.com/yannickcr/eslint-plugin-react/blob/eeb0144f14aa972f533e2ef0b094f6742d63c492/CHANGELOG.md#7260---20210920
@ljharb
Copy link
Member

ljharb commented Sep 22, 2021

I think until we get at least a second commenter on the repo ever that uses fbt, it’s probably best to close :-)

@ljharb ljharb closed this as completed Sep 22, 2021
mrtnzlml added a commit to adeira/universe that referenced this issue Sep 23, 2021
This change updates `eslint-plugin-react` to the latest version 7.26.0
and workarounds `fbt` oddities discovered in the previous version (jsx-eslint/eslint-plugin-react#3080).
I added 2 fixtures to make sure `no-unused-vars` rule works as expected
with FBT.

Additionally, it removes unused suppression comments that were also fixed
in previous React plugin version (jsx-eslint/eslint-plugin-react#3063).

Changelog: https://github.com/yannickcr/eslint-plugin-react/blob/eeb0144f14aa972f533e2ef0b094f6742d63c492/CHANGELOG.md#7260---20210920
mrtnzlml added a commit to adeira/universe that referenced this issue Sep 23, 2021
This change updates `eslint-plugin-react` to the latest version 7.26.0
and workarounds `fbt` oddities discovered in the previous version (jsx-eslint/eslint-plugin-react#3080).
I added 2 fixtures to make sure `no-unused-vars` rule works as expected
with FBT.

Additionally, it removes unused suppression comments that were also fixed
in previous React plugin version (jsx-eslint/eslint-plugin-react#3063).

Changelog: https://github.com/yannickcr/eslint-plugin-react/blob/eeb0144f14aa972f533e2ef0b094f6742d63c492/CHANGELOG.md#7260---20210920
kodiakhq bot pushed a commit to adeira/universe that referenced this issue Sep 23, 2021
This change updates `eslint-plugin-react` to the latest version 7.26.0
and workarounds `fbt` oddities discovered in the previous version (jsx-eslint/eslint-plugin-react#3080).
I added 2 fixtures to make sure `no-unused-vars` rule works as expected
with FBT.

Additionally, it removes unused suppression comments that were also fixed
in previous React plugin version (jsx-eslint/eslint-plugin-react#3063).

Changelog: https://github.com/yannickcr/eslint-plugin-react/blob/eeb0144f14aa972f533e2ef0b094f6742d63c492/CHANGELOG.md#7260---20210920
adeira-github-bot pushed a commit to adeira/eslint-config-adeira that referenced this issue Sep 23, 2021
This change updates `eslint-plugin-react` to the latest version 7.26.0
and workarounds `fbt` oddities discovered in the previous version (jsx-eslint/eslint-plugin-react#3080).
I added 2 fixtures to make sure `no-unused-vars` rule works as expected
with FBT.

Additionally, it removes unused suppression comments that were also fixed
in previous React plugin version (jsx-eslint/eslint-plugin-react#3063).

Changelog: https://github.com/yannickcr/eslint-plugin-react/blob/eeb0144f14aa972f533e2ef0b094f6742d63c492/CHANGELOG.md#7260---20210920

adeira-source-id: 97d82ba734142c6ba2e1c37e3ab006477659b77c
adeira-github-bot pushed a commit to adeira/shipit that referenced this issue Sep 23, 2021
This change updates `eslint-plugin-react` to the latest version 7.26.0
and workarounds `fbt` oddities discovered in the previous version (jsx-eslint/eslint-plugin-react#3080).
I added 2 fixtures to make sure `no-unused-vars` rule works as expected
with FBT.

Additionally, it removes unused suppression comments that were also fixed
in previous React plugin version (jsx-eslint/eslint-plugin-react#3063).

Changelog: https://github.com/yannickcr/eslint-plugin-react/blob/eeb0144f14aa972f533e2ef0b094f6742d63c492/CHANGELOG.md#7260---20210920

adeira-source-id: 97d82ba734142c6ba2e1c37e3ab006477659b77c
@carelulu-igor
Copy link

Hey guys, it seems this bug happens with other types of tags too. Please see my example below.

After updating to v7.26.0 I started to get the following no-unused-vars errors.

/var/lib/jenkins/workspace/v3-app_dev/src/components/Dashboard.js
   8:3  error  'title' is defined but never used  no-unused-vars
   9:3  error  'link' is defined but never used   no-unused-vars
  10:3  error  'meta' is defined but never used   no-unused-vars
  11:3  error  'style' is defined but never used  no-unused-vars

These elements are imported from react-native-web-ui-components/Helmet like this:

import {
  Helmet,
  title,
  link,
  meta,
  style,
} from 'react-native-web-ui-components/Helmet';

What do you think I should do? Use the same workaround as @mrtnzlml did?

@ljharb
Copy link
Member

ljharb commented Oct 4, 2021

@carelulu-igor all lowercase tags in jsx are HTML tags. You can't import style, for example, and use it in <style> - it's not getting used there at all.

The above case is using fbt, a custom jsx transform. The way the rest of the ecosystem uses jsx, what I said above applies.

In React Native, I would expect <style> to always be an error, since that's an HTML tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants