profile
viewpoint
Joe Lencioni lencioni Airbnb 55057 http://twitter.com/lencioni Web infrastructure at @airbnb

Khan/aphrodite 5076

Framework-agnostic CSS-in-JS with support for server-side rendering, browser prefixing, and minimum CSS generation

civiccc/react-waypoint 3609

A React component to execute a function whenever you scroll to an element.

cpojer/js-codemod 991

Codemod scripts to transform code to next generation JS

Galooshi/import-js 502

A tool to simplify importing JS modules

airbnb/dynein 254

Airbnb's Open-source Distributed Delayed Job Queueing System

civiccc/react-simple-pie-chart 62

Simple pie chart React component

happo/lcs-image-diff 5

A JavaScript library to diff two images. Uses the LCS algorithm to allow content to shift.

lencioni/agent_orange 1

Parse and process User Agents like a secret one

lencioni/ama 1

Ask me anything!

issue commentmicrosoft/vscode-eslint

Editor freezes when using replace in files for > 200 files,

Could this be related? https://github.com/microsoft/vscode-eslint/issues/1033

lencioni

comment created time in 2 days

PR opened happo/happo.io

Reviewers
Find asset paths in picture source srcsets

We received a report of a confusing Happo report. Looking at the source of the "after" version, the problematic part seemed to be related to a <picture> element with nested <source> elements that used srcset. After downloading the assets zip file for this report, we noticed that the assets for these images were not included. I suspected that this was related to our asset finding code, which we confirmed by pushing up a change that included regular <img> tags with the same assets, which ended up fixing the confusing report.

To fix this bug, we can include these elements in our srcset extraction query selector. Since <source> is used for <picture>, <video>, and <audio>, I scoped the selector to source elements that descend from picture elements to avoid also grabbing audio and video files, which I think we do not want in these bundles.

+45 -11

0 comment

2 changed files

pr created time in 3 days

create barnchhappo/happo.io

branch : source-srcset

created branch time in 3 days

issue commentoctokit/auth-app.js

Cannot specify permissions option when using createAppAuth and auth.hook

We've recently updated GHE to 2.20.12 and I tried this stuff again and I'm seeing similar behavior.

  • Fresh install of required packages: 406 error
  • Only change {} to { permissions: {} } in @octokit/auth-app/dist-node/index.js line 288: 406 error
  • Only add requestOptions.url = requestOptions.url.replace('/api/app/installations/', '/api/v3/app/installations/'); to the fetchWrapper function in @octokit/request/dist-node/index.js (line 28): Successful request

So it seems that the newer version of GHE no longer needs the empty permissions object, but the URLs are still not able to be set correctly to get through a GraphQL request that also ends up making a REST request for authentication, since it tries to POST to /api/app/installations/<APP ISSUER ID>/access_tokens instead of /api/v3/app/installations/<APP ISSUER ID>/access_tokens.

lencioni

comment created time in 5 days

PR opened bramstein/url-template

Change license spdx from BSD to BSD-3-Clause

The "BSD" spdx refers to the original, controversial 4-clause BSD license. At a glance, it looks like the license file in this repo is actually using the 3-clause license, which has a spdx of "BSD-3-Clause".

https://spdx.org/licenses/BSD-3-Clause.html

+1 -1

0 comment

1 changed file

pr created time in 8 days

create barnchlencioni/url-template

branch : license

created branch time in 8 days

fork lencioni/url-template

A JavaScript URI template implementation (RFC 6570 compliant)

fork in 8 days

issue commentoctokit/auth-app.js

Cannot specify permissions option when using createAppAuth and auth.hook

@gr2m is there any more information I can provide to help move this to the next step?

lencioni

comment created time in 10 days

issue commentairbnb/javascript

The JavaScript Style Guide Guide Reference link is broken in README.md

Ah, I found it https://github.com/airbnb/javascript/wiki/The-JavaScript-Style-Guide-Guide

I've re-enabled the wiki, but to be honest I'm not really sure it adds much value. We should probably just move this content to the readme or something instead.

jeffvandyke

comment created time in 17 days

push eventairbnb/eslint-plugin-miniprogram

dependabot[bot]

commit sha d197fc486a4c6cc449ee3ba0a7c75f6394033553

Bump lodash from 4.17.15 to 4.17.19 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] <support@github.com>

view details

Joe Lencioni

commit sha d7f7af9a1bae37db678d282dff42bd4268f31efb

Merge pull request #16 from airbnb/dependabot/npm_and_yarn/lodash-4.17.19 Bump lodash from 4.17.15 to 4.17.19

view details

push time in a month

PR merged airbnb/eslint-plugin-miniprogram

Bump lodash from 4.17.15 to 4.17.19 dependencies

