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
[eslint-config-universe] Add more lint rules for TypeScript #6783
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Splitting out the config that uses type analysis looks good. I think we should rename "universe/shared/typescript-parsed-linting" to something else for a couple small reasons:
- "linting" is implied: we don't name the other configs "web-linting", for example
- "parsed" is also implied: the linter always parses
some suggestions: typescript-analysis
, typescript-typed
packages/eslint-config-universe/__tests__/fixtures/tsconfig.json
Outdated
Show resolved
Hide resolved
@@ -31,6 +69,15 @@ module.exports = { | |||
{ | |||
files: ['*.ts', '*.tsx', '*.d.ts'], | |||
parser: '@typescript-eslint/parser', | |||
rules: { | |||
'@typescript-eslint/naming-convention': [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this rule need the TS parser? Can it go under the regular rules
section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to remove this for now as it causes too many errors in the expo packages.
Also after this commit we'll need to re-lint all the files. (Might want a small zsh script for this.) |
expotools check-packages --no-build --no-test --fix-lint
16d4222
to
67a227f
Compare
Made updates based on code review and fixed lint. To ease review, this PR has 6 commits:
Also lol codeowners really owned this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (consider this a soft approval) with just a few comments left inline. Tests look good (failing iOS test is unrelated).
@@ -2,8 +2,8 @@ | |||
"name": "expo-gl", | |||
"version": "8.0.0", | |||
"description": "Provides GLView that acts as OpenGL ES render target and gives GL context object implementing WebGL 2.0 specification.", | |||
"main": "build/index.js", | |||
"types": "build/index.d.ts", | |||
"main": "build/src/index.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a new change? Code from src/<X>
should end up in build/<X>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. It's caused by the following change in packages/expo-gl/src/GLView.tsx
:
- const packageJSON = require('../package.json');
+ import packageJSON from '../package.json';
Because of this and how typescript emits, the emitted package.json appears in the toplevel directory (build/
) and the rest of the source must be one level deeper, so it looks like tsc automatically chose src
as the subdirectory name.
This conversion was necessary because the import order linter warned about a relative import being out of order when it was places below other imports, but when placed above other imports a different linter warned that a const assignment appeared above an import (code appearing above import). Alternatively, we could disable the linter for this file, but from reading README the philosophy seemed to be fairly against the disabling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense but I don't think that shipping code under build/src
for some packages (specifically ones that import package.json) and under build
for others is a good idea. It's going to create confusion when different packages are structured differently, and when adding or removing the import can completely change a package's build path!
Philosophically, the intent of the linter is to reduce the attention cost of writing code. If the linter ends up adding new warnings that we need to disable except in very rare cases, we're just moving attention cost around instead of reducing it. Ideally we'd be able to keep the old require()
call in this case.
The ESLint import order plugin says, "Statements using the ES6 import syntax must appear before any require() statements." This sounds different than the behavior you were seeing, but if we could get the import order plugin to have this behavior it sounds like we'd be able to use require()
and address this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why
In a recent universe PR (https://github.com/expo/universe/pull/4068) upstreaming some of the newly added TypeScript and import order rules was discussed. This PR adds/updates the following lint rules:
import/order
to alphabetize imports and add newlines between import type groups. Reasoning is that this seems to be the preferred import convention from recent code reviews.ban-types
- Disallow non-primitive boxed object types in typescript, which are explicitly discouraged in the TypeScript docs: https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#general-typesarray-type
- Enforce using the[]
array specification syntax for TypeScript. - https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/array-type.mdno-extra-non-null-assertion
- Warns when something likevariable!!
is used whenvariable!
is sufficient (thanks kotlin). - https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-extra-non-null-assertion.mdno-for-in-array
- Errors when usingfor...in
-loop for an array, which is nearly always not what a develope means to do, as it iterates over the string properties of the Array object. - https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-for-in-array.mdno-throw-literal
- It seems to be commonly accepted that it's better to throw aError
or a subclass ofError
- https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-throw-literal.mdprefer-nullish-coalescing
- Warns when a nullish coalescing operator (new in TS 3.7) could be used, added to speed up code reviews - https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdprefer-optional-chain
- Warns when an optional chain can be used (new in TS 3.7), added to speed up code reviews - https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/prefer-optional-chain.mdHow
Rules copied from universe repo, used
yarn link
to link local updated version ofeslint-config-universe
into universe, rules removed from universe local config.Some of the added rules require type information from the TypeScript parser (part of @typescript-eslint/parser). Forcing this would be a breaking change, so to avoid that (and only need to increment the minor version number), the rules that require the type information were siloed into their own config extension and instructions were added to the README about how to utilize them. Version was bumped from 2.1.1 to 2.2.0 based on semver guidelines.
Looking for feedback on:
Test Plan
yarn link
method above and manually breaking the rules in universe code.yarn test
, verifying that the snapshots are generating the correct output.