diff --git a/CHANGELOG.md b/CHANGELOG.md index 137bbede23e3..63f4adac3510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +v8.33.0 - January 28, 2023 + +* [`17f4be2`](https://github.com/eslint/eslint/commit/17f4be2b66deb81f4e9ffb3d6bdfb79f3fcf85a2) docs: Fix examples in no-multiple-empty-lines rule (#16835) (jonz94) +* [`9c7cfe3`](https://github.com/eslint/eslint/commit/9c7cfe33c4a39cf2c23529afe02030ea7f8acf70) docs: 'Source Code' content in 'Set up Development Environment' page (#16780) (Ben Perlmutter) +* [`ede5c64`](https://github.com/eslint/eslint/commit/ede5c6475469a905da4f559ab55f0ee73168a9d7) docs: Custom processors page (#16802) (Ben Perlmutter) +* [`2620614`](https://github.com/eslint/eslint/commit/2620614f525de13f2e3ab0a7cd92abe89dae4897) docs: Code of Conduct page (#16781) (Ben Perlmutter) +* [`50a8efd`](https://github.com/eslint/eslint/commit/50a8efd957c70c9978a8ed25744a24193b00e078) docs: report a sec vulnerability page (#16808) (Ben Perlmutter) +* [`2cc7954`](https://github.com/eslint/eslint/commit/2cc7954cdb1fed44e8a5d3c9b3ea1deceadb5e00) feat: add `restrictDefaultExports` option to no-restricted-exports rule (#16785) (Nitin Kumar) +* [`ed60afd`](https://github.com/eslint/eslint/commit/ed60afd4450e769a975447178299446f4439d926) docs: Update page titles, section landing pages, and side TOC (#16760) (Ben Perlmutter) +* [`333c712`](https://github.com/eslint/eslint/commit/333c71243537966930e9ab8178bc98c37949b5f2) docs: add background to code-path-diagrams for dark-mode (#16822) (Tanuj Kanti) +* [`f5f7b9b`](https://github.com/eslint/eslint/commit/f5f7b9b8b512f5c6a5b4a1037f81bb3f5a7311e0) docs: Update README (GitHub Actions Bot) +* [`2aa4f5f`](https://github.com/eslint/eslint/commit/2aa4f5fb2fdb1c4a1734093c225e5c6251b0ee0f) docs: no-constant-condition: Add multi-comparison example (#16776) (Sebastian Simon) +* [`40287db`](https://github.com/eslint/eslint/commit/40287dbe7407934a69805f02ece07491778c3694) docs: Remove Google Group icon (#16779) (Nicholas C. Zakas) +* [`ea10ca5`](https://github.com/eslint/eslint/commit/ea10ca5b7b5bd8f6e6daf030ece9a3a82f10994c) docs: 'a .eslint' -> 'an .eslint' for consistency (#16809) (Ben Perlmutter) +* [`3be0748`](https://github.com/eslint/eslint/commit/3be07488ee7b6a9591d169be9648fbd36b32105e) docs: add example for nodejs lintText api (#16789) (Siva K) +* [`ce4f5ff`](https://github.com/eslint/eslint/commit/ce4f5ff30590df053a539c8e8e2597838e038a36) docs: Replace removed related rules with a valid rule (#16800) (Ville Saalo) + v8.32.0 - January 14, 2023 * [`17b65ad`](https://github.com/eslint/eslint/commit/17b65ad10d653bb05077f21d8b1f79bee96e38d8) docs: IA Update page URL move (#16665) (Ben Perlmutter) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 07597a76ed69..c3c3a2a2e025 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,9 +10,9 @@ This project adheres to the [Open JS Foundation Code of Conduct](https://eslint. Before filing an issue, please be sure to read the guidelines for what you're reporting: -* [Bug Report](https://eslint.org/docs/latest/contribute/report-bugs) +* [Report Bugs](https://eslint.org/docs/latest/contribute/report-bugs) * [Propose a New Rule](https://eslint.org/docs/latest/contribute/propose-new-rule) -* [Proposing a Rule Change](https://eslint.org/docs/latest/contribute/propose-rule-change) +* [Propose a Rule Change](https://eslint.org/docs/latest/contribute/propose-rule-change) * [Request a Change](https://eslint.org/docs/latest/contribute/request-change) To report a security vulnerability in ESLint, please use our [HackerOne program](https://hackerone.com/eslint). diff --git a/README.md b/README.md index 95f4bfe56e6a..ca0cb10024e8 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,10 @@ # ESLint [Website](https://eslint.org) | -[Configuring](https://eslint.org/docs/latest/use/configure) | +[Configure ESLint](https://eslint.org/docs/latest/use/configure) | [Rules](https://eslint.org/docs/rules/) | -[Contributing](https://eslint.org/docs/latest/contribute) | -[Reporting Bugs](https://eslint.org/docs/latest/contribute/report-bugs) | +[Contribute to ESLint](https://eslint.org/docs/latest/contribute) | +[Report Bugs](https://eslint.org/docs/latest/contribute/report-bugs) | [Code of Conduct](https://eslint.org/conduct) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint) | @@ -59,7 +59,7 @@ After that, you can run ESLint on any file or directory like this: ## Configuration -After running `npm init @eslint/config`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this: +After running `npm init @eslint/config`, you'll have an `.eslintrc` file in your directory. In it, you'll see some rules configured like this: ```json { @@ -294,7 +294,7 @@ The following companies, organizations, and individuals support ESLint's ongoing

Chrome Frameworks Fund Automattic

Gold Sponsors

RIDI Salesforce Airbnb

Silver Sponsors

Sentry Liftoff

Bronze Sponsors

-

ThemeIsle Nx (by Nrwl) Anagram Solver Icons8: free icons, photos, illustrations, and music Discord Ignition HeroCoders QuickBooks Tool hub

+

ThemeIsle Nx (by Nrwl) Anagram Solver Icons8: free icons, photos, illustrations, and music Discord Transloadit Ignition HeroCoders QuickBooks Tool hub

## Technology Sponsors diff --git a/docs/.eleventy.js b/docs/.eleventy.js index 01801d389e34..eee65d759621 100644 --- a/docs/.eleventy.js +++ b/docs/.eleventy.js @@ -195,6 +195,7 @@ module.exports = function(eleventyConfig) { .use(markdownItAnchor, { slugify }) + .use(markdownItContainer, "img-container", {}) .use(markdownItContainer, "correct", {}) .use(markdownItContainer, "incorrect", {}) .use(markdownItContainer, "warning", { diff --git a/docs/package.json b/docs/package.json index c0fbd783eebc..7447e1d5c63f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,7 +1,7 @@ { "name": "docs-eslint", "private": true, - "version": "8.32.0", + "version": "8.33.0", "description": "", "main": "index.js", "keywords": [], diff --git a/docs/src/_includes/components/social-icons.html b/docs/src/_includes/components/social-icons.html index 1278f5d0f9dd..bb025af5b134 100644 --- a/docs/src/_includes/components/social-icons.html +++ b/docs/src/_includes/components/social-icons.html @@ -11,16 +11,6 @@ -
  • - - - - - -
  • dependency graph +:::img-container +dependency graph +::: At a high level, there are a few key parts to ESLint: diff --git a/docs/src/contribute/code-of-conduct.md b/docs/src/contribute/code-of-conduct.md new file mode 100644 index 000000000000..3d82299c7e77 --- /dev/null +++ b/docs/src/contribute/code-of-conduct.md @@ -0,0 +1,10 @@ +--- +title: Code of Conduct +eleventyNavigation: + key: code of conduct + parent: contribute to eslint + title: Code of Conduct + order: 0 +--- + +ESLint welcomes contributions from everyone and adheres to the [OpenJS Foundation Code of Conduct](https://eslint.org/conduct). We kindly request that you read over this code of conduct before contributing. diff --git a/docs/src/contribute/development-environment.md b/docs/src/contribute/development-environment.md index 6a0d2951fd37..b84af4e32743 100644 --- a/docs/src/contribute/development-environment.md +++ b/docs/src/contribute/development-environment.md @@ -1,11 +1,10 @@ --- -title: Development Environment +title: Set up a Development Environment eleventyNavigation: - key: set up a development environment - parent: developer guide - title: Set Up a Development Environment - order: 2 - + key: development environment + parent: contribute to eslint + title: Set up a Development Environment + order: 6 --- ESLint has a very lightweight development environment that makes updating code fast and easy. This is a step-by-step guide to setting up a local development environment that will let you contribute back to the project. @@ -16,10 +15,16 @@ Go to to download and install the latest stable version fo Most of the installers already come with [npm](https://www.npmjs.com/) but if for some reason npm doesn't work on your system, you can install it manually using the instructions on the site. -## Step 2: Fork and checkout your own ESLint repository +## Step 2: Fork and Checkout Your Own ESLint Repository Go to and click the "Fork" button. Follow the [GitHub documentation](https://help.github.com/articles/fork-a-repo) for forking and cloning. +Clone your fork: + +```shell +git clone https://github.com//eslint +``` + Once you've cloned the repository, run `npm install` to get all the necessary dependencies: ```shell @@ -29,7 +34,9 @@ npm install You must be connected to the Internet for this step to work. You'll see a lot of utilities being downloaded. -## Step 3: Add the upstream source +**Note:** It's a good idea to re-run `npm install` whenever you pull from the main repository to ensure you have the latest development dependencies. + +## Step 3: Add the Upstream Source The *upstream source* is the main ESLint repository where active development happens. While you won't have push access to upstream, you will have pull access, allowing you to pull in the latest code whenever you want. @@ -57,7 +64,7 @@ npm install -g generator-eslint Please see the [generator documentation](https://github.com/eslint/generator-eslint) for instructions on how to use it. -## Step 5: Run the tests +## Step 5: Run the Tests Running the tests is the best way to ensure you have correctly set up your development environment. Make sure you're in the `eslint` directory and run: @@ -69,6 +76,21 @@ The testing takes a few minutes to complete. If any tests fail, that likely mean ## Reference Information +### Directory Structure + +The ESLint directory and file structure is as follows: + +* `bin` - executable files that are available when ESLint is installed +* `conf` - default configuration information +* `docs` - documentation for the project +* `lib` - contains the source code + * `formatters` - all source files defining formatters + * `rules` - all source files defining rules +* `tests` - the main unit test folder + * `lib` - tests for the source code + * `formatters` - tests for the formatters + * `rules` - tests for the rules + ### Workflow Once you have your development environment installed, you can make and submit changes to the ESLint source files. Doing this successfully requires careful adherence to our [pull-request submission workflow](./pull-requests). diff --git a/docs/src/contribute/governance.md b/docs/src/contribute/governance.md index 7f59b210ff08..53e5cda97af3 100644 --- a/docs/src/contribute/governance.md +++ b/docs/src/contribute/governance.md @@ -2,9 +2,9 @@ title: Governance eleventyNavigation: key: governance - parent: maintainer guide + parent: contribute to eslint title: Governance - order: 4 + order: 10 --- @@ -36,8 +36,8 @@ Website Team Members are community members who have shown that they are committe * Are expected to delete their public branches when they are no longer necessary. * Must submit pull requests for all changes. * Have their work reviewed by Reviewers and TSC members before acceptance into the repository. -* May label and close website-related issues (see [Managing Issues](../maintain/manage-issues)) -* May merge some pull requests (see [Managing Pull Requests](../maintain/review-pull-requests)) +* May label and close website-related issues (see [Manage Issues](../maintain/manage-issues)) +* May merge some pull requests (see [Review Pull Requests](../maintain/review-pull-requests)) To become a Website Team Member: @@ -59,8 +59,8 @@ Committers: * Are expected to delete their public branches when they are no longer necessary. * Must submit pull requests for all changes. * Have their work reviewed by TSC members before acceptance into the repository. -* May label and close issues (see [Managing Issues](../maintain/manage-issues)) -* May merge some pull requests (see [Managing Pull Requests](../maintain/review-pull-requests)) +* May label and close issues (see [Manage Issues](../maintain/manage-issues)) +* May merge some pull requests (see [Review Pull Requests](../maintain/review-pull-requests)) To become a Committer: @@ -143,7 +143,7 @@ A Reviewer is invited to become a TSC member by existing TSC members. A nominati 1. Add the GitHub user to the "ESLint TSC" GitHub team 1. Set the GitHub user to be have the "Owner" role for the ESLint organization -1. Send a welcome email with a link to the [maintainer guide](./) and instructions for npm 2FA. +1. Send a welcome email with a link to the [Maintain ESLint documentation](../maintain/) and instructions for npm 2FA. 1. Invite to the Discord TSC channel 1. Make the TSC member an admin on the ESLint team mailing list 1. Add the TSC member to the recurring TSC meeting event on Google Calendar diff --git a/docs/src/contribute/index.md b/docs/src/contribute/index.md index 8e5a76ce0296..0649ecd3d7d4 100644 --- a/docs/src/contribute/index.md +++ b/docs/src/contribute/index.md @@ -1,11 +1,9 @@ --- -title: Contributing +title: Contribute to ESLint eleventyNavigation: - key: contributing - parent: developer guide - title: Contributing - order: 10 - + key: contribute to eslint + title: Contribute to ESLint + order: 3 --- One of the great things about open source projects is that anyone can contribute in any number of meaningful ways. ESLint couldn't exist without the help of the many contributors it's had since the project began, and we want you to feel like you can contribute and make a difference as well. @@ -16,34 +14,50 @@ This guide is intended for anyone who wants to contribute to an ESLint project. ESLint welcomes contributions from everyone and adheres to the [OpenJS Foundation Code of Conduct](https://eslint.org/conduct). We kindly request that you read over our code of conduct before contributing. -## [Bug Reporting](report-bugs) +## [Report Bugs](report-bugs) Think you found a problem? We'd love to hear about it. This section explains how to submit a bug, the type of information we need to properly verify it, and the overall process. -## Proposing a [New Rule](propose-new-rule) +## [Propose a New Rule](propose-new-rule) We get a lot of proposals for new rules in ESLint. This section explains how we determine which rules are accepted and what information you should provide to help us evaluate your proposal. -## Proposing a [Rule Change](propose-rule-change) +## [Propose a Rule Change](propose-rule-change) Want to make a change to an existing rule? This section explains the process and how we evaluate such proposals. -## Requesting a [Change](request-change) +## [Request a Change](request-change) If you'd like to request a change other than a bug fix or new rule, this section explains that process. -## Reporting a security vulnerability +## [Architecture](architecture) + +Learn about the architecture of the ESLint project. + +## [Set up a Development Environment](development-environment) + +Developing for ESLint is a bit different than running it on the command line. This section shows you how to set up a development environment and get you ready to write code. + +## [Run the Tests](tests) -To report a security vulnerability in ESLint, please use our [HackerOne program](https://hackerone.com/eslint). +There are a lot of unit tests included with ESLint to make sure that we're keeping on top of code quality. This section explains how to run the unit tests. -## [Working on Issues](work-on-issue) +## [Work on Issues](work-on-issue) Have some extra time and want to contribute? This section talks about the process of working on issues. -## Submitting a [Pull Request](pull-requests) +## [Submit a Pull Request](pull-requests) We're always looking for contributions from the community. This section explains the requirements for pull requests and the process of contributing code. -## Signing the CLA +## [Governance](governance) + +Describes the governance policy for ESLint, including the rights and privileges of individuals inside the project. + +## [Report a Security Vulnerability](report-security-vulnerability) + +To report a security vulnerability in ESLint, please create an advisory on Github. + +## Sign the CLA In order to submit code or documentation to an ESLint project, you will need to electronically sign our Contributor License Agreement. The CLA is the commonly used Apache-style template, and is you giving us permission to use your contribution. You only need to sign the CLA once for any OpenJS Foundation projects that use EasyCLA. You will be asked to sign the CLA in the first pull request you open. diff --git a/docs/src/contribute/propose-new-rule.md b/docs/src/contribute/propose-new-rule.md index f540f5b8117d..7aa9d3a0e7cc 100644 --- a/docs/src/contribute/propose-new-rule.md +++ b/docs/src/contribute/propose-new-rule.md @@ -1,6 +1,10 @@ --- -title: New Rules - +title: Propose a New Rule +eleventyNavigation: + key: propose rule + parent: contribute to eslint + title: Propose a New Rule + order: 2 --- ESLint is all about rules. For most of the project's lifetime, we've had over 200 rules, and that list continues to grow. However, we can't just accept any proposed rule because all rules need to work cohesively together. As such, we have some guidelines around which rules can be part of the ESLint core and which are better off as custom rules and plugins. @@ -42,4 +46,4 @@ The ESLint team doesn't implement new rules that are suggested by users because ## Alternative: Creating Your Own Rules -Remember that ESLint is completely pluggable, which means you can create your own rules and distribute them using plugins. We did this on purpose because we don't want to be the gatekeepers for all possible rules. Even if we don't accept a rule into the core, that doesn't mean you can't have the exact rule that you want. See the [working with rules](../extend/custom-rules) and [working with plugins](../extend/plugins) documentation for more information. +Remember that ESLint is completely pluggable, which means you can create your own rules and distribute them using plugins. We did this on purpose because we don't want to be the gatekeepers for all possible rules. Even if we don't accept a rule into the core, that doesn't mean you can't have the exact rule that you want. See the [Custom Rules](../extend/custom-rules) and [Create Plugins](../extend/plugins) documentation for more information. diff --git a/docs/src/contribute/propose-rule-change.md b/docs/src/contribute/propose-rule-change.md index ba2738eed8b0..d2d198b19bde 100644 --- a/docs/src/contribute/propose-rule-change.md +++ b/docs/src/contribute/propose-rule-change.md @@ -1,6 +1,10 @@ --- -title: Rule Changes - +title: Propose a Rule Change +eleventyNavigation: + key: propose rule change + parent: contribute to eslint + title: Propose a Rule Change + order: 3 --- Occasionally, a core ESLint rule needs to be changed. This is not necessarily a bug, but rather, an enhancement that makes a rule more configurable. In those situations, we will consider making changes to rules. diff --git a/docs/src/contribute/pull-requests.md b/docs/src/contribute/pull-requests.md index ca478f521ebc..8854ee2fbb24 100644 --- a/docs/src/contribute/pull-requests.md +++ b/docs/src/contribute/pull-requests.md @@ -1,6 +1,10 @@ --- -title: Pull Requests - +title: Submit a Pull Request +eleventyNavigation: + key: submit pull request + parent: contribute to eslint + title: Submit a Pull Request + order: 9 --- If you want to contribute to an ESLint repo, please use a GitHub pull request. This is the fastest way for us to evaluate your code and to merge it into the code base. Please don't file an issue with snippets of code. Doing so means that we need to manually merge the changes in and update any appropriate tests. That decreases the likelihood that your code is going to get included in a timely manner. Please use pull requests. diff --git a/docs/src/contribute/report-bugs.md b/docs/src/contribute/report-bugs.md index 09a60ccd83a5..98e9ce34237f 100644 --- a/docs/src/contribute/report-bugs.md +++ b/docs/src/contribute/report-bugs.md @@ -1,6 +1,10 @@ --- -title: Reporting Bugs - +title: Report Bugs +eleventyNavigation: + key: report bugs + parent: contribute to eslint + title: Report Bugs + order: 1 --- If you think you've found a bug in ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new/choose) or a [pull request](pull-requests) on GitHub. diff --git a/docs/src/contribute/report-security-vulnerability.md b/docs/src/contribute/report-security-vulnerability.md new file mode 100644 index 000000000000..f68319fd34e1 --- /dev/null +++ b/docs/src/contribute/report-security-vulnerability.md @@ -0,0 +1,10 @@ +--- +title: Report a Security Vulnerability +eleventyNavigation: + key: report security vulnerability + parent: contribute to eslint + title: Report a Security Vulnerability + order: 11 +--- + +To report a security vulnerability in ESLint, please use our [create an advisory form](https://github.com/eslint/eslint/security/advisories/new) on GitHub. diff --git a/docs/src/contribute/request-change.md b/docs/src/contribute/request-change.md index 692715b3844e..f8a05c33bb04 100644 --- a/docs/src/contribute/request-change.md +++ b/docs/src/contribute/request-change.md @@ -1,6 +1,10 @@ --- -title: Change Requests - +title: Request a Change +eleventyNavigation: + key: request change + parent: contribute to eslint + title: Request a Change + order: 4 --- If you'd like to request a change to ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new/choose) on GitHub. Be sure to include the following information: diff --git a/docs/src/contribute/source-code.md b/docs/src/contribute/source-code.md deleted file mode 100644 index 4ddc9a8ba941..000000000000 --- a/docs/src/contribute/source-code.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Source Code -eleventyNavigation: - key: getting the source code - parent: developer guide - title: Getting the Source Code - order: 1 - ---- - -ESLint is hosted at [GitHub](https://github.com/eslint/eslint) and uses [Git](https://git-scm.com/) for source control. In order to obtain the source code, you must first install Git on your system. Instructions for installing and setting up Git can be found at . - -If you simply want to create a local copy of the source to play with, you can clone the main repository using this command: - -```shell -git clone git://github.com/eslint/eslint.git -``` - -If you're planning on contributing to ESLint, then it's a good idea to fork the repository. You can find instructions for forking a repository at . After forking the ESLint repository, you'll want to create a local copy of your fork. - -## Start Developing - -Before you can get started developing, you'll need to have a couple of things installed: - -* [Node.JS](https://nodejs.org) -* [npm](https://www.npmjs.com/) - -Once you have a local copy and have Node.JS and npm installed, you'll need to install the ESLint dependencies: - -```shell -cd eslint -npm install -``` - -Now when you run `eslint`, it will be running your local copy and showing your changes. - -**Note:** It's a good idea to re-run `npm install` whenever you pull from the main repository to ensure you have the latest development dependencies. - -## Directory structure - -The ESLint directory and file structure is as follows: - -* `bin` - executable files that are available when ESLint is installed -* `conf` - default configuration information -* `docs` - documentation for the project -* `lib` - contains the source code - * `formatters` - all source files defining formatters - * `rules` - all source files defining rules -* `tests` - the main unit test folder - * `lib` - tests for the source code - * `formatters` - tests for the formatters - * `rules` - tests for the rules diff --git a/docs/src/contribute/tests.md b/docs/src/contribute/tests.md index 730642f624bc..9ad25500d82b 100644 --- a/docs/src/contribute/tests.md +++ b/docs/src/contribute/tests.md @@ -1,11 +1,10 @@ --- -title: Unit Tests +title: Run the Tests eleventyNavigation: - key: run the tests - parent: developer guide + key: run tests + parent: contribute to eslint title: Run the Tests - order: 3 - + order: 7 --- Most parts of ESLint have unit tests associated with them. Unit tests are written using [Mocha](https://mochajs.org/) and are required when making contributions to ESLint. You'll find all of the unit tests in the `tests` directory. diff --git a/docs/src/contribute/work-on-issue.md b/docs/src/contribute/work-on-issue.md index 216224b0dd45..6205a37fd7e1 100644 --- a/docs/src/contribute/work-on-issue.md +++ b/docs/src/contribute/work-on-issue.md @@ -1,16 +1,20 @@ --- -title: Working on Issues - +title: Work on Issues +eleventyNavigation: + key: work on issues + parent: contribute to eslint + title: Work on Issues + order: 8 --- Our public [issues tracker](https://github.com/eslint/eslint/issues) lists all of the things we plan on doing as well as suggestions from the community. Before starting to work on an issue, be sure you read through the rest of this page. ## Issue Labels -We use labels to indicate the status of issues. The most complete documentation on the labels is found in the [Maintainer Guide](../maintain/manage-issues#when-an-issue-is-opened), but most contributors should find the information on this page sufficient. The most important questions that labels can help you, as a contributor, answer are: +We use labels to indicate the status of issues. The most complete documentation on the labels is found in the [Maintain ESLint documentation](../maintain/manage-issues#when-an-issue-is-opened), but most contributors should find the information on this page sufficient. The most important questions that labels can help you, as a contributor, answer are: 1. Is this issue available for me to work on? If you have little or no experience contributing to ESLint, the [`good first issue`](https://github.com/eslint/eslint/labels/good%20first%20issue) label marks appropriate issues. Otherwise, the [`help wanted`](https://github.com/eslint/eslint/labels/help%20wanted) label is an invitation to work on the issue. If you have more experience, you can try working on other issues labeled [`accepted`](https://github.com/eslint/eslint/labels/accepted). Conversely, issues not yet ready to work on are labeled `triage`, `evaluating`, and/or `needs bikeshedding`, and issues that cannot currently be worked on because of something else, such as a bug in a dependency, are labeled `blocked`. -1. What is this issue about? Labels describing the nature of issues include `bug`, `enhancement`, `feature`, `question`, `rule`, `documentation`, `core`, `build`, `cli`, `infrastructure`, `breaking`, and `chore`. These are documented in the [Maintainer Guide](../maintain/manage-issues#types-of-issues). +1. What is this issue about? Labels describing the nature of issues include `bug`, `enhancement`, `feature`, `question`, `rule`, `documentation`, `core`, `build`, `cli`, `infrastructure`, `breaking`, and `chore`. These are documented in [Maintain ESLint](../maintain/manage-issues#types-of-issues). 1. What is the priority of this issue? Because we have a lot of issues, we prioritize certain issues above others. The following is the list of priorities, from highest to lowest: 1. **Bugs** - problems with the project are actively affecting users. We want to get these resolved as quickly as possible. diff --git a/docs/src/extend/code-path-analysis.md b/docs/src/extend/code-path-analysis.md index 5dca4ed79a52..6cb7d2ac571e 100644 --- a/docs/src/extend/code-path-analysis.md +++ b/docs/src/extend/code-path-analysis.md @@ -14,7 +14,9 @@ if (a && b) { bar(); ``` +:::img-container ![Code Path Example](../assets/images/code-path-analysis/helo.svg) +::: ## Objects @@ -143,17 +145,23 @@ bar(); 1. First, the analysis advances to the end of loop. +:::img-container ![Loop Event's Example 1](../assets/images/code-path-analysis/loop-event-example-while-1.svg) +::: 2. Second, it creates the looping path. At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. It fires `onCodePathSegmentLoop` instead. +:::img-container ![Loop Event's Example 2](../assets/images/code-path-analysis/loop-event-example-while-2.svg) +::: 3. Last, it advances to the end. +:::img-container ![Loop Event's Example 3](../assets/images/code-path-analysis/loop-event-example-while-3.svg) +::: For example 2: @@ -168,29 +176,39 @@ bar(); First, the analysis advances to `ForStatement.update`. The `update` segment is hovered at first. +:::img-container ![Loop Event's Example 1](../assets/images/code-path-analysis/loop-event-example-for-1.svg) +::: 2. Second, it advances to `ForStatement.body`. Of course the `body` segment is preceded by the `test` segment. It keeps the `update` segment hovering. +:::img-container ![Loop Event's Example 2](../assets/images/code-path-analysis/loop-event-example-for-2.svg) +::: 3. Third, it creates the looping path from `body` segment to `update` segment. At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. It fires `onCodePathSegmentLoop` instead. +:::img-container ![Loop Event's Example 3](../assets/images/code-path-analysis/loop-event-example-for-3.svg) +::: 4. Fourth, also it creates the looping path from `update` segment to `test` segment. At this time, the next segment has existed already, so the `onCodePathSegmentStart` event is not fired. It fires `onCodePathSegmentLoop` instead. +:::img-container ![Loop Event's Example 4](../assets/images/code-path-analysis/loop-event-example-for-4.svg) +::: 5. Last, it advances to the end. +:::img-container ![Loop Event's Example 5](../assets/images/code-path-analysis/loop-event-example-for-5.svg) +::: ## Usage Examples @@ -336,7 +354,9 @@ See Also: console.log("Hello world!"); ``` +:::img-container ![Hello World](../assets/images/code-path-analysis/example-hello-world.svg) +::: ### `IfStatement` @@ -348,7 +368,9 @@ if (a) { } ``` +:::img-container ![`IfStatement`](../assets/images/code-path-analysis/example-ifstatement.svg) +::: ### `IfStatement` (chain) @@ -362,7 +384,9 @@ if (a) { } ``` +:::img-container ![`IfStatement` (chain)](../assets/images/code-path-analysis/example-ifstatement-chain.svg) +::: ### `SwitchStatement` @@ -383,7 +407,9 @@ switch (a) { } ``` +:::img-container ![`SwitchStatement`](../assets/images/code-path-analysis/example-switchstatement.svg) +::: ### `SwitchStatement` (has `default`) @@ -408,7 +434,9 @@ switch (a) { } ``` +:::img-container ![`SwitchStatement` (has `default`)](../assets/images/code-path-analysis/example-switchstatement-has-default.svg) +::: ### `TryStatement` (try-catch) @@ -431,7 +459,9 @@ It creates the paths from `try` block to `catch` block at: * The first throwable node (e.g. a function call) in the `try` block. * The end of the `try` block. +:::img-container ![`TryStatement` (try-catch)](../assets/images/code-path-analysis/example-trystatement-try-catch.svg) +::: ### `TryStatement` (try-finally) @@ -449,7 +479,9 @@ If there is not `catch` block, `finally` block has two current segments. At this time, `CodePath.currentSegments.length` is `2`. One is the normal path, and another is the leaving path (`throw` or `return`). +:::img-container ![`TryStatement` (try-finally)](../assets/images/code-path-analysis/example-trystatement-try-finally.svg) +::: ### `TryStatement` (try-catch-finally) @@ -465,7 +497,9 @@ try { last(); ``` +:::img-container ![`TryStatement` (try-catch-finally)](../assets/images/code-path-analysis/example-trystatement-try-catch-finally.svg) +::: ### `WhileStatement` @@ -479,7 +513,9 @@ while (a) { } ``` +:::img-container ![`WhileStatement`](../assets/images/code-path-analysis/example-whilestatement.svg) +::: ### `DoWhileStatement` @@ -490,7 +526,9 @@ do { } while (a); ``` +:::img-container ![`DoWhileStatement`](../assets/images/code-path-analysis/example-dowhilestatement.svg) +::: ### `ForStatement` @@ -504,7 +542,9 @@ for (let i = 0; i < 10; ++i) { } ``` +:::img-container ![`ForStatement`](../assets/images/code-path-analysis/example-forstatement.svg) +::: ### `ForStatement` (for ever) @@ -515,7 +555,9 @@ for (;;) { bar(); ``` +:::img-container ![`ForStatement` (for ever)](../assets/images/code-path-analysis/example-forstatement-for-ever.svg) +::: ### `ForInStatement` @@ -525,7 +567,9 @@ for (let key in obj) { } ``` +:::img-container ![`ForInStatement`](../assets/images/code-path-analysis/example-forinstatement.svg) +::: ### When there is a function @@ -544,8 +588,12 @@ It creates two code paths. * The global's +:::img-container ![When there is a function](../assets/images/code-path-analysis/example-when-there-is-a-function-g.svg) +::: * The function's +:::img-container ![When there is a function](../assets/images/code-path-analysis/example-when-there-is-a-function-f.svg) +::: diff --git a/docs/src/extend/custom-formatters.md b/docs/src/extend/custom-formatters.md index b34baaf250e5..29376d2a8502 100644 --- a/docs/src/extend/custom-formatters.md +++ b/docs/src/extend/custom-formatters.md @@ -1,10 +1,10 @@ --- -title: Working with Custom Formatters +title: Custom Formatters eleventyNavigation: - key: working with custom formatters - parent: developer guide - title: Working with Custom Formatters - order: 6 + key: custom formatters + parent: extend eslint + title: Custom Formatters + order: 3 --- @@ -132,7 +132,7 @@ The formatter function receives an object as the second argument. The object has * `cwd` ... The current working directory. This value comes from the `cwd` constructor option of the [ESLint](../integrate/nodejs-api#-new-eslintoptions) class. * `maxWarningsExceeded` (optional): If `--max-warnings` was set and the number of warnings exceeded the limit, this property's value will be an object containing two properties: `maxWarnings`, the value of the `--max-warnings` option, and `foundWarnings`, the number of lint warnings. -* `rulesMeta` ... The `meta` property values of rules. See the [Working with Rules](custom-rules) page for more information about rules. +* `rulesMeta` ... The `meta` property values of rules. See the [Custom Rules](custom-rules) page for more information about rules. For example, here's what the object would look like if one rule, `no-extra-semi`, had been run: diff --git a/docs/src/extend/custom-parsers.md b/docs/src/extend/custom-parsers.md index a2b47c53f035..e49c24c98a96 100644 --- a/docs/src/extend/custom-parsers.md +++ b/docs/src/extend/custom-parsers.md @@ -1,10 +1,10 @@ --- -title: Working with Custom Parsers +title: Custom Parsers eleventyNavigation: - key: working with custom parsers - parent: developer guide - title: Working with Custom Parsers - order: 7 + key: custom parsers + parent: extend eslint + title: Custom Parsers + order: 4 --- diff --git a/docs/src/extend/custom-processors.md b/docs/src/extend/custom-processors.md new file mode 100644 index 000000000000..a2f1d8059930 --- /dev/null +++ b/docs/src/extend/custom-processors.md @@ -0,0 +1,120 @@ +--- +title: Custom Processors +eleventyNavigation: + key: custom processors + parent: extend eslint + title: Custom Processors + order: 5 + +--- +You can also create custom processors that tell ESLint how to process files other than JavaScript. + +## Custom Processor Specification + +In order to create a processor, the object that is exported from your module has to conform to the following interface: + +```js +module.exports = { + processors: { + "processor-name": { + // takes text of the file and filename + preprocess: function(text, filename) { + // here, you can strip out any non-JS content + // and split into multiple strings to lint + + return [ // return an array of code blocks to lint + { text: code1, filename: "0.js" }, + { text: code2, filename: "1.js" }, + ]; + }, + + // takes a Message[][] and filename + postprocess: function(messages, filename) { + // `messages` argument contains two-dimensional array of Message objects + // where each top-level array item contains array of lint messages related + // to the text that was returned in array from preprocess() method + + // you need to return a one-dimensional array of the messages you want to keep + return [].concat(...messages); + }, + + supportsAutofix: true // (optional, defaults to false) + } + } +}; +``` + +**The `preprocess` method** takes the file contents and filename as arguments, and returns an array of code blocks to lint. The code blocks will be linted separately but still be registered to the filename. + +A code block has two properties `text` and `filename`; the `text` property is the content of the block and the `filename` property is the name of the block. Name of the block can be anything, but should include the file extension, that would tell the linter how to process the current block. The linter will check [`--ext` CLI option](../use/command-line-interface#--ext) to see if the current block should be linted, and resolve `overrides` configs to check how to process the current block. + +It's up to the plugin to decide if it needs to return just one part, or multiple pieces. For example in the case of processing `.html` files, you might want to return just one item in the array by combining all scripts, but for `.md` file where each JavaScript block might be independent, you can return multiple items. + +**The `postprocess` method** takes a two-dimensional array of arrays of lint messages and the filename. Each item in the input array corresponds to the part that was returned from the `preprocess` method. The `postprocess` method must adjust the locations of all errors to correspond to locations in the original, unprocessed code, and aggregate them into a single flat array and return it. + +Reported problems have the following location information: + +```typescript +{ + line: number, + column: number, + + endLine?: number, + endColumn?: number +} +``` + +By default, ESLint will not perform autofixes when a processor is used, even when the `--fix` flag is enabled on the command line. To allow ESLint to autofix code when using your processor, you should take the following additional steps: + +1. Update the `postprocess` method to additionally transform the `fix` property of reported problems. All autofixable problems will have a `fix` property, which is an object with the following schema: + + ```js + { + range: [number, number], + text: string + } + ``` + + The `range` property contains two indexes in the code, referring to the start and end location of a contiguous section of text that will be replaced. The `text` property refers to the text that will replace the given range. + + In the initial list of problems, the `fix` property will refer to a fix in the processed JavaScript. The `postprocess` method should transform the object to refer to a fix in the original, unprocessed file. + +2. Add a `supportsAutofix: true` property to the processor. + +You can have both rules and processors in a single plugin. You can also have multiple processors in one plugin. +To support multiple extensions, add each one to the `processors` element and point them to the same object. + +## Specifying Processor in Config Files + +To use a processor, add its ID to a `processor` section in the config file. Processor ID is a concatenated string of plugin name and processor name with a slash as a separator. This can also be added to a `overrides` section of the config, to specify which processors should handle which files. + +For example: + +```yml +plugins: + - a-plugin +overrides: + - files: "*.md" + processor: a-plugin/markdown +``` + +See [Specify a Processor](../use/configure/plugins#specify-a-processor) in the Plugin Configuration documentation for more details. + +## File Extension-named Processor + +If a processor name starts with `.`, ESLint handles the processor as a **file extension-named processor** especially and applies the processor to the kind of files automatically. People don't need to specify the file extension-named processors in their config files. + +For example: + +```js +module.exports = { + processors: { + // This processor will be applied to `*.md` files automatically. + // Also, people can use this processor as "plugin-id/.md" explicitly. + ".md": { + preprocess(text, filename) { /* ... */ }, + postprocess(messageLists, filename) { /* ... */ } + } + } +} +``` diff --git a/docs/src/extend/custom-rules.md b/docs/src/extend/custom-rules.md index 8e7632484adf..5da0b6722de5 100644 --- a/docs/src/extend/custom-rules.md +++ b/docs/src/extend/custom-rules.md @@ -1,10 +1,10 @@ --- -title: Working with Rules +title: Custom Rules eleventyNavigation: - key: working with rules - parent: developer guide - title: Working with Rules - order: 4 + key: custom rules + parent: extend eslint + title: Custom Rules + order: 2 --- diff --git a/docs/src/extend/index.md b/docs/src/extend/index.md index 2c97b2fa2043..426000d49e61 100644 --- a/docs/src/extend/index.md +++ b/docs/src/extend/index.md @@ -1,54 +1,46 @@ --- -title: Developer Guide +title: Extend ESLint eleventyNavigation: - key: developer guide - title: Developer Guide + key: extend eslint + title: Extend ESLint order: 2 --- -This guide is intended for those who wish to: +This guide is intended for those who wish to extend the functionality of ESLint. -* Contribute code to ESLint -* Create their own rules for ESLint - -In order to work with ESLint as a developer, it's recommended that: +In order to extend ESLint, it's recommended that: * You know JavaScript, since ESLint is written in JavaScript. * You have some familiarity with Node.js, since ESLint runs on it. * You're comfortable with command-line programs. -* You understand unit tests and why they're important. If that sounds like you, then continue reading to get started. -## Section 1: Get the [Source Code](../contribute/source-code) +## [Create Plugins](plugins) -Before you can get started, you'll need to get a copy of the ESLint source code. This section explains how to do that and a little about the source code structure. +You've developed custom rules for ESLint and you want to share them with the community. You can publish an ESLint plugin on npm. -## Section 2: Set up a [Development Environment](../contribute/development-environment) +## [Custom Rules](custom-rules) -Developing for ESLint is a bit different than running it on the command line. This section shows you how to set up a development environment and get you ready to write code. +This section explains how to create and modify rules to use with ESLint. -## Section 3: Run the [Unit Tests](../contribute/tests) +## [Custom Formatters](custom-formatters) -There are a lot of unit tests included with ESLint to make sure that we're keeping on top of code quality. This section explains how to run the unit tests. +This section explains how you can create a custom formatter to control what ESLint outputs. -## Section 4: [Working with Rules](custom-rules) +## [Custom Parsers](custom-parsers) -You're finally ready to start working with rules. You may want to fix an existing rule or create a new one. This section explains how to do all of that. +If you don't want to use the default parser of ESLint, this section explains how to create custom parsers. -## Section 5: [Working with Plugins](plugins) +## [Custom Processors](custom-processors) -You've developed library-specific rules for ESLint and you want to share them with the community. You can publish an ESLint plugin on npm. +This section explains how you can use a custom processor to have ESLint process files other than JavaScript. -## Section 6: [Working with Custom Parsers](custom-parsers) +## [Share Configurations](shareable-configs) -If you aren't going to use the default parser of ESLint, this section explains about using custom parsers. +This section explains how you can bundle and share ESLint configuration in a JavaScript package. -## Section 7: [Node.js API](../integrate/nodejs-api) +## [Node.js API Reference](../integrate/nodejs-api) If you're interested in writing a tool that uses ESLint, then you can use the Node.js API to get programmatic access to functionality. - -## Section 8: [Contributing](../contribute/) - -Once you've made changes that you want to share with the community, the next step is to submit those changes back via a pull request. diff --git a/docs/src/extend/plugins.md b/docs/src/extend/plugins.md index 8de331714db3..970581ae4f24 100644 --- a/docs/src/extend/plugins.md +++ b/docs/src/extend/plugins.md @@ -1,10 +1,10 @@ --- -title: Working with Plugins +title: Create Plugins eleventyNavigation: - key: working with plugings - parent: developer guide - title: Working with Plugins - order: 5 + key: create plugins + parent: extend eslint + title: Create Plugins + order: 1 --- @@ -57,109 +57,20 @@ Plugin environments can define the following objects: ### Processors in Plugins -You can also create plugins that would tell ESLint how to process files other than JavaScript. In order to create a processor, the object that is exported from your module has to conform to the following interface: - -```js -module.exports = { - processors: { - "processor-name": { - // takes text of the file and filename - preprocess: function(text, filename) { - // here, you can strip out any non-JS content - // and split into multiple strings to lint - - return [ // return an array of code blocks to lint - { text: code1, filename: "0.js" }, - { text: code2, filename: "1.js" }, - ]; - }, - - // takes a Message[][] and filename - postprocess: function(messages, filename) { - // `messages` argument contains two-dimensional array of Message objects - // where each top-level array item contains array of lint messages related - // to the text that was returned in array from preprocess() method - - // you need to return a one-dimensional array of the messages you want to keep - return [].concat(...messages); - }, - - supportsAutofix: true // (optional, defaults to false) - } - } -}; -``` - -**The `preprocess` method** takes the file contents and filename as arguments, and returns an array of code blocks to lint. The code blocks will be linted separately but still be registered to the filename. - -A code block has two properties `text` and `filename`; the `text` property is the content of the block and the `filename` property is the name of the block. Name of the block can be anything, but should include the file extension, that would tell the linter how to process the current block. The linter will check [`--ext` CLI option](../use/command-line-interface#--ext) to see if the current block should be linted, and resolve `overrides` configs to check how to process the current block. - -It's up to the plugin to decide if it needs to return just one part, or multiple pieces. For example in the case of processing `.html` files, you might want to return just one item in the array by combining all scripts, but for `.md` file where each JavaScript block might be independent, you can return multiple items. - -**The `postprocess` method** takes a two-dimensional array of arrays of lint messages and the filename. Each item in the input array corresponds to the part that was returned from the `preprocess` method. The `postprocess` method must adjust the locations of all errors to correspond to locations in the original, unprocessed code, and aggregate them into a single flat array and return it. - -Reported problems have the following location information: - -```typescript -{ - line: number, - column: number, - - endLine?: number, - endColumn?: number -} -``` - -By default, ESLint will not perform autofixes when a processor is used, even when the `--fix` flag is enabled on the command line. To allow ESLint to autofix code when using your processor, you should take the following additional steps: - -1. Update the `postprocess` method to additionally transform the `fix` property of reported problems. All autofixable problems will have a `fix` property, which is an object with the following schema: - - ```js - { - range: [number, number], - text: string - } - ``` - - The `range` property contains two indexes in the code, referring to the start and end location of a contiguous section of text that will be replaced. The `text` property refers to the text that will replace the given range. - - In the initial list of problems, the `fix` property will refer to a fix in the processed JavaScript. The `postprocess` method should transform the object to refer to a fix in the original, unprocessed file. - -2. Add a `supportsAutofix: true` property to the processor. - -You can have both rules and processors in a single plugin. You can also have multiple processors in one plugin. -To support multiple extensions, add each one to the `processors` element and point them to the same object. - -#### Specifying Processor in Config Files - -To use a processor, add its ID to a `processor` section in the config file. Processor ID is a concatenated string of plugin name and processor name with a slash as a separator. This can also be added to a `overrides` section of the config, to specify which processors should handle which files. - -For example: - -```yml -plugins: - - a-plugin -overrides: - - files: "*.md" - processor: a-plugin/markdown -``` - -See [Specifying Processor](../use/configure/plugins#specify-a-processor) for details. - -#### File Extension-named Processor - -If a processor name starts with `.`, ESLint handles the processor as a **file extension-named processor** especially and applies the processor to the kind of files automatically. People don't need to specify the file extension-named processors in their config files. - -For example: +You can add processors to plugins by including the processor functions in the `processors` key. For more information on defining custom processors, refer to [Custom Processors](custom-processors). ```js module.exports = { processors: { // This processor will be applied to `*.md` files automatically. - // Also, people can use this processor as "plugin-id/.md" explicitly. ".md": { preprocess(text, filename) { /* ... */ }, - postprocess(messageLists, filename) { /* ... */ } + postprocess(messages, filename) { /* ... */ } + } + "processor-name": { + preprocess: function(text, filename) {/* ... */}, + + postprocess: function(messages, filename) { /* ... */ }, } } } @@ -205,7 +116,7 @@ If the example plugin above were called `eslint-plugin-myPlugin`, the `myConfig` ``` -**Note:** Please note that configuration will not enable any of the plugin's rules by default, and instead should be treated as a standalone config. This means that you must specify your plugin name in the `plugins` array as well as any rules you want to enable that are part of the plugin. Any plugin rules must be prefixed with the short or long plugin name. See [Configuring Plugins](../use/configure/plugins#configure-plugins) for more information. +**Note:** Please note that configuration will not enable any of the plugin's rules by default, and instead should be treated as a standalone config. This means that you must specify your plugin name in the `plugins` array as well as any rules you want to enable that are part of the plugin. Any plugin rules must be prefixed with the short or long plugin name. See [Configure Plugins](../use/configure/plugins#configure-plugins) for more information. ### Peer Dependency diff --git a/docs/src/extend/shareable-configs.md b/docs/src/extend/shareable-configs.md index ca42eafa69d5..297229b96946 100644 --- a/docs/src/extend/shareable-configs.md +++ b/docs/src/extend/shareable-configs.md @@ -1,10 +1,10 @@ --- -title: Shareable Configs +title: Share Configurations eleventyNavigation: - key: shareable configs - parent: developer guide - title: Shareable Configs - order: 8 + key: share configs + parent: extend eslint + title: Share Configurations + order: 6 --- diff --git a/docs/src/integrate/nodejs-api.md b/docs/src/integrate/nodejs-api.md index b817c23fa538..08583fc34487 100644 --- a/docs/src/integrate/nodejs-api.md +++ b/docs/src/integrate/nodejs-api.md @@ -1,11 +1,10 @@ --- -title: Node.js API +title: Node.js API Reference eleventyNavigation: key: node.js api - parent: developer guide - title: Node.js API - order: 9 - + parent: extend eslint + title: Node.js API Reference + order: 7 --- While ESLint is designed to be run on the command line, it's possible to use ESLint programmatically through the Node.js API. The purpose of the Node.js API is to allow plugin and tool authors to use the ESLint functionality directly, without going through the command line interface. @@ -24,48 +23,92 @@ Here's a simple example of using the `ESLint` class: const { ESLint } = require("eslint"); (async function main() { - // 1. Create an instance. - const eslint = new ESLint(); + // 1. Create an instance. + const eslint = new ESLint(); - // 2. Lint files. - const results = await eslint.lintFiles(["lib/**/*.js"]); + // 2. Lint files. + const results = await eslint.lintFiles(["lib/**/*.js"]); - // 3. Format the results. - const formatter = await eslint.loadFormatter("stylish"); - const resultText = formatter.format(results); + // 3. Format the results. + const formatter = await eslint.loadFormatter("stylish"); + const resultText = formatter.format(results); - // 4. Output it. - console.log(resultText); + // 4. Output it. + console.log(resultText); })().catch((error) => { - process.exitCode = 1; - console.error(error); + process.exitCode = 1; + console.error(error); }); ``` -And here is an example that autofixes lint problems: +Here's an example that autofixes lint problems: ```js const { ESLint } = require("eslint"); (async function main() { - // 1. Create an instance with the `fix` option. - const eslint = new ESLint({ fix: true }); + // 1. Create an instance with the `fix` option. + const eslint = new ESLint({ fix: true }); + + // 2. Lint files. This doesn't modify target files. + const results = await eslint.lintFiles(["lib/**/*.js"]); + + // 3. Modify the files with the fixed code. + await ESLint.outputFixes(results); + + // 4. Format the results. + const formatter = await eslint.loadFormatter("stylish"); + const resultText = formatter.format(results); + + // 5. Output it. + console.log(resultText); +})().catch((error) => { + process.exitCode = 1; + console.error(error); +}); +``` - // 2. Lint files. This doesn't modify target files. - const results = await eslint.lintFiles(["lib/**/*.js"]); +And here is an example of using the `ESLint` class with `lintText` API: + +```js +const { ESLint } = require("eslint"); + +const testCode = ` + const name = "eslint"; + if(true) { + console.log("constant condition warning") + }; +`; + +(async function main() { + // 1. Create an instance + const eslint = new ESLint({ + useEslintrc: false, + overrideConfig: { + extends: ["eslint:recommended"], + parserOptions: { + sourceType: "module", + ecmaVersion: "latest", + }, + env: { + es2022: true, + node: true, + }, + }, + }); - // 3. Modify the files with the fixed code. - await ESLint.outputFixes(results); + // 2. Lint text. + const results = await eslint.lintText(testCode); - // 4. Format the results. - const formatter = await eslint.loadFormatter("stylish"); - const resultText = formatter.format(results); + // 3. Format the results. + const formatter = await eslint.loadFormatter("stylish"); + const resultText = formatter.format(results); - // 5. Output it. - console.log(resultText); + // 4. Output it. + console.log(resultText); })().catch((error) => { - process.exitCode = 1; - console.error(error); + process.exitCode = 1; + console.error(error); }); ``` diff --git a/docs/src/maintain/index.md b/docs/src/maintain/index.md index ed7d04005bb2..88d537aa0535 100644 --- a/docs/src/maintain/index.md +++ b/docs/src/maintain/index.md @@ -1,30 +1,26 @@ --- -title: Maintainer Guide +title: Maintain ESLint eleventyNavigation: - key: maintainer guide - title: Maintainer Guide - order: 3 + key: maintain eslint + title: Maintain ESLint + order: 4 --- This guide is intended for those who work as part of the ESLint project team. -## [Managing Issues](manage-issues) +## [Manage Issues](manage-issues) Describes how to deal with issues when they're opened, when interacting with users, and how to close them effectively. -## [Reviewing Pull Requests](review-pull-requests) +## [Review Pull Requests](review-pull-requests) Describes how to review incoming pull requests. -## [Managing Releases](manage-releases) +## [Manage Releases](manage-releases) Describes how to do an ESLint project release. -## [Governance](../contribute/governance) - -Describes the governance policy for ESLint, including the rights and privileges of individuals inside the project. - ## [Working Groups](working-groups) Describes how working groups are created and how they function within the ESLint project. diff --git a/docs/src/maintain/manage-issues.md b/docs/src/maintain/manage-issues.md index 977fc3d891c7..394019df0663 100644 --- a/docs/src/maintain/manage-issues.md +++ b/docs/src/maintain/manage-issues.md @@ -1,9 +1,9 @@ --- -title: Managing Issues +title: Manage Issues eleventyNavigation: - key: managing issues - parent: maintainer guide - title: Managing Issues + key: manage issues + parent: maintain eslint + title: Manage Issues order: 1 --- diff --git a/docs/src/maintain/manage-releases.md b/docs/src/maintain/manage-releases.md index 9b58eb92e6f4..10d681a4fd82 100644 --- a/docs/src/maintain/manage-releases.md +++ b/docs/src/maintain/manage-releases.md @@ -1,9 +1,9 @@ --- -title: Managing Releases +title: Manage Releases eleventyNavigation: - key: managing releases - parent: maintainer guide - title: Managing Releases + key: manage releases + parent: maintain eslint + title: Manage Releases order: 3 --- diff --git a/docs/src/maintain/review-pull-requests.md b/docs/src/maintain/review-pull-requests.md index 9c43ccad4add..6705a81d6034 100644 --- a/docs/src/maintain/review-pull-requests.md +++ b/docs/src/maintain/review-pull-requests.md @@ -1,9 +1,9 @@ --- -title: Reviewing Pull Requests +title: Review Pull Requests eleventyNavigation: - key: reviewing pull requests - parent: maintainer guide - title: Reviewing Pull Requests + key: review pull requests + parent: maintain eslint + title: Review Pull Requests order: 2 --- diff --git a/docs/src/maintain/working-groups.md b/docs/src/maintain/working-groups.md index 1293340d734b..97d31dfd29fd 100644 --- a/docs/src/maintain/working-groups.md +++ b/docs/src/maintain/working-groups.md @@ -1,6 +1,10 @@ --- title: Working Groups - +eleventyNavigation: + key: working groups + parent: maintain eslint + title: Working Groups + order: 4 --- The ESLint TSC may form working groups to focus on a specific area of the project. diff --git a/docs/src/pages/index.md b/docs/src/pages/index.md index a2e82b8cd1cd..c8f5f62dcaa8 100644 --- a/docs/src/pages/index.md +++ b/docs/src/pages/index.md @@ -5,15 +5,19 @@ permalink: /index.html Welcome to our documentation pages! What would you like to view? -## [User Guide](use/) +## [Use ESLint in Your Project](use/) Intended for end users of ESLint. Contains information about core rules, configuration, command line options, formatters, and integrations, as well as guides for migrating from earlier versions of ESLint. -## [Developer Guide](extend/) +## [Extend ESLint](extend/) Intended for people who wish to extend ESLint. Contains information about creating custom rules, configurations, plugins, and formatters; and information about our Node.js API. -## [Maintainer Guide](maintain/) +## [Contribute to ESLint](contribute/) + +Intended for people who wish to contribute to the ESLint project. Contains information about ways you can contribute, the project structure, and setting up the development environment. + +## [Maintain ESLint](maintain/) Intended for maintainers of ESLint. diff --git a/docs/src/pages/rules.md b/docs/src/pages/rules.md index fabc4241266a..996860e2c865 100644 --- a/docs/src/pages/rules.md +++ b/docs/src/pages/rules.md @@ -1,10 +1,10 @@ --- -title: Rules +title: Rules Reference permalink: /rules/index.html eleventyNavigation: key: rules - parent: user guide - title: Rules + parent: use eslint + title: Rules Reference order: 5 --- diff --git a/docs/src/rules/id-denylist.md b/docs/src/rules/id-denylist.md index 8be841832741..850f5923e830 100644 --- a/docs/src/rules/id-denylist.md +++ b/docs/src/rules/id-denylist.md @@ -37,7 +37,7 @@ For example, to restrict the use of common generic identifiers: } ``` -**Note:** The first element of the array is for the rule severity (see [configuring rules](../use/configure/rules). The other elements in the array are the identifiers that you want to disallow. +**Note:** The first element of the array is for the rule severity (see [Configure Rules](../use/configure/rules). The other elements in the array are the identifiers that you want to disallow. Examples of **incorrect** code for this rule with sample `"data", "callback"` restricted identifiers: diff --git a/docs/src/rules/no-constant-condition.md b/docs/src/rules/no-constant-condition.md index 828a036ca489..2ac613f7abfb 100644 --- a/docs/src/rules/no-constant-condition.md +++ b/docs/src/rules/no-constant-condition.md @@ -74,6 +74,10 @@ do { } while (x = -1); var result = 0 ? a : b; + +if(input === "hello" || "bye"){ + output(input); +} ``` ::: @@ -102,6 +106,10 @@ do { } while (x); var result = x !== 0 ? a : b; + +if(input === "hello" || input === "bye"){ + output(input); +} ``` ::: diff --git a/docs/src/rules/no-multiple-empty-lines.md b/docs/src/rules/no-multiple-empty-lines.md index a997103966b7..81bb3127356d 100644 --- a/docs/src/rules/no-multiple-empty-lines.md +++ b/docs/src/rules/no-multiple-empty-lines.md @@ -31,6 +31,7 @@ Examples of **incorrect** code for this rule with the default `{ "max": 2 }` opt var foo = 5; + var bar = 3; ``` @@ -45,6 +46,7 @@ Examples of **correct** code for this rule with the default `{ "max": 2 }` optio var foo = 5; + var bar = 3; ``` @@ -61,8 +63,10 @@ Examples of **incorrect** code for this rule with the `{ max: 2, maxEOF: 0 }` op var foo = 5; + var bar = 3; + ``` ::: @@ -76,6 +80,7 @@ Examples of **correct** code for this rule with the `{ max: 2, maxEOF: 0 }` opti var foo = 5; + var bar = 3; ``` @@ -85,6 +90,8 @@ var bar = 3; **Incorrect**: +::: incorrect + ```js 1 /*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎ 2 ⏎ @@ -96,8 +103,12 @@ var bar = 3; 8 ``` +::: + **Correct**: +::: correct + ```js 1 /*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎ 2 ⏎ @@ -108,6 +119,8 @@ var bar = 3; 7 ``` +::: + ### maxBOF Examples of **incorrect** code for this rule with the `{ max: 2, maxBOF: 1 }` options: @@ -117,8 +130,10 @@ Examples of **incorrect** code for this rule with the `{ max: 2, maxBOF: 1 }` op ```js /*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxBOF": 1 }]*/ + var foo = 5; + var bar = 3; ``` @@ -133,6 +148,7 @@ Examples of **correct** code for this rule with the `{ max: 2, maxBOF: 1 }` opti var foo = 5; + var bar = 3; ``` diff --git a/docs/src/rules/no-restricted-exports.md b/docs/src/rules/no-restricted-exports.md index 8a40852e0673..2f83643f9cb8 100644 --- a/docs/src/rules/no-restricted-exports.md +++ b/docs/src/rules/no-restricted-exports.md @@ -17,8 +17,16 @@ By default, this rule doesn't disallow any names. Only the names you specify in This rule has an object option: * `"restrictedNamedExports"` is an array of strings, where each string is a name to be restricted. +* `"restrictDefaultExports"` is an object option with boolean properties to restrict certain default export declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. The following properties are allowed: + * `direct`: restricts `export default` declarations. + * `named`: restricts `export { foo as default };` declarations. + * `defaultFrom`: restricts `export { default } from 'foo';` declarations. + * `namedFrom`: restricts `export { foo as default } from 'foo';` declarations. + * `namespaceFrom`: restricts `export * as default from 'foo';` declarations. -Examples of **incorrect** code for this rule: +### restrictedNamedExports + +Examples of **incorrect** code for the `"restrictedNamedExports"` option: ::: incorrect @@ -50,7 +58,7 @@ export { "👍" } from "some_module"; ::: -Examples of **correct** code for this rule: +Examples of **correct** code for the `"restrictedNamedExports"` option: ::: correct @@ -82,11 +90,11 @@ export { "👍" as thumbsUp } from "some_module"; ::: -### Default exports +#### Default exports -By design, this rule doesn't disallow `export default` declarations. If you configure `"default"` as a restricted name, that restriction will apply only to named export declarations. +By design, the `"restrictedNamedExports"` option doesn't disallow `export default` declarations. If you configure `"default"` as a restricted name, that restriction will apply only to named export declarations. -Examples of additional **incorrect** code for this rule: +Examples of additional **incorrect** code for the `"restrictedNamedExports": ["default"]` option: ::: incorrect @@ -110,7 +118,7 @@ export { default } from "some_module"; ::: -Examples of additional **correct** code for this rule: +Examples of additional **correct** code for the `"restrictedNamedExports": ["default"]` option: ::: correct @@ -122,6 +130,85 @@ export default function foo() {} ::: +### restrictDefaultExports + +This option allows you to restrict certain `default` declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. This option accepts the following properties: + +#### direct + +Examples of **incorrect** code for the `"restrictDefaultExports": { "direct": true }` option: + +::: incorrect + +```js +/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "direct": true } }]*/ + +export default foo; +export default 42; +export default function foo() {} +``` + +::: + +#### named + +Examples of **incorrect** code for the `"restrictDefaultExports": { "named": true }` option: + +::: incorrect + +```js +/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "named": true } }]*/ + +const foo = 123; + +export { foo as default }; +``` + +::: + +#### defaultFrom + +Examples of **incorrect** code for the `"restrictDefaultExports": { "defaultFrom": true }` option: + +::: incorrect + +```js +/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "defaultFrom": true } }]*/ + +export { default } from 'foo'; +export { default as default } from 'foo'; +``` + +::: + +#### namedFrom + +Examples of **incorrect** code for the `"restrictDefaultExports": { "namedFrom": true }` option: + +::: incorrect + +```js +/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "namedFrom": true } }]*/ + +export { foo as default } from 'foo'; +``` + +::: + +#### namespaceFrom + +Examples of **incorrect** code for the `"restrictDefaultExports": { "namespaceFrom": true }` option: + +::: incorrect + +```js +/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "namespaceFrom": true } }]*/ + +export * as default from 'foo'; +``` + +::: + ## Known Limitations This rule doesn't inspect the content of source modules in re-export declarations. In particular, if you are re-exporting everything from another module's export, that export may include a restricted name. This rule cannot detect such cases. diff --git a/docs/src/rules/space-before-function-paren.md b/docs/src/rules/space-before-function-paren.md index a8bb5be12db1..1948d903cf0e 100644 --- a/docs/src/rules/space-before-function-paren.md +++ b/docs/src/rules/space-before-function-paren.md @@ -2,8 +2,7 @@ title: space-before-function-paren rule_type: layout related_rules: -- space-after-keywords -- space-return-throw-case +- keyword-spacing --- diff --git a/docs/src/use/command-line-interface.md b/docs/src/use/command-line-interface.md index 04eb6a0805b1..9270e64fd333 100644 --- a/docs/src/use/command-line-interface.md +++ b/docs/src/use/command-line-interface.md @@ -1,9 +1,9 @@ --- -title: Command Line Interface +title: Command Line Interface Reference eleventyNavigation: key: command line interface - parent: user guide - title: Command Line Interface + parent: use eslint + title: Command Line Interface Reference order: 4 --- @@ -132,7 +132,7 @@ npx eslint --no-eslintrc file.js #### `-c`, `--config` -This option allows you to specify an additional configuration file for ESLint (see [Configuring ESLint](configure/) for more). +This option allows you to specify an additional configuration file for ESLint (see [Configure ESLint](configure/) for more). * **Argument Type**: String. Path to file. * **Multiple Arguments**: No diff --git a/docs/src/use/configure/configuration-files-new.md b/docs/src/use/configure/configuration-files-new.md index ce79525b7c5e..e9bc207566f0 100644 --- a/docs/src/use/configure/configuration-files-new.md +++ b/docs/src/use/configure/configuration-files-new.md @@ -2,7 +2,7 @@ title: Configuration Files (New) eleventyNavigation: key: configuration files - parent: configuring + parent: configure title: Configuration Files (New) order: 1 diff --git a/docs/src/use/configure/configuration-files.md b/docs/src/use/configure/configuration-files.md index 644bc5127f3c..f9c7aa341f3a 100644 --- a/docs/src/use/configure/configuration-files.md +++ b/docs/src/use/configure/configuration-files.md @@ -2,9 +2,9 @@ title: Configuration Files eleventyNavigation: key: configuration files - parent: configuring + parent: configure title: Configuration Files - order: 1 + order: 2 --- @@ -136,7 +136,7 @@ your-project └── test.js ``` -The configuration cascade works based on the location of the file being linted. If there is a `.eslintrc` file in the same directory as the file being linted, then that configuration takes precedence. ESLint then searches up the directory structure, merging any `.eslintrc` files it finds along the way until reaching either a `.eslintrc` file with `root: true` or the root directory. +The configuration cascade works based on the location of the file being linted. If there is an `.eslintrc` file in the same directory as the file being linted, then that configuration takes precedence. ESLint then searches up the directory structure, merging any `.eslintrc` files it finds along the way until reaching either an `.eslintrc` file with `root: true` or the root directory. In the same way, if there is a `package.json` file in the root directory with an `eslintConfig` field, the configuration it describes is applied to all subdirectories beneath it. However, the configuration described by the `.eslintrc` file in the `tests/` directory overrides conflicting specifications. @@ -150,7 +150,7 @@ your-project └── test.js ``` -If there is a `.eslintrc` and a `package.json` file found in the same directory, `.eslintrc` takes priority and the `package.json` file is not used. +If there is an `.eslintrc` and a `package.json` file found in the same directory, `.eslintrc` takes priority and the `package.json` file is not used. By default, ESLint looks for configuration files in all parent folders up to the root directory. This can be useful if you want all of your projects to follow a certain convention, but can sometimes lead to unexpected results. To limit ESLint to a specific project, place `"root": true` inside the `.eslintrc.*` file or `eslintConfig` field of the `package.json` file or in the `.eslintrc.*` file at your project's root level. ESLint stops looking in parent folders once it finds a configuration with `"root": true`. diff --git a/docs/src/use/configure/ignore.md b/docs/src/use/configure/ignore.md index 46852ef6135d..ac481547895b 100644 --- a/docs/src/use/configure/ignore.md +++ b/docs/src/use/configure/ignore.md @@ -1,10 +1,10 @@ --- -title: Ignoring Code +title: Ignore Files eleventyNavigation: - key: ignoring code - parent: configuring - title: Ignoring Code - order: 5 + key: ignore files + parent: configure + title: Ignore Files + order: 6 --- @@ -37,13 +37,13 @@ If a config is provided via the `--config` CLI option, the ignore patterns that ## The `.eslintignore` File -You can tell ESLint to ignore specific files and directories by creating a `.eslintignore` file in your project's root directory. The `.eslintignore` file is a plain text file where each line is a glob pattern indicating which paths should be omitted from linting. For example, the following omits all JavaScript files: +You can tell ESLint to ignore specific files and directories by creating an `.eslintignore` file in your project's root directory. The `.eslintignore` file is a plain text file where each line is a glob pattern indicating which paths should be omitted from linting. For example, the following omits all JavaScript files: ```text **/*.js ``` -When ESLint is run, it looks in the current working directory to find a `.eslintignore` file before determining which files to lint. If this file is found, then those preferences are applied when traversing directories. Only one `.eslintignore` file can be used at a time, so `.eslintignore` files other than the one in the current working directory are not used. +When ESLint is run, it looks in the current working directory to find an `.eslintignore` file before determining which files to lint. If this file is found, then those preferences are applied when traversing directories. Only one `.eslintignore` file can be used at a time, so `.eslintignore` files other than the one in the current working directory are not used. Globs are matched using [node-ignore](https://github.com/kaelzhang/node-ignore), so a number of features are available: diff --git a/docs/src/use/configure/index.md b/docs/src/use/configure/index.md index a00b927b54d8..05850e9f1d53 100644 --- a/docs/src/use/configure/index.md +++ b/docs/src/use/configure/index.md @@ -1,9 +1,9 @@ --- -title: Configuring ESLint +title: Configure ESLint eleventyNavigation: - key: configuring - parent: user guide - title: Configuring + key: configure + parent: use eslint + title: Configure ESLint order: 3 --- @@ -34,24 +34,24 @@ All of these options give you fine-grained control over how ESLint treats your c * [Configuration Based on Glob Patterns](./configuration-files#configuration-based-on-glob-patterns) * [Personal Configuration Files](./configuration-files#personal-configuration-files-deprecated) -[**Language Options**](language-options) +[**Configure Language Options**](language-options) * [Specifying Environments](./language-options#specifying-environments) * [Specifying Globals](./language-options#specifying-globals) * [Specifying Parser Options](./language-options#specifying-parser-options) -[**Rules**](rules) +[**Configure Rules**](rules) * [Configuring Rules](./rules#configuring-rules) * [Disabling Rules](./rules#disabling-rules) -[**Plugins**](plugins) +[**Configure Plugins**](plugins) -* [Configuring Plugins](./plugins#configure-plugins) -* [Specifying Processors](./plugins#specify-a-processor) -* [Configuring Parsers](./plugins#configure-a-parser) +* [Configure Plugins](./plugins#configure-plugins) +* [Specify a Processor](./plugins#specify-a-processor) +* [Configure Parsers](./plugins#configure-a-parser) -[**Ignoring Code**](ignore) +[**Ignore Files**](ignore) * [`ignorePatterns` in Config Files](./ignore#ignorepatterns-in-config-files) * [The `.eslintignore` File](./ignore#the-eslintignore-file) diff --git a/docs/src/use/configure/language-options.md b/docs/src/use/configure/language-options.md index 0e0f34fbafea..ef21c35d57e4 100644 --- a/docs/src/use/configure/language-options.md +++ b/docs/src/use/configure/language-options.md @@ -1,10 +1,10 @@ --- -title: Language Options +title: Configure Language Options eleventyNavigation: - key: configuring language options - parent: configuring - title: Configuring Language Options - order: 2 + key: configure language options + parent: configure + title: Configure Language Options + order: 3 --- diff --git a/docs/src/use/configure/plugins.md b/docs/src/use/configure/plugins.md index 5303625bdbd1..2c4706ff4768 100644 --- a/docs/src/use/configure/plugins.md +++ b/docs/src/use/configure/plugins.md @@ -1,10 +1,10 @@ --- -title: Plugins & Parsers +title: Configure Plugins & Parsers eleventyNavigation: - key: configuring plugins - parent: configuring - title: Configuring Plugins & Parsers - order: 4 + key: configure plugins + parent: configure + title: Configure Plugins & Parsers + order: 5 --- diff --git a/docs/src/use/configure/rules.md b/docs/src/use/configure/rules.md index 44e9076edf2a..fd661063fbb4 100644 --- a/docs/src/use/configure/rules.md +++ b/docs/src/use/configure/rules.md @@ -1,10 +1,10 @@ --- -title: Rules +title: Configure Rules eleventyNavigation: - key: configuring rules - parent: configuring - title: Configuring Rules - order: 3 + key: configure rules + parent: configure + title: Configure Rules + order: 4 --- diff --git a/docs/src/use/core-concepts.md b/docs/src/use/core-concepts.md index 93b0fb9fa821..b9dfbbbfa1c0 100644 --- a/docs/src/use/core-concepts.md +++ b/docs/src/use/core-concepts.md @@ -3,7 +3,7 @@ title: Core Concepts eleventyNavigation: key: core concepts title: Core Concepts - parent: user guide + parent: use eslint order: 2 --- @@ -43,7 +43,7 @@ An ESLint plugin is an npm module that can contain a set of ESLint rules, config A popular use case for plugins is to enforce best practices for a framework. For example, [@angular-eslint/eslint-plugin](https://www.npmjs.com/package/@angular-eslint/eslint-plugin) contains best practices for using the Angular framework. -For more information, refer to [Configuring Plugins](./configure/plugins). +For more information, refer to [Configure Plugins](./configure/plugins). ## Parsers diff --git a/docs/src/use/formatters/html-formatter-example.html b/docs/src/use/formatters/html-formatter-example.html index 0d567d1e84f2..0d820b894d5d 100644 --- a/docs/src/use/formatters/html-formatter-example.html +++ b/docs/src/use/formatters/html-formatter-example.html @@ -118,7 +118,7 @@

    ESLint Report

    - 9 problems (5 errors, 4 warnings) - Generated on Sat Jan 14 2023 23:14:23 GMT-0500 (Eastern Standard Time) + 9 problems (5 errors, 4 warnings) - Generated on Sat Jan 28 2023 18:25:23 GMT-0500 (Eastern Standard Time)
    diff --git a/docs/src/use/formatters/index.md b/docs/src/use/formatters/index.md index fe8d68d08efc..b5bb8be723d9 100644 --- a/docs/src/use/formatters/index.md +++ b/docs/src/use/formatters/index.md @@ -1,9 +1,9 @@ --- -title: Formatters +title: Formatters Reference eleventyNavigation: key: formatters - parent: user guide - title: Formatters + parent: use eslint + title: Formatters Reference order: 6 edit_link: https://github.com/eslint/eslint/edit/main/templates/formatter-examples.md.ejs --- diff --git a/docs/src/use/getting-started.md b/docs/src/use/getting-started.md index 31beeac3b67f..623011aaf486 100644 --- a/docs/src/use/getting-started.md +++ b/docs/src/use/getting-started.md @@ -2,7 +2,7 @@ title: Getting Started with ESLint eleventyNavigation: key: getting started - parent: user guide + parent: use eslint title: Getting Started order: 1 @@ -64,7 +64,7 @@ yarn run eslint yourfile.js **Note:** If you are coming from a version before 1.0.0 please see the [migration guide](migrating-to-1.0.0). -After running `npm init @eslint/config`, you'll have a `.eslintrc.{js,yml,json}` file in your directory. In it, you'll see some rules configured like this: +After running `npm init @eslint/config`, you'll have an `.eslintrc.{js,yml,json}` file in your directory. In it, you'll see some rules configured like this: ```json { @@ -116,7 +116,7 @@ Before you begin, you must already have a `package.json` file. If you don't, mak touch .eslintrc.js ``` -1. Add configuration to the `.eslintrc` file. Refer to the [Configuring ESLint documentation](configure/) to learn how to add rules, environments, custom configurations, plugins, and more. +1. Add configuration to the `.eslintrc` file. Refer to the [Configure ESLint documentation](configure/) to learn how to add rules, environments, custom configurations, plugins, and more. ```js // .eslintrc.js example diff --git a/docs/src/use/index.md b/docs/src/use/index.md index 5358b7240cf0..6e68a087f38b 100644 --- a/docs/src/use/index.md +++ b/docs/src/use/index.md @@ -1,32 +1,40 @@ --- -title: User Guide +title: Use ESLint in Your Project eleventyNavigation: - key: user guide - title: User Guide + key: use eslint + title: Use ESLint in Your Project order: 1 --- -This guide is intended for those who wish to use ESLint as an end-user. If you're looking for how to extend ESLint or work with the ESLint source code, please see the [Developer Guide](../extend/). +This guide is intended for those who wish to use ESLint as an end-user. If you're looking for how to extend ESLint or work with the ESLint source code, please see the [Extend ESLint documentation](../extend/). ## [Getting Started](getting-started) Want to skip ahead and just start using ESLint? This section gives a high-level overview of installation, setup, and configuration options. -## [Rules](../rules/) +## [Core Concepts](core-concepts) -ESLint has a lot of rules that you can configure to fine-tune it to your project. This section is an exhaustive list of every rule and link to each rule's documentation. +Understand the main components of ESLint and how to use them in your project. -## [Configuring](configure/) +## [Configure ESLint](configure/) Once you've got ESLint running, you'll probably want to adjust the configuration to better suit your project. This section explains all the different ways you can configure ESLint. -## [Command Line Interface](command-line-interface) +## [Command Line Interface Reference](command-line-interface) There are a lot of command line flags for ESLint and this section explains what they do. +## [Rules Reference](../rules/) + +ESLint has a lot of rules that you can configure to fine-tune it to your project. This section is an exhaustive list of every rule and link to each rule's documentation. + +## [Formatters Reference](formatters) + +Control the appearance of the linting results with formatters. View all built-in formatters on this page. + ## [Integrations](integrations) -Wondering if ESLint will work with your favorite editor or build system? This section has a list of all known integrations (submitted by their authors). +Wondering if ESLint will work with your favorite editor or build system? This page has a list of integrations (submitted by their authors). ## [Rule Deprecation](rule-deprecation) diff --git a/docs/src/use/integrations.md b/docs/src/use/integrations.md index 7de6e11b6419..892a5080e359 100644 --- a/docs/src/use/integrations.md +++ b/docs/src/use/integrations.md @@ -2,7 +2,7 @@ title: Integrations eleventyNavigation: key: integrations - parent: user guide + parent: use eslint title: Integrations order: 7 diff --git a/docs/src/use/migrate-to-8.0.0.md b/docs/src/use/migrate-to-8.0.0.md index fbc3b85c775d..71d92c52087a 100644 --- a/docs/src/use/migrate-to-8.0.0.md +++ b/docs/src/use/migrate-to-8.0.0.md @@ -1,9 +1,9 @@ --- -title: Migrating to v8.0.0 +title: Migrate to v8.0.0 eleventyNavigation: - key: migrating to v8 - parent: user guide - title: Migrating to v8.x + key: migrate to v8 + parent: use eslint + title: Migrate to v8.x order: 7 --- diff --git a/docs/src/use/migrating-from-jscs.md b/docs/src/use/migrating-from-jscs.md index cf213b4596ec..54b19683fedd 100644 --- a/docs/src/use/migrating-from-jscs.md +++ b/docs/src/use/migrating-from-jscs.md @@ -30,7 +30,7 @@ To convert your configuration file, pass in the location of your `.jscs.json` fi polyjuice --jscs .jscsrc.json > .eslintrc.json ``` -This creates a `.eslintrc.json` with the equivalent rules from `.jscsrc.json`. +This creates an `.eslintrc.json` with the equivalent rules from `.jscsrc.json`. If you have multiple `.jscsrc.json` files, you can pass them all and Polyjuice will combine them into one `.eslintrc.json` file: diff --git a/docs/src/use/migrating-to-3.0.0.md b/docs/src/use/migrating-to-3.0.0.md index b4aa4580e79b..289aa145a613 100644 --- a/docs/src/use/migrating-to-3.0.0.md +++ b/docs/src/use/migrating-to-3.0.0.md @@ -15,7 +15,7 @@ With ESLint v3.0.0, we are dropping support for Node.js versions prior to 4. Nod ESLint v3.0.0 now requires that you use a configuration to run. A configuration can be any of the following: -1. A `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml`, `.eslintrc.yaml`, or `.eslintrc` file either in your project or home directory. +1. An `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml`, `.eslintrc.yaml`, or `.eslintrc` file either in your project or home directory. 2. Configuration options passed on the command line using `--rule` (or to CLIEngine using `rules`). 3. A configuration file passed on the command line using `-c` (or to CLIEngine using `configFile`). 4. A base configuration is provided to CLIEngine using the `baseConfig` option. diff --git a/docs/src/use/migrating-to-7.0.0.md b/docs/src/use/migrating-to-7.0.0.md index 80fad67a0258..898bcad11a3f 100644 --- a/docs/src/use/migrating-to-7.0.0.md +++ b/docs/src/use/migrating-to-7.0.0.md @@ -108,7 +108,7 @@ Personal config files have been deprecated since [v6.7.0](https://eslint.org/blo 1. When a project does not have a configuration file present and ESLint loads configuration from `~/.eslintrc.*`. 1. When a project has a configuration file and ESLint ignored a `~/.eslintrc.*` configuration file. This occurs when the `$HOME` directory is an ancestor directory of the project and the project's configuration files doesn't contain `root:true`. -**To address:** Remove `~/.eslintrc.*` configuration files and add a `.eslintrc.*` configuration file to your project. Alternatively, use the `--config` option to use shared config files. +**To address:** Remove `~/.eslintrc.*` configuration files and add an `.eslintrc.*` configuration file to your project. Alternatively, use the `--config` option to use shared config files. **Related issue(s):** [RFC32](https://github.com/eslint/rfcs/tree/master/designs/2019-deprecating-personal-config/README.md), [#12678](https://github.com/eslint/eslint/pull/12678) diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js index d99e8928209b..d201e3b03a69 100644 --- a/lib/rules/no-restricted-exports.js +++ b/lib/rules/no-restricted-exports.js @@ -27,27 +27,78 @@ module.exports = { }, schema: [{ - type: "object", - properties: { - restrictedNamedExports: { - type: "array", - items: { - type: "string" + anyOf: [ + { + type: "object", + properties: { + restrictedNamedExports: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + } }, - uniqueItems: true + additionalProperties: false + }, + { + type: "object", + properties: { + restrictedNamedExports: { + type: "array", + items: { + type: "string", + pattern: "^(?!default$)" + }, + uniqueItems: true + }, + restrictDefaultExports: { + type: "object", + properties: { + + // Allow/Disallow `export default foo; export default 42; export default function foo() {}` format + direct: { + type: "boolean" + }, + + // Allow/Disallow `export { foo as default };` declarations + named: { + type: "boolean" + }, + + // Allow/Disallow `export { default } from "mod"; export { default as default } from "mod";` declarations + defaultFrom: { + type: "boolean" + }, + + // Allow/Disallow `export { foo as default } from "mod";` declarations + namedFrom: { + type: "boolean" + }, + + // Allow/Disallow `export * as default from "mod"`; declarations + namespaceFrom: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false } - }, - additionalProperties: false + ] }], messages: { - restrictedNamed: "'{{name}}' is restricted from being used as an exported name." + restrictedNamed: "'{{name}}' is restricted from being used as an exported name.", + restrictedDefault: "Exporting 'default' is restricted." } }, create(context) { const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports); + const restrictDefaultExports = context.options[0] && context.options[0].restrictDefaultExports; /** * Checks and reports given exported name. @@ -63,6 +114,42 @@ module.exports = { messageId: "restrictedNamed", data: { name } }); + return; + } + + if (name === "default") { + if (node.parent.type === "ExportAllDeclaration") { + if (restrictDefaultExports && restrictDefaultExports.namespaceFrom) { + context.report({ + node, + messageId: "restrictedDefault" + }); + } + + } else { // ExportSpecifier + const isSourceSpecified = !!node.parent.parent.source; + const specifierLocalName = astUtils.getModuleExportName(node.parent.local); + + if (!isSourceSpecified && restrictDefaultExports && restrictDefaultExports.named) { + context.report({ + node, + messageId: "restrictedDefault" + }); + return; + } + + if (isSourceSpecified && restrictDefaultExports) { + if ( + (specifierLocalName === "default" && restrictDefaultExports.defaultFrom) || + (specifierLocalName !== "default" && restrictDefaultExports.namedFrom) + ) { + context.report({ + node, + messageId: "restrictedDefault" + }); + } + } + } } } @@ -73,6 +160,15 @@ module.exports = { } }, + ExportDefaultDeclaration(node) { + if (restrictDefaultExports && restrictDefaultExports.direct) { + context.report({ + node, + messageId: "restrictedDefault" + }); + } + }, + ExportNamedDeclaration(node) { const declaration = node.declaration; diff --git a/package.json b/package.json index 1cd7ea195bfb..913fba605202 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint", - "version": "8.32.0", + "version": "8.33.0", "author": "Nicholas C. Zakas ", "description": "An AST-based pattern checker for JavaScript.", "bin": { diff --git a/packages/eslint-config-eslint/README.md b/packages/eslint-config-eslint/README.md index d12b24a8fed4..a44f991b77dd 100644 --- a/packages/eslint-config-eslint/README.md +++ b/packages/eslint-config-eslint/README.md @@ -2,7 +2,7 @@ # ESLint Configuration -[Website](https://eslint.org) | [Configuring](https://eslint.org/docs/latest/use/configure) | [Rules](https://eslint.org/docs/rules/) | [Contributing](https://eslint.org/docs/latest/contribute) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint) | [Chatroom](https://eslint.org/chat) +[Website](https://eslint.org) | [Configure ESLint](https://eslint.org/docs/latest/use/configure) | [Rules](https://eslint.org/docs/rules/) | [Contributing](https://eslint.org/docs/latest/contribute) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint) | [Chatroom](https://eslint.org/chat) Contains the ESLint configuration used for projects maintained by the ESLint team. diff --git a/templates/formatter-examples.md.ejs b/templates/formatter-examples.md.ejs index 8bd8bfb2b64d..20f46f2d5aa3 100644 --- a/templates/formatter-examples.md.ejs +++ b/templates/formatter-examples.md.ejs @@ -1,9 +1,9 @@ --- -title: Formatters +title: Formatters Reference eleventyNavigation: key: formatters - parent: user guide - title: Formatters + parent: use eslint + title: Formatters Reference order: 6 edit_link: https://github.com/eslint/eslint/edit/main/templates/formatter-examples.md.ejs --- diff --git a/tests/lib/cli-engine/cli-engine.js b/tests/lib/cli-engine/cli-engine.js index df3b6719f4c5..03dff9bb3d76 100644 --- a/tests/lib/cli-engine/cli-engine.js +++ b/tests/lib/cli-engine/cli-engine.js @@ -4433,7 +4433,7 @@ describe("CLIEngine", () => { const cwd = getFixturePath("ignored-paths", "configurations"); const engine = new CLIEngine({ cwd }); - // a .eslintignore in parent directories includes `*.js`, but don't load it. + // an .eslintignore in parent directories includes `*.js`, but don't load it. assert(!engine.isPathIgnored("foo.js")); assert(engine.isPathIgnored("node_modules/foo.js")); }); @@ -4593,7 +4593,7 @@ describe("CLIEngine", () => { const cwd = getFixturePath("ignored-paths", "no-ignore-file"); const engine = new CLIEngine({ ignorePath: false, cwd }); - // a .eslintignore in parent directories includes `*.js`, but don't load it. + // an .eslintignore in parent directories includes `*.js`, but don't load it. assert(!engine.isPathIgnored("foo.js")); assert(engine.isPathIgnored("node_modules/foo.js")); }); diff --git a/tests/lib/eslint/eslint.js b/tests/lib/eslint/eslint.js index 112f0c85ae8f..aa30047edc28 100644 --- a/tests/lib/eslint/eslint.js +++ b/tests/lib/eslint/eslint.js @@ -4400,7 +4400,7 @@ describe("ESLint", () => { const cwd = getFixturePath("ignored-paths", "configurations"); const engine = new ESLint({ cwd }); - // a .eslintignore in parent directories includes `*.js`, but don't load it. + // an .eslintignore in parent directories includes `*.js`, but don't load it. assert(!await engine.isPathIgnored("foo.js")); assert(await engine.isPathIgnored("node_modules/foo.js")); }); diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index 631fd6f02fa3..9505e8ff6c35 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -107,7 +107,31 @@ ruleTester.run("no-restricted-exports", rule, { { code: "export default 1;", options: [{ restrictedNamedExports: ["default"] }] }, // "default" does not disallow re-exporting a renamed default export from another module - { code: "export { default as a } from 'foo';", options: [{ restrictedNamedExports: ["default"] }] } + { code: "export { default as a } from 'foo';", options: [{ restrictedNamedExports: ["default"] }] }, + + // restrictDefaultExports.direct option + { code: "export default foo;", options: [{ restrictDefaultExports: { direct: false } }] }, + { code: "export default 42;", options: [{ restrictDefaultExports: { direct: false } }] }, + { code: "export default function foo() {}", options: [{ restrictDefaultExports: { direct: false } }] }, + + // restrictDefaultExports.named option + { code: "const foo = 123;\nexport { foo as default };", options: [{ restrictDefaultExports: { named: false } }] }, + + // restrictDefaultExports.defaultFrom option + { code: "export { default } from 'mod';", options: [{ restrictDefaultExports: { defaultFrom: false } }] }, + { code: "export { default as default } from 'mod';", options: [{ restrictDefaultExports: { defaultFrom: false } }] }, + { code: "export { foo as default } from 'mod';", options: [{ restrictDefaultExports: { defaultFrom: true } }] }, + { code: "export { default } from 'mod';", options: [{ restrictDefaultExports: { named: true, defaultFrom: false } }] }, + { code: "export { 'default' } from 'mod'; ", options: [{ restrictDefaultExports: { defaultFrom: false } }] }, + + // restrictDefaultExports.namedFrom option + { code: "export { foo as default } from 'mod';", options: [{ restrictDefaultExports: { namedFrom: false } }] }, + { code: "export { default as default } from 'mod';", options: [{ restrictDefaultExports: { namedFrom: true } }] }, + { code: "export { default as default } from 'mod';", options: [{ restrictDefaultExports: { namedFrom: false } }] }, + { code: "export { 'default' } from 'mod'; ", options: [{ restrictDefaultExports: { defaultFrom: false, namedFrom: true } }] }, + + // restrictDefaultExports.namespaceFrom option + { code: "export * as default from 'mod';", options: [{ restrictDefaultExports: { namespaceFrom: false } }] } ], invalid: [ @@ -519,6 +543,66 @@ ruleTester.run("no-restricted-exports", rule, { code: "export { default } from 'foo';", options: [{ restrictedNamedExports: ["default"] }], errors: [{ messageId: "restrictedNamed", data: { name: "default" }, type: "Identifier", column: 10 }] + }, + + // restrictDefaultExports.direct option + { + code: "export default foo;", + options: [{ restrictDefaultExports: { direct: true } }], + errors: [{ messageId: "restrictedDefault", type: "ExportDefaultDeclaration", column: 1 }] + }, + { + code: "export default 42;", + options: [{ restrictDefaultExports: { direct: true } }], + errors: [{ messageId: "restrictedDefault", type: "ExportDefaultDeclaration", column: 1 }] + }, + { + code: "export default function foo() {}", + options: [{ restrictDefaultExports: { direct: true } }], + errors: [{ messageId: "restrictedDefault", type: "ExportDefaultDeclaration", column: 1 }] + }, + { + code: "export default foo;", + options: [{ restrictedNamedExports: ["bar"], restrictDefaultExports: { direct: true } }], + errors: [{ messageId: "restrictedDefault", type: "ExportDefaultDeclaration", column: 1 }] + }, + + // restrictDefaultExports.named option + { + code: "const foo = 123;\nexport { foo as default };", + options: [{ restrictDefaultExports: { named: true } }], + errors: [{ messageId: "restrictedDefault", type: "Identifier", line: 2, column: 17 }] + }, + + // restrictDefaultExports.defaultFrom option + { + code: "export { default } from 'mod';", + options: [{ restrictDefaultExports: { defaultFrom: true } }], + errors: [{ messageId: "restrictedDefault", type: "Identifier", line: 1, column: 10 }] + }, + { + code: "export { default as default } from 'mod';", + options: [{ restrictDefaultExports: { defaultFrom: true } }], + errors: [{ messageId: "restrictedDefault", type: "Identifier", line: 1, column: 21 }] + }, + { + code: "export { 'default' } from 'mod';", + options: [{ restrictDefaultExports: { defaultFrom: true } }], + errors: [{ messageId: "restrictedDefault", type: "Literal", line: 1, column: 10 }] + }, + + // restrictDefaultExports.namedFrom option + { + code: "export { foo as default } from 'mod';", + options: [{ restrictDefaultExports: { namedFrom: true } }], + errors: [{ messageId: "restrictedDefault", type: "Identifier", line: 1, column: 17 }] + }, + + // restrictDefaultExports.namespaceFrom option + { + code: "export * as default from 'mod';", + options: [{ restrictDefaultExports: { namespaceFrom: true } }], + errors: [{ messageId: "restrictedDefault", type: "Identifier", line: 1, column: 13 }] } ] });