Bumps lodash from 4.17.15 to 4.17.19. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/lodash/lodash/releases">lodash's releases</a>.</em></p> <blockquote> <h2>4.17.16</h2> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/lodash/lodash/commit/d7fbc52ee0466a6d248f047b5d5c3e6d1e099056"><code>d7fbc52</code></a> Bump to v4.17.19</li> <li><a href="https://github.com/lodash/lodash/commit/2e1c0f22f425e9c013815b2cd7c2ebd51f49a8d6"><code>2e1c0f2</code></a> Add npm-package</li> <li><a href="https://github.com/lodash/lodash/commit/1b6c282299f4e0271f932b466c67f0f822aa308e"><code>1b6c282</code></a> Bump to v4.17.18</li> <li><a href="https://github.com/lodash/lodash/commit/a370ac81408de2da77a82b3c4b61a01a3b9c2fac"><code>a370ac8</code></a> Bump to v4.17.17</li> <li><a href="https://github.com/lodash/lodash/commit/1144918f3578a84fcc4986da9b806e63a6175cbb"><code>1144918</code></a> Rebuild lodash and docs</li> <li><a href="https://github.com/lodash/lodash/commit/3a3b0fd339c2109563f7e8167dc95265ed82ef3e"><code>3a3b0fd</code></a> Bump to v4.17.16</li> <li><a href="https://github.com/lodash/lodash/commit/c84fe82760fb2d3e03a63379b297a1cc1a2fce12"><code>c84fe82</code></a> fix(zipObjectDeep): prototype pollution (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4759">#4759</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/e7b28ea6cb17b4ca021e7c9d66218c8c89782f32"><code>e7b28ea</code></a> Sanitize sourceURL so it cannot affect evaled code (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4518">#4518</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/0cec225778d4ac26c2bac95031ecc92a94f08bbb"><code>0cec225</code></a> Fix lodash.isEqual for circular references (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4320">#4320</a>) (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4515">#4515</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/94c3a8133cb4fcdb50db72b4fd14dd884b195cd5"><code>94c3a81</code></a> Document matches* shorthands for over* methods (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4510">#4510</a>) (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4514">#4514</a>)</li> <li>Additional commits viewable in <a href="https://github.com/lodash/lodash/compare/4.17.15...4.17.19">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~mathias">mathias</a>, a new releaser for lodash since your current version.</p> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the Security Alerts page.

</details>

+3 -3

0 comment

1 changed file

dependabot[bot]

pr closed time in a month

issue commentoctokit/auth-app.js

Cannot specify permissions option when using createAppAuth and auth.hook

@gr2m did you find out anything useful yesterday?

lencioni

comment created time in a month

PR merged airbnb/js-shims

Fix es5-sham link

This just complete's the suggestion from @ljharb here: https://github.com/airbnb/js-shims/pull/9#discussion_r278313934 Closes #9

+1 -1

0 comment

1 changed file

devinrhode2

pr closed time in a month

push eventairbnb/js-shims

Devin Rhode

commit sha 9177278ffd9f424fe49af7aef424c04592d3548c

Fix es5-sham link This just complete's the suggestion from @ljharb here: https://github.com/airbnb/js-shims/pull/9#discussion_r278313934 Closes #9

view details

Joe Lencioni

commit sha 339192174a67f323bb92cde5e99e098bf87860bf

Merge pull request #13 from devinrhode2/patch-1 Fix es5-sham link

view details

push time in a month

PR closed airbnb/js-shims

FIX typo
+1 -1

0 comment

1 changed file

ndelangen

pr closed time in a month

issue commentoctokit/auth-app.js

Cannot specify permissions option when using createAppAuth and auth.hook

It was tricky to make a successful request to test this. Here's the script I used:

const { createAppAuth } = require('@octokit/auth-app');
const { graphql } = require('@octokit/graphql');
const jsonwebtoken = require('jsonwebtoken');
const octokit = require('@octokit/rest');

const { request } = require('@octokit/request');

const { GITHUB_BASE_URL, GITHUB_APP_PEM_BASE64, GITHUB_APP_ISSUER_ID } = process.env;

const PEM = Buffer.from(GITHUB_APP_PEM_BASE64.trim(), 'base64').toString('ascii');

function graphqlForInstallation(installationId) {
  const auth = createAppAuth({
    id: GITHUB_APP_ISSUER_ID,
    privateKey: PEM,
    installationId,
    request: request.defaults({
      baseUrl: `${GITHUB_BASE_URL}/api/v3`,
    }),
  });

  const graphqlWithAuth = graphql.defaults({
    baseUrl: `${GITHUB_BASE_URL}/api`,
    request: {
      hook: auth.hook,
    },
  });

  return graphqlWithAuth;
}

async function main () {
  const client = graphqlForInstallation(1);

  let data;
  try {
    data = await client(
    `
      query getCommits($name: String!, $owner: String!, $defaultBranch: String!, $since: GitTimestamp) {
        repository(name: $name, owner: $owner) {
          ref(qualifiedName: $defaultBranch) {
            target {
              ... on Commit {
                id
                history(first: 100, since: $since) {
                  pageInfo {
                    hasNextPage
                    endCursor
                  }
                  edges {
                    node {
                      oid
                      committer {
                        date
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }

    `,
      {
        name: 'repo-name',
        owner: 'repo-owner',
        defaultBranch: 'master',
        since: '2020-06-18T00:00:00.000Z',
      },
    );
  } catch (e) {
    throw e;
  }

  console.log(data);
}

main().catch(e => { console.error(e); });

I was getting stuck on only receiving 406 Not Acceptable responses. I've looked at issues like https://github.com/octokit/request.js/issues/83 which suggest setting the accept header to application/json instead of application/vnd.github.machine-man-preview+json which I tried doing in a hacky way by adding this to @octokit/request/dist-node/index.js at line 27, but I still end up with the same result.

requestOptions.headers.accept = 'application/json';

Looking at the request URL that we are hitting, I suspected that the base URL here might not be correct. So I added this hacky thing to @octokit/request/dist-node/index.js at line 27 as well:

requestOptions.url = requestOptions.url.replace('/app/installations/', '/api/v3/app/installations/');

which gave me a new error response:

415 Unsupported Media Type

If I remove the accept header hack and leave the URL hack, it seems to get past this to actually make the graphql request!

If I leave getInstallationAuthentication with an empty object as the second arg as it is currently published, I get the following error:

TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at set (/private/tmp/ghe/node_modules/@octokit/auth-app/dist-node/index.js:65:63)
    at getInstallationAuthentication (/private/tmp/ghe/node_modules/@octokit/auth-app/dist-node/index.js:161:9)
    at process._tickCallback (internal/process/next_tick.js:68:7)

If I set it to be { permissions: {} }, the request is successful.

So I think adding that empty object resolves part of the problem here for me, but I've also uncovered a different issue which is that I need two different baseUrl options here (one with /api/v3 for REST requests and one with /api for graphql requests. @gr2m do you have any thoughts on how we might be able to solve that problem? Or, am I just configuring something incorrectly here?

  const auth = createAppAuth({
    id: GITHUB_APP_ISSUER_ID,
    privateKey: PEM,
    installationId,
    request: request.defaults({
      baseUrl: `${GITHUB_BASE_URL}/api/v3`,
    }),
  });

  const graphqlWithAuth = graphql.defaults({
    baseUrl: `${GITHUB_BASE_URL}/api`,
    request: {
      hook: auth.hook,
    },
  });
lencioni

comment created time in a month

issue commentairbnb/lunar

OT: Airbnb reviews collapse whitespace

The bug I filed for your original issue has been triaged but it is still open.

dandv

comment created time in a month

issue commentairbnb/lunar

OT: Airbnb reviews collapse whitespace

@dandv are you referring to the notifications here? https://www.airbnb.com/alerts

dandv

comment created time in a month

issue commentoctokit/auth-app.js

Cannot specify permissions option when using createAppAuth and auth.hook

@gr2m I hope you had a great holiday! How do you want to proceed here?

lencioni

comment created time in a month

pull request commentfacebook/react

Fix ExhaustiveDeps ESLint rule throwing with optional chaining

I've poked around a bit and I'm not sure what the best solution is yet. One way to fix this would be to normalize the paths in the dependencies Map like this maybe:

--- a/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
+++ b/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
@@ -561,7 +561,7 @@ export default {
             const isStatic =
               memoizedIsStaticKnownHookValue(resolved) ||
               memoizedIsFunctionWithoutCapturedValues(resolved);
-            dependencies.set(dependency, {
+            dependencies.set(dependency.replace(/\?/g, ''), {
               isStatic,
               references: [reference],
             });

but the downside is the error messages and suggestions will drop the optional chaining, which is not ideal.

I started to investigate fixing it on the other end (so that the missingDependencies Set includes the optional chaining) but that train ended up getting deeper than I have time to investigate at the moment (missingDependencies is built from depTree which comes from createDepTree which ends up normalizing the paths somehow--I think possibly by getChildByKey).

I can modify this PR to normalize out the optional chaining, or leave it as is. Anything more involved I'll have to set this aside for a while. Or perhaps @yanneves or @fredvollmer can offer some better insights, since it seems they've also been in this part of the codebase recently?

lencioni

comment created time in a month

pull request commentfacebook/react

Fix ExhaustiveDeps ESLint rule throwing with optional chaining

Yep, looking into that now. In b0533fe33c it looks like the missingDependencies is normalized to remove the ? bits, so I suppose we could do the same for the dependencies Map keys, which I think would just mean using the normalizedPath instead of path in scanTreeRecursively.

lencioni

comment created time in a month

pull request commentfacebook/react

Fix ExhaustiveDeps ESLint rule throwing with optional chaining

It looks like there is a mismatch between the keys in the dependencies Map and the keys in missingDependencies. The Map includes the optional chaining in its keys (e.g. pizza?.toppings) while the missingDependencies array does not (e.g. pizza.toppings).

lencioni

comment created time in a month

issue commentfacebook/react

Bug: Cannot read property 'references' of undefined in eslint-plugin-react-hooks v4.0.5

@gaearon I put up a potential fix here: https://github.com/facebook/react/pull/19260

lencioni

comment created time in a month

push eventlencioni/react

Joe Lencioni

commit sha 44b93b67a2fce09c985cb7d784c3dd54e66b25f2

Fix ExhaustiveDeps ESLint rule throwing with optional chaining Certain code patterns using optional chaining syntax causes eslint-plugin-react-hooks to throw an error. We can avoid the throw by adding some guards. I didn't read through the code to understand how it works, I just added a guard to every place where it threw, so maybe there is a better fix closer to the root cause than what I have here. In my test case, I noticed that the optional chaining that was used in the code was not included in the suggestions description or output, but it seems like it should be. This might make a nice future improvement on top of this fix, so I left a TODO comment to that effect. Fixes #19243

view details

push time in a month

PR opened facebook/react

Fix ExhaustiveDeps ESLint rule throwing with optional chaining

<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory.

Before submitting a pull request, please make sure the following is done:

  1. Fork the repository and create your branch from master.
  2. Run yarn in the repository root.
  3. If you've fixed a bug or added code that should be tested, add tests!
  4. Ensure the test suite passes (yarn test). Tip: yarn test --watch TestName is helpful in development.
  5. Run yarn test-prod to test in the production environment. It supports the same options as yarn test.
  6. If you need a debugger, run yarn debug-test --watch TestName, open chrome://inspect, and press "Inspect".
  7. Format your code with prettier (yarn prettier).
  8. Make sure your code lints (yarn lint). Tip: yarn linc to only check changed files.
  9. Run the Flow type checks (yarn flow).
  10. If you haven't already, complete the CLA.

Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html -->

Summary

<!-- Explain the motivation for making this change. What existing problem does the pull request solve? --> Certain code patterns using optional chaining syntax causes eslint-plugin-react-hooks to throw an error.

We can avoid the throw by adding some guards. I didn't read through the code to understand how it works, I just added a guard to every place where it threw, so maybe there is a better fix closer to the root cause than what I have here.

In my test case, I noticed that the optional chaining that was used in the code was not included in the suggestions description or output, but it seems like it should be. This might make a nice future improvement on top of this fix, so I left a TODO comment to that effect.

Fixes #19243

Test Plan

<!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes the user interface. -->

yarn test --watch eslint-plugin
+42 -4

0 comment

3 changed files

pr created time in a month

create barnchlencioni/react

branch : issue-19243

created branch time in a month

fork lencioni/react

A declarative, efficient, and flexible JavaScript library for building user interfaces.

https://reactjs.org

fork in a month

pull request commentjest-community/jest-runner-eslint

feat: Support ESLint 7.x

This package is still pre-1.0 so that change could be either 0.10.0 or 1.0.0.

MichaelDeBoey

comment created time in a month

issue commentoctokit/auth-app.js

Cannot specify permissions option when using createAppAuth and auth.hook

@gr2m Thanks for the quick response! The best approach here is not super clear to me. Three options immediately come to mind:

  1. Allow hook options to be passed to createAppAuth in some way and propagate them down the chain. If we go with this, I'm not sure if the options need to be scoped in some way so they only get passed to the getInstallationAuthentication call (e.g. via a getInstallationApplicationOptions property) or if we can add a more generally named property. Some guidance here would be appreciated.
  2. Change the argument passed to getInstallationAuthentication from {} to { permissions: {} }.
  3. Add a default value to get-installation-authentication.js (e.g. permissions: options.permissions || {}).

Of these options, I think I prefer 3 because the size of the change is relatively small and I think this would help solve this problem everywhere (might allow us to remove the caveat note from the docs). Failing that, my second choice would be 2 because it would still be a small change for me to make.

What is your preference here?

lencioni

comment created time in a month

issue commentjest-community/jest-runner-eslint

TypeError: Converting circular structure to JSON

Upstream bug report: https://github.com/facebook/react/issues/19243

lencioni

comment created time in a month

issue openedfacebook/react

Bug: Cannot read property 'references' of undefined in eslint-plugin-react-hooks v4.0.5

<!-- Please provide a clear and concise description of what the bug is. Include screenshots if needed. Please test using the latest version of the relevant React packages to make sure your issue has not already been fixed. -->

Certain code patterns using optional chaining syntax causes eslint-plugin-react-hooks to throw an error.

React version: 16.10.2

Steps To Reproduce

  1. Install eslint-plugin-react-hooks v4.0.5
  2. Put this code in a file:
import React, { useEffect } from 'react';

export const Repro = (props) => {
  const foo = {};

  const bar = () => ({
    pizza: foo.pizza,
    pasta: foo?.pasta,
  });

  useEffect(bar, []);

  return <div />;
};

<!-- Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Issues without reproduction steps or code examples may be immediately closed as not actionable. -->

<!-- Please provide a CodeSandbox (https://codesandbox.io/s/new), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem. You may provide a screenshot of the application if you think it is relevant to your bug report. Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve. -->

The current behavior

ESLint throws the following error:

TypeError: Cannot read property 'references' of undefined
Occurred while linting /path/to/repo/file.ts:102
    at /path/to/repo/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js:1681:23
    at Set.forEach (<anonymous>)
    at visitFunctionWithDependencies (/path/to/repo/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js:1672:29)
    at visitCallExpression (/path/to/repo/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js:886:19)
    at /path/to/repo/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/path/to/repo/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/path/to/repo/node_modules/eslint/lib/linter/node-event-generator.js:254:26)
    at NodeEventGenerator.applySelectors (/path/to/repo/node_modules/eslint/lib/linter/node-event-generator.js:283:22)
    at NodeEventGenerator.enterNode (/path/to/repo/node_modules/eslint/lib/linter/node-event-generator.js:297:14)

The expected behavior

ESLint does not throw an error.

This looks related to https://github.com/facebook/react/issues/19043 and https://github.com/facebook/react/pull/19062.

I've noticed that it does not throw if a number of slight variations are made to the code. The following do not throw:

import React, { useEffect } from 'react';

export const Repro = (props) => {
  const foo = {};

  const bar = {
    pizza: foo.pizza,
    pasta: foo?.pasta,
  };

  useEffect(bar, []);

  return <div />;
};
import React, { useEffect } from 'react';

export const Repro = (props) => {
  const foo = {};

  const bar = () => ({
    pizza: foo?.pizza,
    pasta: foo?.pasta,
  });

  useEffect(bar, []);

  return <div />;
};
import React, { useEffect } from 'react';

export const Repro = (props) => {
  const foo = {};

  const bar = () => ({
    pizza: something.pizza,
    pasta: foo?.pasta,
  });

  useEffect(bar, []);

  return <div />;
};

cc @krailler

created time in a month

issue commentjest-community/jest-runner-eslint

TypeError: Converting circular structure to JSON

I've narrowed it down a bit more, at least for some of these. This issue seems to arise in a handful of files when I am updating eslint-plugin-react-hooks from 2.5.1 to 4.0.5. When I run eslint without the jest runner, I get a more useful error here:

TypeError: Cannot read property 'references' of undefined
Occurred while linting /path/to/repo/file.ts:102
    at /path/to/repo/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js:1681:23
    at Set.forEach (<anonymous>)
    at visitFunctionWithDependencies (/path/to/repo/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js:1672:29)
    at visitCallExpression (/path/to/repo/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js:886:19)
    at /path/to/repo/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/path/to/repo/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/path/to/repo/node_modules/eslint/lib/linter/node-event-generator.js:254:26)
    at NodeEventGenerator.applySelectors (/path/to/repo/node_modules/eslint/lib/linter/node-event-generator.js:283:22)
    at NodeEventGenerator.enterNode (/path/to/repo/node_modules/eslint/lib/linter/node-event-generator.js:297:14)

In this particular case, I was able to reproduce it with this file:

import React, { useEffect, useContext } from 'react';

export const Repro = (props) => {
  const fooContext = useContext(foo);

  const bar = () => {
    baz({
      pizza: fooContext.pizza,
      pasta: fooContext?.pasta?.sauce,
    });
  };

  useEffect(bar, []);

  return <div />;
};

If I change this file in a number of ways (e.g. removing the pizza, removing useContext, or removing one of the optional chaining operators), it doesn't cause this error. This is almost certainly a bug in the rule (I'll file an issue upstream), but it seems that jest-runner-eslint should be able to handle this more clearly instead of adding an additional failure on top of it that obscures the root cause.

lencioni

comment created time in a month

pull request commentjest-community/jest-runner-eslint

feat: Support ESLint 7.x

I think we should just drop support for eslint 4 here.

MichaelDeBoey

comment created time in a month

issue openedoctokit/auth-app.js

Cannot specify permissions option when using createAppAuth and auth.hook

This is similar to #47, but when using createAppAuth.

We have some code that looks like this:

function graphqlForInstallation(installationId) {
  const auth = createAppAuth({
    id: GITHUB_APP_ISSUER_ID,
    privateKey: PEM,
    installationId,
    request: request.defaults({
      baseUrl: `${GITHUB_BASE_URL}/api/v3`,
    }),
  });
  const graphqlWithAuth = graphql.defaults({
    baseUrl: GITHUB_BASE_URL,
    request: {
      hook: auth.hook,
    },
  });
  return graphqlWithAuth;
}

When this is used with public GitHub it works okay. However, when it is used with GHE v2.18 (specifically tried with 2.18.20), we get an error with the following stack trace (partial, starting at @octokit/auth-app code):

TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at set (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:65:63)
    at getInstallationAuthentication (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:161:9)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async hook (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:280:7)

I looked into applying the workaround mentioned in #47, but after reading through some of the code here, I think that may not be possible at this time.

Looking at the stack trace, the problem seems to be when octokit is getting installation authentication via the request auth hook

    at getInstallationAuthentication (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:161:9)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async hook (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:280:7)

I believe that is called right here: https://github.com/octokit/auth-app.js/blob/71e1d1d8a2672686464a9399655bcd8872da6e58/src/hook.ts#L32

This is calling getInstallationAuthentication with {} as the second argument. Here's the signature: https://github.com/octokit/auth-app.js/blob/71e1d1d8a2672686464a9399655bcd8872da6e58/src/get-installation-authentication.ts#L11-L15

The second argument here is options, which is where it pulls permissions when making the request: https://github.com/octokit/auth-app.js/blob/71e1d1d8a2672686464a9399655bcd8872da6e58/src/get-installation-authentication.ts#L58-L61

So since createAppAuth or the hook do not provide a way for us to specify this permissions option, I don't think we can use this workaround with createAppAuth.

Is there an alternative approach we could use here, or would you be open to making a change to this package to make this work?

created time in a month

PR opened octokit/auth-app.js

Fix auth.hook link in README table of contents

GitHub uses a slightly different hash here.

+1 -1

0 comment

1 changed file

pr created time in a month

push eventlencioni/auth-app.js

Joe Lencioni

commit sha c1c431e0723c437b1fd162d8ef55a0aee0447571

Fix auth.hook link in README table of contents GitHub uses a slightly different hash here.

view details

push time in a month

fork lencioni/auth-app.js

GitHub App authentication for JavaScript

fork in a month

issue commenthappo/happo-jest

Technical design discussion

jest-playwright might be worth a look: https://github.com/playwright-community/jest-playwright

trotzig

comment created time in a month

issue commenthappo/happo-jest

Technical design discussion

Is the idea here for making a jest runner that runs all of the Happo tests (e.g. like jest-runner-eslint for running ESLint), or is this for adding Happo tests to existing jest runs?

trotzig

comment created time in a month

PR opened jest-community/create-jest-runner

Update repo and homepage in package.json

This repo has moved.

+2 -2

0 comment

1 changed file

pr created time in a month

push eventlencioni/create-jest-runner

Joe Lencioni

commit sha 107878a5927172d92cc9b65f9cb6ca70a9720ff0

Update repo and homepage in package.json This repo has moved.

view details

push time in a month

fork lencioni/create-jest-runner

A highly opinionated way for creating Jest Runners

fork in a month

issue openedjest-community/jest-runner-eslint

TypeError: Converting circular structure to JSON

I've been looking at our logs in CI and I've noticed the following error pop up a bunch of times:

TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at process.target._send (internal/child_process.js:735:23)
    at process.target.send (internal/child_process.js:634:19)
    at reportError (/path/to/repo/node_modules/jest-runner-eslint/node_modules/jest-worker/build/workers/processChild.js:103:11)
    at reportClientError (/path/to/repo/node_modules/jest-runner-eslint/node_modules/jest-worker/build/workers/processChild.js:87:10)
    at execFunction (/path/to/repo/node_modules/jest-runner-eslint/node_modules/jest-worker/build/workers/processChild.js:157:5)
    at execHelper (/path/to/repo/node_modules/jest-runner-eslint/node_modules/jest-worker/build/workers/processChild.js:139:5)
    at execMethod (/path/to/repo/node_modules/jest-runner-eslint/node_modules/jest-worker/build/workers/processChild.js:143:5)
    at process.on.request (/path/to/repo/node_modules/jest-runner-eslint/node_modules/jest-worker/build/workers/processChild.js:64:7)
    at process.emit (events.js:198:13)

jest-runner-eslint 0.9.0

I believe that nested jest-worker version is 24.9.0.

Based on this stack trace I'm not really sure where this might be coming from or how I might reduce it to a minimal repro case. Any ideas or suggestions of where to start?

created time in a month

created tagairbnb/eslint-plugin-react-with-styles

tagv2.3.0

ESLint plugin for react-with-styles

created time in a month

push eventairbnb/eslint-plugin-react-with-styles

Joe Lencioni

commit sha 7027fc12c0a3aed11ef7ff8e5c9463f3a97a0ddd

Version 2.3.0

view details

push time in a month

push eventairbnb/eslint-plugin-react-with-styles

Joe Lencioni

commit sha 777f7a5aa1ebc55f18c992dc4231441005bcd2d6

Allow eslint v7

view details

push time in a month

delete branch lencioni/axe-core

delete branch : one-time-code

delete time in a month

pull request commentjsx-eslint/eslint-plugin-jsx-a11y

Add failing test for autocomplete with dynamic type

Happy to file a bug upstream, but I'm not sure I understand what you mean by this:

caused by using default values and forgetting that that doesn't handle null

lencioni

comment created time in a month

pull request commentdequelabs/axe-core

Allow autocomplete="one-time-code"

@straker CLA signed, thanks!

lencioni

comment created time in a month

issue commentyannickcr/eslint-plugin-react

TypeError: Cannot read property 'name' of undefined

I am also able to reproduce this with the following file:

function foo({
  test,
}: {
  [key: string]: any;
}) {
  return;
}

It seems to be related to this part: [key: string]: any;

tu4mo

comment created time in 2 months

PR opened jsx-eslint/eslint-plugin-jsx-a11y

Add failing test for autocomplete with dynamic type

This will cause axe to throw an error like:

TypeError: Cannot read property 'replace' of null

I believe that the problem might be related to getLiteralPropValue returning null instead of undefined for dynamic props.

+1 -0

0 comment

1 changed file

pr created time in 2 months

PR opened dequelabs/axe-core

Allow autocomplete="one-time-code"

This autocomplete value can be used by some browsers to automatically fill in the value after receiving a one-time-code for 2-factor authentication. More info:

  • https://github.com/whatwg/html/pull/4573
  • https://developer.apple.com/documentation/security/password_autofill/enabling_password_autofill_on_an_html_input_element
  • https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#Values
  • https://www.twilio.com/blog/html-attributes-two-factor-authentication-autocomplete

<< Describe the changes >>

Closes issue: #2335

Reviewer checks

Required fields, to be filled out by PR reviewer(s)

  • [ ] Follows the commit message policy, appropriate for next version
  • [ ] Code is reviewed for security
+6 -2

0 comment

3 changed files

pr created time in 2 months

create barnchlencioni/axe-core

branch : one-time-code

created branch time in 2 months

fork lencioni/axe-core

Accessibility engine for automated Web UI testing

https://www.deque.com/axe/

fork in 2 months

issue openeddequelabs/axe-core

is-valid-autocomplete should allow one-time-code as a standalone term

<!-- Thanks for reporting an issue to axe-core. Please provide all necessary info to reproduce the issue. Without adequate details, your issue may be closed without investigation.

If you’re reporting a bug, include a description of the issue and a page or code snippet where it can be reproduced. Please make sure you have tested this with the latest version of axe-core. When proposing a new rule, please use our rule template: https://github.com/dequelabs/axe-core/blob/develop/doc/rule-proposal.md

Describe what the desired behavior would be, and how it applies to axe-core's "Accessibility Supported" policy: https://github.com/dequelabs/axe-core/blob/develop/doc/accessibility-supported.md -->

Expectation: <input type="text" autocomplete="one-time-code" /> should be allowed

Actual: It is flagged as invalid

Motivation: This autocomplete value can be used by some browsers to automatically fill in the value after receiving a one-time-code for 2-factor authentication. More info:

  • https://github.com/whatwg/html/pull/4573
  • https://developer.apple.com/documentation/security/password_autofill/enabling_password_autofill_on_an_html_input_element
  • https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#Values
  • https://www.twilio.com/blog/html-attributes-two-factor-authentication-autocomplete

<pre><code> axe-core version: 3.5.5 axe-webdriver, extension or other integration version: eslint-plugin-jsx-a11y@6.3.0

Browser and Assistive Technology versions

For Tooling issues:

  • Node version: 10.16.0 <!-- run node --version -->
  • Platform: Mac <!-- Mac, Linux, Windows --> </code></pre>

created time in 2 months

issue closedKhan/aphrodite

Edit generated styles in dev tools

Is there a way to edit the generated styles in chrome dev tools? Currently they are grayed out, which decreases development time. image

closed time in 2 months

Duskfall

issue commentKhan/aphrodite

Edit generated styles in dev tools

This has been fixed in Chrome 85: https://developers.google.com/web/updates/2020/06/devtools

Duskfall

comment created time in 2 months

issue commentw3c/IntersectionObserver

Changelog?

@szager-chromium it would be helpful to have a changelog for the polyfill npm package, which just published version 0.11.0, that categories the changes by things like breaking change, new feature, bugfix, etc. This would help folks know what to look out for when updating.

matt3224

comment created time in 2 months

delete branch lencioni/jest

delete branch : searchsource-micromatch

delete time in 2 months

pull request commentfacebook/jest

Improve Jest startup time and test runtime, particularly when running with coverage, by caching micromatch and avoiding recreating RegExp instances

In CI we currently spread our tests across 10 separate machines.

When running all tests, the 10 machines on 26.0.1 had runtimes of:

  • 10m 28s
  • 9m 47s
  • 10m 11s
  • 9m 59s
  • 10m 9s
  • 11m 8s
  • 11m 26s
  • 9m 53s
  • 10m 33s
  • 13m 39s

On 26.1.0:

  • 8m 8s
  • 10m 0s
  • 9m 28s
  • 9m 36s
  • 9m 8s
  • 9m 50s
  • 10m 41s
  • 9m 21s
  • 10m 8s
  • 9m 54s

n=1

Not as much as I had wished for, but this is definitely a nice win for us! Thank you for the reviews and the release!

lencioni

comment created time in 2 months

pull request commenthappo/happo.io

Reuse JSDOM instances across targets

After trying this out on our codebase, I'm nervous about merging it. We noticed a number of diffs where state from a different target had spilled over into other targets. For the most part this was okay, but I think it will make Happo more confusing to work with and may make rendering some things not possible. This was mostly problematic for code that read the viewport size and expected it to not change.

lencioni

comment created time in 2 months

push eventhappo/happo.io

Joe Lencioni

commit sha 48cf902c7fae31228c55e6e1f0dfb4de6238a52e

Reuse JSDOM instances across targets I've been investigating a performance problem we ran into at Airbnb the last couple of days. We have some components that end up with very very large dependency graphs, which makes the webpack bundle quite large. Looking at the CI output, it seems to take about 2 min to bundle, which isn't the most terrible thing. But, then I've noticed that the timings for the targets are pretty crazy. Look at these logs: ``` [2020-06-17T19:36:15Z] image_analytics was not bootstrapped [2020-06-17T19:36:37Z] - chrome-medium ✓ (22034.4ms) [2020-06-17T19:38:38Z] No examples found for target chrome-mediumPlus, skipping [2020-06-17T19:38:38Z] - chrome-mediumPlus ✓ (4.0ms) [2020-06-17T19:41:05Z] p3_defer_modals was not bootstrapped ``` Here chrome-medium had examples, so it took snapshots and that took a while which makes sense. mediumPlus didn't have examples, so it took no snapshots. Happo says that mediumPlus took 4ms, but if you look at the timestamps in the log lines, you can see that it actually took 2 minutes. I believe that the time spent on empty targets is in initializing the JSDOM and loading up the webpack bundle. Since we have 6 targets, this adds up to 12 minutes of overhead per job just for loading the bundle, and another 12 if we have to check out previous SHA. This is much too long. I think we can improve performance by reusing the JSDOM instance for all of the targets. In the example above, this should save us about 10 minutes on a run where the previous SHA report exists, and 20 minutes on a run where the previous SHA report does not exist. One potential issue that could arise from this is if there is any side-effecty code in the bundle that looks at the viewport size when it is first executed, that will no longer work quite right since we run the bundle and then resize the window later. In order to preserve backwards compatibility with other DomProvider plugins, like the puppeteer plugin, I left in the width/height in the initialization call, and included a guard around the resize call in case it does not exist yet. We should clean these up in the next breaking change.

view details

push time in 2 months

PR opened happo/happo.io

Reuse JSDOM instances across targets

I've been investigating a performance problem we ran into at Airbnb the last couple of days. We have some components that end up with very very large dependency graphs, which makes the webpack bundle quite large. Looking at the CI output, it seems to take about 2 min to bundle, which isn't the most terrible thing. But, then I've noticed that the timings for the targets are pretty crazy. Look at these logs:

[2020-06-17T19:36:15Z] image_analytics was not bootstrapped
[2020-06-17T19:36:37Z]   - chrome-medium ✓ (22034.4ms)
[2020-06-17T19:38:38Z] No examples found for target chrome-mediumPlus, skipping
[2020-06-17T19:38:38Z]   - chrome-mediumPlus ✓ (4.0ms)
[2020-06-17T19:41:05Z] p3_defer_modals was not bootstrapped

Here chrome-medium had examples, so it took snapshots and that took a while which makes sense. mediumPlus didn't have examples, so it took no snapshots. Happo says that mediumPlus took 4ms, but if you look at the timestamps in the log lines, you can see that it actually took 2 minutes.

I believe that the time spent on empty targets is in initializing the JSDOM and loading up the webpack bundle. Since we have 6 targets, this adds up to 12 minutes of overhead per job just for loading the bundle, and another 12 if we have to check out previous SHA. This is much too long.

I think we can improve performance by reusing the JSDOM instance for all of the targets. In the example above, this should save us about 10 minutes on a run where the previous SHA report exists, and 20 minutes on a run where the previous SHA report does not exist.

One potential issue that could arise from this is if there is any side-effecty code in the bundle that looks at the viewport size when it is first executed, that will no longer work quite right since we run the bundle and then resize the window later.

In order to preserve backwards compatibility with other DomProvider plugins, like the puppeteer plugin, I left in the width/height in the initialization call, and included a guard around the resize call in case it does not exist yet. We should clean these up in the next breaking change.

+53 -16

0 comment

4 changed files

pr created time in 2 months

create barnchhappo/happo.io

branch : jdl-reuse-jsdom

created branch time in 2 months

pull request commentbabel/preset-modules

Handle cases where a binding is not defined in a scope

I saw the note about preset-env that was added by https://github.com/babel/preset-modules/pull/17 and decided to try switching over from preset-modules to preset-env:

-          "@babel/preset-modules",
+          "@babel/preset-env",
           {
-            "loose": true
+            "loose": true,
+
+            // https://babeljs.io/docs/en/babel-preset-env#modules
+            "modules": false,
+
+            // https://babeljs.io/docs/en/babel-preset-env#bugfixes
+            "bugfixes": true,
+
+            "targets": {
+              "esmodules": true
+            },
+
+            "exclude": [
+              "transform-async-to-generator",
+              "transform-regenerator"
+            ]

Unfortunately, I ran into the error that this fixes. So I'm wondering if you would have time to publish a new version soon?

Also, since this is the only change I'm making, I'm actually a little surprised that it would trigger this error. Using preset-env 7.9.6 at the moment, so maybe something has improved in 7.10? If not, it seems that maybe there are some unaccounted differences between preset-env with esmodules targets and preset-modules that might be worth auditing. (Or maybe I botched the config in some way)

LarsDenBakker

comment created time in 2 months

Pull request review commentyannickcr/eslint-plugin-react

Cache detected React version

 function resetWarningFlag() {   warnedForMissingVersion = false; } +let cachedDetectedReactVersion; function detectReactVersion() {+  if (cachedDetectedReactVersion) {+    return cachedDetectedReactVersion;+  }+   try {     const reactPath = resolve.sync('react', {basedir: process.cwd()});     const react = require(reactPath); // eslint-disable-line global-require, import/no-dynamic-require-    return react.version;+    cachedDetectedReactVersion = react.version;

Done, I also fixed the tests I think

lencioni

comment created time in 2 months

push eventyannickcr/eslint-plugin-react

Joe Lencioni

commit sha b8e91a571bc6b58cc3c78e9e62e8b60ecb45e233

Cache detected React version I've been timing and profiling ESLint runs at Airbnb and noticed that react/no-unknown-property is particularly slow for us when using the "detect" setting for React version. When running ESLint using TIMING=1 on a directory that contains about 500 files to be linted in it, react/no-unknown-property shows up as taking about 1700ms. Looking at the callstacks in the profiler, it seems that when this rule calls getStandardName for every JSXAttribute here, it will actually do all of the work to detect the React version every time to determine the correct set of DOM property names. Since there may be a lot of JSXAttribute nodes in a codebase, this adds up to quite a bit of work. By specifying the react version in our ESLint config, the no-unkown-property rule drops out of the top 10 slowest rules entirely, with the 10th slowest clocking in at 180ms. I think it would be a good idea to cache the React version when using detect instead of looking it up every time.

view details

push time in 2 months

push eventyannickcr/eslint-plugin-react

Joe Lencioni

commit sha b3f7a85dd9f858ffe50bef290b4e8fffb3cc9676

Cache detected React version I've been timing and profiling ESLint runs at Airbnb and noticed that react/no-unknown-property is particularly slow for us when using the "detect" setting for React version. When running ESLint using TIMING=1 on a directory that contains about 500 files to be linted in it, react/no-unknown-property shows up as taking about 1700ms. Looking at the callstacks in the profiler, it seems that when this rule calls getStandardName for every JSXAttribute here, it will actually do all of the work to detect the React version every time to determine the correct set of DOM property names. Since there may be a lot of JSXAttribute nodes in a codebase, this adds up to quite a bit of work. By specifying the react version in our ESLint config, the no-unkown-property rule drops out of the top 10 slowest rules entirely, with the 10th slowest clocking in at 180ms. I think it would be a good idea to cache the React version when using detect instead of looking it up every time.

view details

push time in 2 months

PR opened yannickcr/eslint-plugin-react

Cache detected React version

I've been timing and profiling ESLint runs at Airbnb and noticed that react/no-unknown-property is particularly slow for us when using the "detect" setting for React version.

When running ESLint using TIMING=1 on a directory that contains about 500 files to be linted in it, react/no-unknown-property shows up as taking about 1700ms.

Looking at the callstacks in the profiler, it seems that when this rule calls getStandardName for every JSXAttribute here, it will actually do all of the work to detect the React version every time to determine the correct set of DOM property names. Since there may be a lot of JSXAttribute nodes in a codebase, this adds up to quite a bit of work.

By specifying the react version in our ESLint config, the no-unkown-property rule drops out of the top 10 slowest rules entirely, with the 10th slowest clocking in at 180ms.

I think it would be a good idea to cache the React version when using detect instead of looking it up every time.

Fixes #2671

+7 -1

0 comment

1 changed file

pr created time in 2 months

create barnchyannickcr/eslint-plugin-react

branch : cache-react-version

created branch time in 2 months

delete branch lencioni/eslint-plugin-prettier

delete branch : clear-cache

delete time in 2 months

pull request commentprettier/eslint-plugin-prettier

Avoid clearing Prettier cache when not using prettierrc

Our of interest what's the speedup for just the prettier rule on your codebase?

Thanks for the quick publish on this! I've updated our plugin and early results look like it saves us 1-2 minutes in CI, which is somewhere around 10-15% of the total job runtime.

This is now the TIMING=1 output for one of our Jest workers:

[2020-06-15T14:55:38Z] Rule                                     |  Time (ms) | Relative
[2020-06-15T14:55:38Z] :----------------------------------------|-----------:|--------:
[2020-06-15T14:55:38Z] import/no-named-as-default               | 112620.047 |    27.2%
[2020-06-15T14:55:38Z] prettier/prettier                        |  82839.768 |    20.0%
[2020-06-15T14:55:38Z] import/no-self-import                    |  23323.196 |     5.6%
[2020-06-15T14:55:38Z] import/default                           |  20537.711 |     5.0%
[2020-06-15T14:55:38Z] import/no-extraneous-dependencies        |  16908.916 |     4.1%
[2020-06-15T14:55:38Z] rulesdir/no-hyperloop-restricted-imports |  10973.224 |     2.7%
[2020-06-15T14:55:38Z] import/named                             |  10957.346 |     2.6%
[2020-06-15T14:55:38Z] react/void-dom-elements-no-children      |   7367.993 |     1.8%
[2020-06-15T14:55:38Z] react/no-unknown-property                |   6615.837 |     1.6%
[2020-06-15T14:55:38Z] react/destructuring-assignment           |   6272.271 |     1.5%
lencioni

comment created time in 2 months

startedlydiahallie/javascript-questions

started time in 2 months

issue commentyannickcr/eslint-plugin-react

React version "detect" is slow, particularly for no-unknown-property

In the meantime, I'm going to use this bit of config:

  settings: {
    react: {
      // "detect" is slow
      // https://github.com/yannickcr/eslint-plugin-react/issues/2671
      // eslint-disable-next-line global-require
      version: require('react').version,
    },
  },
lencioni

comment created time in 2 months

issue openedyannickcr/eslint-plugin-react

React version "detect" is slow, particularly for no-unknown-property

I've been timing and profiling ESLint runs at Airbnb and noticed that react/no-unknown-property is particularly slow for us when using the "detect" setting for React version.

When running ESLint using TIMING=1 on a directory that contains about 500 files to be linted in it, react/no-unknown-property shows up as taking about 1700ms.

Looking at the callstacks in the profiler, it seems that when this rule calls getStandardName for every JSXAttribute here, it will actually do all of the work to detect the React version every time to determine the correct set of DOM property names.

https://github.com/yannickcr/eslint-plugin-react/blob/ef9a51225e3d5f6cb7cbdc3ec0382ad49246034b/lib/rules/no-unknown-property.js#L275

image

By specifying the react version in our ESLint config, the no-unkown-property rule drops out of the top 10 slowest rules entirely, with the 10th slowest clocking in at 180ms.

I think it would be a good idea to cache the React version when using detect instead of looking it up every time here: https://github.com/yannickcr/eslint-plugin-react/blob/ef9a51225e3d5f6cb7cbdc3ec0382ad49246034b/lib/util/version.js#L17-L33

Would you be open to a PR that did this?

created time in 2 months

pull request commentprettier/eslint-plugin-prettier

Avoid clearing Prettier cache when not using prettierrc

Our of interest what's the speedup for just the prettier rule on your codebase?

ESLint takes too long to run locally on our entire codebase right now. In CI, we use jest-runner-eslint to speed things up a lot. We also have a large monorepo and do some things to only run ESLint on parts of the monorepo that might be affected by any given change. With all of this in place, and running on some pretty beefy boxes, we see max run times around 14 minutes lately. I'd be happy to report back with new numbers after this change is published, but I'm expecting that this will drop that time considerably.

lencioni

comment created time in 2 months

issue openedbabel/babel-eslint

Feature idea: have a way for eslint-plugin-prettier to share an AST with eslint

I'm not sure if this is the best place to open this issue, given the migration to the babel monorepo. Please let me know if you'd like me to post this somewhere else.

Adding eslint-plugin-prettier to your ESLint config currently adds a lot of overhead to ESLint runs. On larger codebases, this can be a considerable performance hit.

One of the main costs here comes from the fact that both ESLint and Prettier need to parse each file to an AST separately. I think we could see a performance improvement by providing a way for the AST to be shared between these two programs.

Thankfully, both ESLint and Prettier allow for a custom parser to be used.

  • ESLint: https://eslint.org/docs/user-guide/configuring#specifying-parser
  • Prettier: https://prettier.io/docs/en/options.html#parser, https://prettier.io/docs/en/api.html#custom-parser-api

babel-eslint uses babel to parse the code to an AST, and then runs some functions to mutate that AST to make it look right for ESLint. That code is here: https://github.com/babel/babel-eslint/blob/187e69aa8942039a5ae91cb9ac3a7998417e935e/lib/parse.js#L57-L72 Because of this mutation, it seems like we might not be able to pass it directly to Prettier without it erroring.

So, I think that if we could make it so the original parsed AST is cached for a short amount of time (maybe WeakMap or a simple LRU cache so we are kind to memory usage), and provide a babel-eslint/prettier entrypoint that can be used by Prettier that pulls from this cached original Babel AST, we could avoid the double parsing.

I think the main downside with this is that it would require us to copy the AST instead of mutating it directly, which would come with its own performance cost in both CPU and memory usage.

One alternative might be to see if we can teach Prettier to handle the babel-eslint mutated AST, and then simply add some caching to the parser here. I'm not very familiar with Prettier's internals, so I'm not sure how much effort that would be or whether it would be possible with the babel-eslint mutated AST, but if it is possible that seems like it would be a good option worth considering. It looks like typescript-estree is able to support both ESLint and Prettier, so maybe this isn't too wild of an idea? https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/typescript-estree

cc @BPScott

created time in 2 months

pull request commentprettier/eslint-plugin-prettier

Avoid clearing Prettier cache when not using prettierrc

Even if the vscode plugin does this, there area bunch of others that would also need to have this special case, like sublime, atom, and eslint_d.

One option would be to add an async thing that clears the cache later, but I suspect that won't be ideal now that eslint has gone async. I think this would be ideal if node had requestIdleCallback (https://github.com/nodejs/node/issues/2543), but we could probably mimic something pretty decent without too much overhead using recursive setTimeouts.

I think ideally eslint would have an API for rules to do some cleanup work after all the rules finished. Obviously, that won't be backwards compatible though.

In any case, my preference would be to get this change published as is ASAP, since it is a strict improvement, and then follow up with deeper changes. Then we can decide if we want to break people's workflows or try to make it just work.

I'd be happy to submit a separate PR that does the setTimeouts shenanigans if you like that idea.

lencioni

comment created time in 2 months

Pull request review commentprettier/eslint-plugin-prettier

Fix: Support prettier v1.6.0 config (#46)

 module.exports = {           }         } +        if (prettier) {+          prettier.clearConfigCache();

This makes ESLint a lot slower. I have a partial fix here, but it would be good to figure out a better way to do this: https://github.com/prettier/eslint-plugin-prettier/pull/303

kombucha

comment created time in 2 months

PR opened prettier/eslint-plugin-prettier

Avoid clearing Prettier cache when not using prettierrc

At Airbnb we've noticed that the Prettier ESLint rule is extraordinarily slow. When running ESLint with TIMING=1, Prettier is two orders of magnitude slower than our other slowest rules (which come from eslint-plugin-import mostly).

I spent some time investigating this today. I ran the Chrome DevTools profiler while running ESLint on a directory with 480 files in it. Looking at the flame charts, I noticed that this plugin ended up calling Prettier's pluginSearchDirs.map.pluginSearchDir for every file that was being linted, even though it was being memoized. Through some logging, I determined that the Prettier cache was being cleared between every file, and narrowed it down to this line, which was added here:

https://github.com/prettier/eslint-plugin-prettier/pull/55#discussion_r139307523

It looks like this cache busting was added to make it so long-running ESLint processes (e.g. for vscode-eslint) would be able to pick up changes to prettierrc files without having to reload the process. Thankfully, we don't use a prettierrc file at Airbnb right now, in favor of putting our Prettier config inline with our ESLint config. So the quick performance fix for us is to simply skip the cache busting when this option is not enabled.

In my profiling, this reduces the time spent in ESLint's verifyAndFix when running on the same 480 files from 34 seconds to 26 seconds, for a total savings of 8 seconds.

For folks who are using prettierrc files, this is still pretty crappy, so it would be great to find a better way to do this. Unfortunately my knowledge of the inner workings of vscode-eslint and ESLint are not enough to know if there might be a better way to do this--e.g. maybe there's some ESLint option that we can respect here?

+6 -1

0 comment

1 changed file

pr created time in 2 months

create barnchlencioni/eslint-plugin-prettier

branch : clear-cache

created branch time in 2 months

fork lencioni/eslint-plugin-prettier

ESLint plugin for Prettier formatting

fork in 2 months

Pull request review commentfacebook/jest

Watchman crawler now includes dotfiles

 class HasteMap extends EventEmitter {       watch: !!options.watch,     };     this._console = options.console || global.console;-    if (options.ignorePattern && !(options.ignorePattern instanceof RegExp)) {-      this._console.warn(-        'jest-haste-map: the `ignorePattern` options as a function is being ' +-          'deprecated. Provide a RegExp instead. See https://github.com/facebook/jest/pull/4063.',-      );++    if (options.ignorePattern) {+      if (options.ignorePattern instanceof RegExp) {+        this._options.ignorePattern = new RegExp(+          options.ignorePattern.source.concat('|' + VCS_DIRECTORIES),+        );+      } else {+        const ignorePattern = options.ignorePattern;+        this._options.ignorePattern = (filePath: string) =>+          new RegExp(VCS_DIRECTORIES).test(filePath) || ignorePattern(filePath);

Probably would be a good idea to instantiate this RegExp outside the function, for better performance.

grosto

comment created time in 2 months

delete branch lencioni/jest

delete branch : patch-1

delete time in 2 months

PR opened facebook/jest

Remove Flow from vscode recommended extensions

Jest has migrated to TypeScript, so this extension is probably not very useful in this repo anymore.

https://github.com/facebook/jest/issues/7807

<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. The two fields below are mandatory. -->

<!-- Please remember to update CHANGELOG.md in the root of the project if you have not done so. -->

Summary

<!-- Explain the motivation for making this change. What existing problem does the pull request solve? -->

Test plan

<!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI. -->

+0 -1

0 comment

1 changed file

pr created time in 2 months

push eventlencioni/jest

Joe Lencioni

commit sha f8ad1f43c8ffca29059cb8114b19e0a0dde666e5

Remove Flow from vscode recommended extensions Jest has migrated to TypeScript, so this extension is probably not very useful in this repo anymore. https://github.com/facebook/jest/issues/7807

view details

push time in 2 months

push eventlencioni/jest

Joe Lencioni

commit sha 42ab2e9dcb52d96cbfa13f6ceabc8a75fb0a33da

Add code comments to globsToMatcher The logic here might be a little confusing, so I am adding some comments that I hope will help make it easier for future explorers to understand. While I was doing this, I noticed a small way to simplify this function even more.

view details

push time in 2 months

Pull request review commentfacebook/jest

Improve Jest startup time and test runtime, particularly when running with coverage, by caching micromatch and avoiding recreating RegExp instances

+/**+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.+ *+ * This source code is licensed under the MIT license found in the+ * LICENSE file in the root directory of this source tree.+ */++import micromatch = require('micromatch');+import type {Config} from '@jest/types';+import replacePathSepForGlob from './replacePathSepForGlob';++const globsMatchers = new Map<+  string,+  {+    isMatch: (str: string) => boolean;+    negated: boolean;+  }+>();++// Every time micromatch is called, it will parse the glob strings and turn them

One of the windows builds was flaking and there's no way to re-run, so I decided to add some code comments to this file.

lencioni

comment created time in 2 months

Pull request review commentfacebook/jest

Improve Jest startup time and test runtime, particularly when running with coverage, by caching micromatch and avoiding recreating RegExp instances

+/**+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.+ *+ * This source code is licensed under the MIT license found in the+ * LICENSE file in the root directory of this source tree.+ */++import micromatch = require('micromatch');+import type {Config} from '@jest/types';+import replacePathSepForGlob from './replacePathSepForGlob';++const globsMatchers = new Map<+  string,+  {+    isMatch: (str: string) => boolean;+    negated: boolean;+  }+>();++export default function globsToMatcher(+  globs: Array<Config.Glob>,+): (path: Config.Path) => boolean {+  if (globs.length === 0) {+    return (_: Config.Path): boolean => false;

FWIW the breaking changes seem to be pretty okay for this repo: https://github.com/typescript-eslint/typescript-eslint/releases/tag/v3.0.0

lencioni

comment created time in 2 months

Pull request review commentfacebook/jest

Improve Jest startup time and test runtime, particularly when running with coverage, by caching micromatch and avoiding recreating RegExp instances

+/**+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.+ *+ * This source code is licensed under the MIT license found in the+ * LICENSE file in the root directory of this source tree.+ */++import micromatch = require('micromatch');+import type {Config} from '@jest/types';+import replacePathSepForGlob from './replacePathSepForGlob';++const globsMatchers = new Map<+  string,+  {+    isMatch: (str: string) => boolean;+    negated: boolean;+  }+>();++export default function globsToMatcher(+  globs: Array<Config.Glob>,+): (path: Config.Path) => boolean {+  if (globs.length === 0) {+    return (_: Config.Path): boolean => false;

Yeah, seems promising. It looks like Jest is still on v2.30 though, so I think I'd like to say that updating the eslint plugin is out of scope for this PR if that's alright with you.

lencioni

comment created time in 2 months

push eventlencioni/jest

Joe Lencioni

commit sha f588adaf179535b9c2ab45a56e7dc17dcd821ab6

Add code comments to globsToMatcher The logic here might be a little confusing, so I am adding some comments that I hope will help make it easier for future explorers to understand. While I was doing this, I noticed a small way to simplify this function even more.

view details

push time in 2 months

Pull request review commentfacebook/jest

Improve Jest startup time and test runtime, particularly when running with coverage, by caching micromatch and avoiding recreating RegExp instances

 export default function shouldInstrument(     // still cover if `only` is specified     !options.collectCoverageOnlyFrom &&     options.collectCoverageFrom.length &&-    micromatch(-      [replacePathSepForGlob(path.relative(config.rootDir, filename))],-      options.collectCoverageFrom,-    ).length === 0+    !globsToMatcher(options.collectCoverageFrom)(

I just noticed that this will end up using the dot: true option where before that wasn't used here (and above in this file). This seems like it should be fine, but I don't really have enough context here to know for sure.

lencioni

comment created time in 2 months

push eventlencioni/jest

Joe Lencioni

commit sha 793c8c60b5ac4c1f30aaaff5136fd1d7b9cca2fb

Optimize micromatch and RegExps in shouldInstrument I've been profiling running Jest with code coverage at Airbnb, and noticed that shouldInstrument is called often and is fairly expensive. It also seems to call micromatch and `new RegExp` repeatedly, both of which can be optimized by caching the work to convert globs and strings into matchers and regexes. I profiled this change by running a set of 27 fairly simple tests. Before this change, about 6-7 seconds was spent in shouldInstrument. After this change, only 400-500 ms is spent there. I would expect this delta to increase along with the number of tests and size of their dependency graphs.

view details

Joe Lencioni

commit sha f51fd3475aefc40c230219c82925d42c404cfc77

Reduce micromatch overhead in jest-haste-map HasteFS I was profiling some Jest runs at Airbnb and noticed that on my MacBook Pro, we can spend over 30 seconds after running Jest with code coverage as the coverage reporter adds all of the untested files. I believe that this will grow as the size of the codebase increases. Looking at the call stacks, it appears to be calling micromatch repeatedly, which calls picomatch, which builds a regex out of the globs. It seems that the parsing and regex building also triggers the garbage collector frequently. Since this is in a tight loop and the globs won't change between checks, we can greatly improve the performance here by using our new and optimized globsToMatcher function, which avoids re-parsing globs unnecessarily. This optimization reduces the block of time here from about 30s to about 10s. The aggregated total time of coverage reporter's onRunComplete goes from 23s to 600ms.

view details

push time in 2 months

push eventlencioni/jest

Joe Lencioni

commit sha e39266dc6ccd75616a9fe20b3ab27f2cf3b26650

Move globsToMatcher from jest-core to jest-util I'd like to start using this in more places to improve performance. Moving it to jest-util seems like a better spot. Now that it is a standalone module, I decided to write some unit tests for this function. In doing so, I uncovered a small difference between the behavior of this function and micromatch when overlapping glob patterns are used which I also fixed.

view details

Joe Lencioni

commit sha 9c01c204aae8d3841cdc13159995bd9342874ca4

Teach globsToMatcher to work with empty globs While incorporating this function into more places, I discovered a discrepancy here with how micromatch works. We can fix this by creating a fast path for when there are no globs at all.

view details

Joe Lencioni

commit sha 94590ae7b82861177349291c15aebacfa0470a52

Optimize micromatch and RegExps in shouldInstrument I've been profiling running Jest with code coverage at Airbnb, and noticed that shouldInstrument is called often and is fairly expensive. It also seems to call micromatch and `new RegExp` repeatedly, both of which can be optimized by caching the work to convert globs and strings into matchers and regexes. I profiled this change by running a set of 27 fairly simple tests. Before this change, about 6-7 seconds was spent in shouldInstrument. After this change, only 400-500 ms is spent there. I would expect this delta to increase along with the number of tests and size of their dependency graphs.

view details

Joe Lencioni

commit sha f3e1f027728801a3e8165cac0776d9244cdc26a9

Reduce micromatch overhead in jest-haste-map HasteFS I was profiling some Jest runs at Airbnb and noticed that on my MacBook Pro, we can spend over 30 seconds after running Jest with code coverage as the coverage reporter adds all of the untested files. I believe that this will grow as the size of the codebase increases. Looking at the call stacks, it appears to be calling micromatch repeatedly, which calls picomatch, which builds a regex out of the globs. It seems that the parsing and regex building also triggers the garbage collector frequently. Since this is in a tight loop and the globs won't change between checks, we can greatly improve the performance here by using our new and optimized globsToMatcher function, which avoids re-parsing globs unnecessarily. This optimization reduces the block of time here from about 30s to about 10s. The aggregated total time of coverage reporter's onRunComplete goes from 23s to 600ms.

view details

push time in 2 months

Pull request review commentfacebook/jest

Improve Jest startup time and test runtime, particularly when running with coverage, by caching micromatch and avoiding recreating RegExp instances

+/**+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.+ *+ * This source code is licensed under the MIT license found in the+ * LICENSE file in the root directory of this source tree.+ */++import micromatch = require('micromatch');+import type {Config} from '@jest/types';+import replacePathSepForGlob from './replacePathSepForGlob';++const globsMatchers = new Map<+  string,+  {+    isMatch: (str: string) => boolean;+    negated: boolean;+  }+>();++export default function globsToMatcher(+  globs: Array<Config.Glob>,+): (path: Config.Path) => boolean {+  if (globs.length === 0) {+    return (_: Config.Path): boolean => false;

I didn't expect them to be needed, but vscode showed me an eslint error when I didn't have them:

Missing return type on function. eslint@typescript-eslint/explicit-module-boundary-types

lencioni

comment created time in 2 months

Pull request review commentfacebook/jest

Improve Jest startup time and test runtime, particularly when running with coverage, by caching micromatch and avoiding recreating RegExp instances

 describe('SearchSource', () => {       });     }); +    it('finds tests matching a JS with overriding glob patterns', () => {+      const {options: config} = normalize(+        {+          moduleFileExtensions: ['js', 'jsx'],+          name,+          rootDir,+          testMatch: [+            '**/*.js?(x)',+            '!**/test.js?(x)',+            '**/test.js',+            '!**/test.js',+          ],+          testRegex: '',+        },+        {} as Config.Argv,+      );++      return findMatchingTests(config).then(data => {

Yep, mostly copypasta here

lencioni

comment created time in 2 months

pull request commentfacebook/jest

Improve Jest startup time and test runtime, particularly when running with coverage, by caching micromatch and avoiding recreating RegExp instances

Alright friends, I think I'm done hacking on this now. Please let me know if you'd like me to make any changes. I'm really looking forward to seeing how this performs for us in CI!

lencioni

comment created time in 2 months

more