Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add rules for hybrid Node.js and browser environments #242

Merged
merged 7 commits into from Nov 15, 2022

Conversation

Mrtenz
Copy link
Member

@Mrtenz Mrtenz commented Oct 14, 2022

This adds a new package for hybrid Node.js and browser envrionments. It prevents the use of any Node.js or browser-specific globals.

Because we make use of Node.js and browser APIs in many modules right now, adding this to an existing package would cause a lot of breaking changes. That's why I created a new package instead. It includes a script to update the rules automatically.

Using the following file as example:

import { createHash } from 'crypto';
import { join } from 'path';

export const doThing = () => {
  const value = Buffer.from('foo bar');
  createHash('sha256').update(value).digest('hex');
  join('foo');
};

Results in these errors:

  1:1   error  'crypto' import is restricted from being used. Use 'ethereum-cryptography' instead        no-restricted-imports
  2:1   error  'path' import is restricted from being used. This module is not available in the browser  no-restricted-imports
  5:17  error  Unexpected use of 'Buffer'. Use 'Uint8Array' instead                                      no-restricted-globals

To do

  • Disable rules in test files?
  • Test in production to ensure it works as expected.

@Mrtenz
Copy link
Member Author

Mrtenz commented Oct 15, 2022

I'm not sure what the best way would be to handle test files. For testing in production, I simply added this package to the *.ts override, which would also apply it to test files. We could set it up in the module template to turn off those rules for *.test.ts maybe.

@Mrtenz Mrtenz marked this pull request as ready for review October 15, 2022 07:48
@Mrtenz Mrtenz requested a review from a team as a code owner October 15, 2022 07:48
@Gudahtt
Copy link
Member

Gudahtt commented Oct 15, 2022

Could we add this to the base package instead? That package is already meant to prevent the use of anything Node.js or browser-specific.

I'm still confused as to why Node.js specific globals aren't already disallowed though 🤔 The base package uses no-undef, and doesn't use an environment that includes globals like Buffer.

@Mrtenz
Copy link
Member Author

Mrtenz commented Oct 16, 2022

Could we add this to the base package instead? That package is already meant to prevent the use of anything Node.js or browser-specific.

I'm afraid that it will cause many breaking changes in projects, preventing them from upgrading to the latest config. Fixing these errors is not as simple as changing one line of code, some possibly requiring a larger refactor (like swapping out Buffer for Uint8Array and crypto with a browser-friendly version).

It might be better to have it as a new package, wait until most of our modules have implemented it, and then merge it with the base rules.

I'm still confused as to why Node.js specific globals aren't already disallowed though 🤔 The base package uses no-undef, and doesn't use an environment that includes globals like Buffer.

It seems to be overridden somewhere. Explicitly adding /* eslint no-undef: "error" */ to a file does cause it to error when using Buffer. no-undef doesn't solve the problem for Node.js built-in modules though.

@Gudahtt
Copy link
Member

Gudahtt commented Oct 23, 2022

I think this is the culprit: https://github.com/typescript-eslint/typescript-eslint/blob/efc147b04dce52ab17415b6a4ae4076b944b9036/packages/eslint-plugin/src/configs/eslint-recommended.ts

It's disabled because TypeScript is already checking for undefined types. But TypeScript isn't seeing it as undefined because we have @types/node installed (presumably so that we can use Node.js APIs in tests?). Not sure what the best way to solve this would be - either explicitly re-add no-undef in our TypeScript ESLint config, or ask TypeScript to not include @types/node when checking the production files by default.

@Gudahtt
Copy link
Member

Gudahtt commented Oct 23, 2022

I'm afraid that it will cause many breaking changes in projects, preventing them from upgrading to the latest config. Fixing these errors is not as simple as changing one line of code, some possibly requiring a larger refactor (like swapping out Buffer for Uint8Array and crypto with a browser-friendly version).

In the past, we've handled this by disabling disruptive rules in the project ESLint config to make the update easier. Then we can re-enable any rules one-by-one to fix lint errors. We're made many disruptive lint changes recently, and many more are planned (e.g. enabling the ESLint TypeScript rules that require type information); making a new package each time would be confusing.

@Gudahtt
Copy link
Member

Gudahtt commented Nov 14, 2022

Not sure what the best way to solve this would be - either explicitly re-add no-undef in our TypeScript ESLint config, or ask TypeScript to not include @types/node when checking the production files by default.

I looked into this, and couldn't find a reasonable way of excluding @types/node from tsconfig.build.json specifically, while including it in tsconfig.json.

So I guess we should explicitly add no-undef to our TypeScript ESLint config.

@Mrtenz Mrtenz force-pushed the mrtenz/hybrid-browser-config branch from 1e55041 to c97444a Compare November 14, 2022 20:10
@Mrtenz Mrtenz changed the title Add package for hybrid Node.js and browser environments Add rules for hybrid Node.js and browser environments Nov 14, 2022
@Mrtenz Mrtenz merged commit e2f8302 into main Nov 15, 2022
@Mrtenz Mrtenz deleted the mrtenz/hybrid-browser-config branch November 15, 2022 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants