-
Notifications
You must be signed in to change notification settings - Fork 395
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
Proposed linting config updates #669
Conversation
what if we remove dependency on Prettier, and solely rely on ESLint? it seems we will lose some strictness in our enforcement, but possibly gain a better development experience in this codebase. Prettier reprints the entire program following its own style (subject to a few config options) but its style is often subpar for our needs. it also can be tricky for IDEs, extensions, and CI to integrate with. we've had our fair share of issues and exploring this direction will allow us to understand what we might gain and whether its worth it.
TODO: lint rules for test files (*.spec.ts) starting off with some well considered and inherited rules. will evaluate the impact of these rules on a file or two to see how well they hold up.
there are still warnings in the file, and that's okay for now. we're getting pretty close a good spot to collect feedback.
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.
Did a first pass of the eslintrc
and App.ts
. Still need to run it locally.
// no reason we cannot adopt this syntax now. | ||
// NOTE: The `@typescript-eslint/no-require-imports` rule can also achieve the same effect, but it is less | ||
// configurable and only built to provide a migration path from TSLint. | ||
'import/no-commonjs': ['error', { |
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.
can this rule still be overridden inline? I've seen a few places in our code that require('package.json')
. Importing it instead breaks our dist
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.
good question! let me know if it breaks the dist after you try. not sure if this is what you've tried in the past, but i also updated the tsconfig.json
to turn on the resolveJsonModule
option. that might make the difference.
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.
I used resolveJsonModule
option last time I tried. Just pulled this locally and this issue exists. You can see it by running npm pack
in your root directly (the command npm publish
uses under the hood to build the archive). The package that is created is missing all of dist pretty much.
|
||
// Allow cyclical imports. Turning this rule on is mainly a way to manage the performance concern for linting | ||
// time. Our projects are not large enough to warrant this. Overrides AirBnB styles. | ||
'import/no-cycle': 'off', |
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.
I believe we have inline exceptions to this rule, but I'll have to look it up
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.
sounds like we can remove those inline exceptions then 🙌 . this is a good reminder that as we update the other sources for this config (item in the TODO) we should audit all the inline exceptions with a goal to remove as many as possible.
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.
Last time I looked I didn't manage to remove the exceptions for this. We can take another spin this go around
(this.receiver as ExpressReceiver).installer !== undefined && | ||
(this.receiver as ExpressReceiver).installer!.authorize !== undefined | ||
) { | ||
if ((this.receiver as ExpressReceiver).installer !== undefined |
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 looks way better IMO
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.
thanks for the validation! humans: 1, prettier: 0. this takes a small manual effort and an eye for clarity, but i hope we all feel the result is worth it.
@@ -380,10 +367,11 @@ export default class App { | |||
callbackIdOrConstraints: string | RegExp | Constraints, | |||
...listeners: Middleware<SlackShortcutMiddlewareArgs<Extract<Shortcut, { type: Constraints['type'] }>>>[] | |||
): void { | |||
const constraints: ShortcutConstraints = | |||
const constraints: ShortcutConstraints = ( |
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.
I like that we are bringing back the round bracket to encapsulate the code below. I like this style better. Prettier removed them.
: type === IncomingEventType.Command | ||
? ((body as SlackCommandMiddlewareArgs['body']).user_id as string) | ||
: undefined, | ||
const teamId: string = (() => { |
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 refactor is much easier to read and follow. Good stuff!
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.
🙏
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.
i'm pretty happy that there are a lot less type assertions this way!
import { Agent } from 'http'; | ||
import { SecureContextOptions } from 'tls'; | ||
import util from 'util'; | ||
import { WebClient, ChatPostMessageArguments, addAppMetadata, WebClientOptions } from '@slack/web-api'; | ||
import { Logger, LogLevel, ConsoleLogger } from '@slack/logger'; | ||
import axios, { AxiosInstance } from 'axios'; | ||
import allSettled from 'promise.allsettled'; |
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.
I also want to add that I saw issues with removing require from allSettled
last time too, but I don't remember what that issue was off the top of my head
@@ -0,0 +1,15 @@ | |||
import { WebClient, WebClientOptions } from '@slack/web-api'; |
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.
I like this idea but how about doing this in another (smaller) pull request?
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.
its related to getting the lint rules to pass. the rule is max-classes-per-file
. we could do this in a separate PR if we want to land it before this PR. otherwise this PR will be blocked on failing its own lint.
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.
Thanks for sharing the context.
we could do this in a separate PR if we want to land it before this PR
I think there is no blocker for it. If we separate this change, we can quickly review and merge it. Also, if the change has issues by any chance, it's much easier to revert.
Once we removed StringIndexed from SlackEvent types, many property lookups became typechecking errors. I borrowed this refactor mostly from a WIP PR to improve our style/linting in a proactive effort to redue conflicts when that PR lands. The only changes I needed to add were the Org Apps changes that had landed on main. slackapi#669 In a few cases, the event types had other issues that became apparent only after removing the aggressive casting we had before. Those are fixed. It's now evident that there's more type related problems with respect to the Authorize, its related types, especially the OrgApps variants. I'll try to fix these next. It's also not clear if buildSource needs the orgInstall argument. Will seek advice in code review for that.
@stevengill will revisit this soon. |
Closing this in favour of #1024 - which is wholly based on the efforts in this PR. Thank you to everyone involved! |
Summary
This PR explores using a linting configuration that is different in a few key ways:
slackapi
.overrides
to create an obvious space for additional tweaks based on their desired affects. For example, it's clear where to add new rules that only apply to TypeScript, new rules that apply to both TypeScript and JavaScript, or a rule configuration that overrides an existing rule from the above configs.Disadvantages
The main disadvantage of this config is the loss of the
indent
rule within TypeScript. The author of the TypeScript-specific fork of that rule has decided not to maintain it any longer, and has acknowledged that the rule currently in a broken state. The author prefers to use Prettier in their own work, which relieved them of the need to work on that rule. But Prettier is highly opinionated as a formatter, and not nearly as configurable, so in this change we've made the tradeoff that this flexibility is worth the cost of not having a goodindent
rule in*.ts
files.The next largest disadvantage is lack of enforcement on JSDoc descriptions for all public API. This isn't a regression though, the current config also doesn't enforce this.
A few other rules are less than perfect, but those shortcomings have been described in the comments. Where possible, a link to relevant issues to watch have been added.
Feedback needed
The
src/App.ts
file was migrated to pass this config in order to aide discussion of this config. Please look at the changes in this one file, and let us know if any changes don't sit well with you. Feel free to be as opinionated or subjective as you want. Now is a good time to get aligned. After that, it should be relatively straight-forward to update the rest of the source files to pass.Are any of the disadvantages dealbreakers?
TODO
*.spec.js
and*.spec.ts
files, to describe unique environment (mocha globals) and conventions.src/App.ts
). This should happen after other maintainers have offered feedback.package.json
, re-enable format on save for VSCode in the settings.Requirements (place an
x
in each[ ]
)