Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: import-js/eslint-plugin-import
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: eddcfa9ff0affe64eff61cf749fef95e46d38b50
Choose a base ref
...
head repository: import-js/eslint-plugin-import
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5ff9e45d585c5aac396802288aa9a8d93b0a09c6
Choose a head ref

Commits on Apr 16, 2019

  1. [fix] no-unused-modules: make appveyor tests passing

    Fixes #1317.
    rfermann authored and ljharb committed Apr 16, 2019

    Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    12bbfca View commit details

Commits on Apr 21, 2019

  1. Copy the full SHA
    174afbb View commit details

Commits on Apr 23, 2019

  1. Copy the full SHA
    1db357e View commit details

Commits on Apr 24, 2019

  1. Copy the full SHA
    fbe5c30 View commit details
  2. Merge pull request #1342 from rfermann/1339

    [fix] `no-unused-modules`: make `import { name as otherName }` work
    ljharb authored Apr 24, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c17dd73 View commit details

Commits on Apr 25, 2019

  1. Copy the full SHA
    4620185 View commit details

Commits on Apr 27, 2019

  1. Copy the full SHA
    bb686de View commit details
  2. Merge pull request #1347 from rfermann/1338

    [fix] `no-unused-modules`: don't crash when lint file outside src-folder
    ljharb authored Apr 27, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f63dd26 View commit details

Commits on May 1, 2019

  1. [Docs] no-unused-modules: Indicates usage, plugin defaults to no-op…

    …, and add description to main README.md
    
    Fixes #1351
    johndevedu authored and ljharb committed May 1, 2019

    Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    2f85fbe View commit details

Commits on May 5, 2019

  1. Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    1edbbd0 View commit details

Commits on May 11, 2019

  1. Copy the full SHA
    aa290bb View commit details

Commits on May 12, 2019

  1. Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    7c13a4f View commit details
  2. Make groups non-capturing.

    Co-Authored-By: Jordan Harband <ljharb@gmail.com>
    christophercurrie and ljharb authored May 12, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    288cedf View commit details
  3. Copy the full SHA
    67b1e95 View commit details

Commits on May 13, 2019

  1. Copy the full SHA
    d1e4455 View commit details
  2. Remove log messages

    christophercurrie committed May 13, 2019
    Copy the full SHA
    f66e064 View commit details
  3. PR feedback

    Co-Authored-By: Jordan Harband <ljharb@gmail.com>
    christophercurrie and ljharb authored May 13, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7aa13d1 View commit details
  4. PR feedback

    Co-Authored-By: Jordan Harband <ljharb@gmail.com>
    christophercurrie and ljharb authored May 13, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b52bf3e View commit details

Commits on May 15, 2019

  1. Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    753c9db View commit details
  2. Issue #1258 (docs)

    Document `env` option for `eslint-import-resolver-webpack`
    kgregory committed May 15, 2019
    Copy the full SHA
    c09c0ce View commit details

Commits on May 16, 2019

  1. [Docs] Document env option for eslint-import-resolver-webpack

    Merge pull request #1363 from kgregory/webpack-resolver-doc-env
    
    Fixes #1258.
    ljharb authored May 16, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c8ac7ff View commit details

Commits on May 23, 2019

  1. Merge pull request #1356 from christophercurrie/typescript-declare

    Improve support for Typescript declare structures
    ljharb authored May 23, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    17beb33 View commit details
  2. [Deps] update resolve

    ljharb committed May 23, 2019

    Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    557a3e2 View commit details
  3. Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    caae65c View commit details

Commits on May 24, 2019

  1. Bump to v2.17.3

    ljharb committed May 24, 2019

    Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    cf5573b View commit details

Commits on May 28, 2019

  1. Update no-cycle.md

    Alex Page authored May 28, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d27aeaf View commit details
  2. Merge pull request #1370 from alex-page/master

    Docs: no cycle, split code examples so file separation is obvious
    ljharb authored May 28, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ca4bf95 View commit details

Commits on May 29, 2019

  1. Copy the full SHA
    8b55e8f View commit details
  2. Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    15e5c61 View commit details

Commits on May 30, 2019

  1. Merge pull request #1371 from golopot/no-unused-modules-handles-class

    [fix] `no-unused-modules`: handle ClassDeclaration
    ljharb authored May 30, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0e719c3 View commit details

Commits on Jun 3, 2019

  1. add TS def extensions + defer to TS over JS

    closes #1366, thanks @davidNHK for bringing this up
    benmosher authored Jun 3, 2019
    4

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e4334e3 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9a0455e View commit details

Commits on Jun 6, 2019

  1. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    e1c5054 View commit details
  2. Added changelog entry

    swernerx committed Jun 6, 2019

    Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    4827e72 View commit details

Commits on Jun 11, 2019

  1. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    d81a5c8 View commit details
  2. Merge pull request #1375 from swernerx/fix/order-unknown-types

    [New] Added support for correctly ordering `unknown` types e.g. custom aliases
    ljharb authored Jun 11, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    45bfe47 View commit details

Commits on Jun 17, 2019

  1. [Build] make node 12 pass CI

    golopot committed Jun 17, 2019
    Copy the full SHA
    8974346 View commit details
  2. Merge pull request #1383 from golopot/node-12

    [Build] make node 12 pass CI
    ljharb authored Jun 17, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    58b41c2 View commit details

Commits on Jun 21, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4140870 View commit details

Commits on Jun 22, 2019

  1. Merge pull request #1389 from fooloomanzoo/patch-1

    Update no-named-as-default-member.md
    ljharb authored Jun 22, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    fc65509 View commit details

Commits on Jun 23, 2019

  1. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    b5ff64e View commit details
  2. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    1029b4f View commit details
  3. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    e6ea127 View commit details
  4. Allow ESLint@6

    sheepsteak committed Jun 23, 2019

    Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    2f1f4da View commit details
  5. Update to @typescript-eslint/parser canary

    Includes fixes for the use of `eslint/lib/util/traverser` that is now removed in ESLint 6
    
    Co-Authored-By: golopot <golopot@gmail.com>
    sheepsteak and golopot committed Jun 23, 2019

    Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    c2b19d0 View commit details
  6. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    d9b7258 View commit details
  7. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    3bee716 View commit details
  8. Remove ESLint 6 from allowed failures in Travis

    It's now supported
    sheepsteak committed Jun 23, 2019

    Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    d7023f6 View commit details
  9. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    7e41d29 View commit details

Commits on Jun 24, 2019

  1. Merge pull request #1393 from sheepsteak/eslint-6

    Support ESLint v6
    ljharb authored Jun 24, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c8132f2 View commit details
Showing 486 changed files with 23,765 additions and 6,750 deletions.
13 changes: 11 additions & 2 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
{
"presets": [ "es2015-argon" ],
"presets": ["airbnb"],
"sourceMaps": "inline",
"retainLines": true,
"env": {
"test": {
"plugins": [ "istanbul" ]
"plugins": [
"istanbul",
["module-resolver", { "root": ["./src/"] }],
]
},
"testCompiled": {
"plugins": [
["module-resolver", { "root": ["./lib/"] }],
]
}
}
}
2 changes: 1 addition & 1 deletion .coveralls.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
repo_token: fW3moW39Z8pKOgqTnUMT68DnNCd2SM8Ly
repo_token: fW3moW39Z8pKOgqTnUMT68DnNCd2SM8Ly
12 changes: 12 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
lib
coverage
.nyc_output
node_modules
tests/files/malformed.js
tests/files/with-syntax-error
tests/files/just-json-files/invalid.json
tests/files/typescript-d-ts/
resolvers/webpack/test/files
# we want to ignore "tests/files" here, but unfortunately doing so would
# interfere with unit test and fail it for some reason.
# tests/files
160 changes: 160 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
{
"root": true,
"plugins": [
"eslint-plugin",
"import",
],
"extends": [
"eslint:recommended",
"plugin:eslint-plugin/recommended",
"plugin:import/recommended",
],
"env": {
"node": true,
"es6": true,
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2020,
},
"rules": {
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "always-multiline",
}],
"comma-style": [2, "last"],
"curly": [2, "multi-line"],
"eol-last": [2, "always"],
"eqeqeq": [2, "allow-null"],
"func-call-spacing": 2,
"indent": [2, 2],
"keyword-spacing": ["error", {
"before": true,
"after": true,
"overrides": {
"return": { "after": true },
"throw": { "after": true },
"case": { "after": true }
}
}],
"max-len": 0,
"no-cond-assign": [2, "always"],
"no-return-assign": [2, "always"],
"no-var": 2,
"object-curly-spacing": [2, "always"],
"object-shorthand": ["error", "always", {
"ignoreConstructors": false,
"avoidQuotes": true,
}],
"one-var": [2, "never"],
"prefer-const": 2,
"quotes": [2, "single", {
"allowTemplateLiterals": true,
"avoidEscape": true,
}],
"semi": [2, "always"],
"space-before-function-paren": ["error", {
"anonymous": "always",
"named": "never",
"asyncArrow": "always",
}],

"eslint-plugin/consistent-output": [
"error",
"always",
],
"eslint-plugin/meta-property-ordering": "error",
"eslint-plugin/no-deprecated-context-methods": "error",
"eslint-plugin/no-deprecated-report-api": "off",
"eslint-plugin/prefer-replace-text": "error",
"eslint-plugin/report-message-format": "error",
"eslint-plugin/require-meta-docs-description": ["error", { "pattern": "^(Enforce|Ensure|Prefer|Forbid).+\\.$" }],
"eslint-plugin/require-meta-schema": "error",
"eslint-plugin/require-meta-type": "error",

// dog fooding
"import/no-extraneous-dependencies": ["error", {
"devDependencies": [
"tests/**",
"resolvers/*/test/**",
"scripts/**"
],
"optionalDependencies": false,
"peerDependencies": true,
"bundledDependencies": false,
}],
"import/unambiguous": "off",
},

"settings": {
"import/resolver": {
"node": {
"paths": [
"src",
],
},
},
},

"overrides": [
{
"files": "scripts/**",
"rules": {
"no-console": "off",
},
},
{
"files": "resolvers/**",
"env": {
"es6": false,
},
},
{
"files": "resolvers/webpack/**",
"rules": {
"no-console": 1,
},
"env": {
"es6": true,
},
},
{
"files": [
"resolvers/*/test/**/*",
],
"env": {
"mocha": true,
"es6": false
},
},
{
"files": "utils/**",
"parserOptions": {
"ecmaVersion": 6,
},
"rules": {
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "never"
}],
"no-console": 1,
},
},
{
"files": "tests/**",
"env": {
"mocha": true,
},
"rules": {
"max-len": 0,
"import/default": 0,
},
},
],
}
35 changes: 0 additions & 35 deletions .eslintrc.yml

This file was deleted.

12 changes: 12 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# These are supported funding model platforms

github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: eslint-plugin-import # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/eslint-plugin-import
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
123 changes: 123 additions & 0 deletions .github/workflows/node-4+.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: 'Tests: node.js'

on: [pull_request, push]

permissions:
contents: read

jobs:
matrix:
runs-on: ubuntu-latest
outputs:
latest: ${{ steps.set-matrix.outputs.requireds }}
minors: ${{ steps.set-matrix.outputs.optionals }}
steps:
- uses: ljharb/actions/node/matrix@main
id: set-matrix
with:
versionsAsRoot: true
type: majors
preset: '>= 6' # preset: '>=4' # see https://github.com/import-js/eslint-plugin-import/issues/2053

latest:
needs: [matrix]
name: 'majors'
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
eslint:
- 8
- 7
- 6
- 5
- 4
- 3
- 2
include:
- node-version: 'lts/*'
eslint: 7
ts-parser: 4
env:
TS_PARSER: 4
- node-version: 'lts/*'
eslint: 7
ts-parser: 3
env:
TS_PARSER: 3
- node-version: 'lts/*'
eslint: 7
ts-parser: 2
env:
TS_PARSER: 2
exclude:
- node-version: 15
eslint: 8
- node-version: 13
eslint: 8
- node-version: 11
eslint: 8
- node-version: 10
eslint: 8
- node-version: 9
eslint: 8
- node-version: 9
eslint: 7
- node-version: 8
eslint: 8
- node-version: 8
eslint: 7
- node-version: 7
eslint: 8
- node-version: 7
eslint: 7
- node-version: 7
eslint: 6
- node-version: 6
eslint: 8
- node-version: 6
eslint: 7
- node-version: 6
eslint: 6
- node-version: 5
eslint: 8
- node-version: 5
eslint: 7
- node-version: 5
eslint: 6
- node-version: 5
eslint: 5
- node-version: 4
eslint: 8
- node-version: 4
eslint: 7
- node-version: 4
eslint: 6
- node-version: 4
eslint: 5

steps:
- uses: actions/checkout@v3
- uses: ljharb/actions/node/install@main
continue-on-error: ${{ matrix.eslint == 4 && matrix.node-version == 4 }}
name: 'nvm install ${{ matrix.node-version }} && npm install, with eslint ${{ matrix.eslint }}'
env:
NPM_CONFIG_LEGACY_PEER_DEPS: ${{ matrix.node-version == 11 && false || true }}
ESLINT_VERSION: ${{ matrix.eslint }}
TRAVIS_NODE_VERSION: ${{ matrix.node-version }}
with:
node-version: ${{ matrix.node-version }}
after_install: npm run copy-metafiles && ./tests/dep-time-travel.sh
skip-ls-check: true
- run: npm run pretest
- run: npm run tests-only
- uses: codecov/codecov-action@v3

node:
name: 'node 4+'
needs: [latest]
runs-on: ubuntu-latest
steps:
- run: 'echo tests completed'
31 changes: 31 additions & 0 deletions .github/workflows/node-pretest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: 'Tests: pretest/posttest'

on: [pull_request, push]

permissions:
contents: read

jobs:
# pretest:
# runs-on: ubuntu-latest

# steps:
# - uses: actions/checkout@v3
# - uses: ljharb/actions/node/install@main
# name: 'nvm install lts/* && npm install'
# with:
# node-version: 'lts/*'
# skip-ls-check: true
# - run: npm run pretest

posttest:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: ljharb/actions/node/install@main
name: 'nvm install lts/* && npm install'
with:
node-version: 'lts/*'
skip-ls-check: true
- run: npm run posttest
60 changes: 60 additions & 0 deletions .github/workflows/packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: 'Tests: packages'

on: [pull_request, push]

permissions:
contents: read

jobs:
matrix:
runs-on: ubuntu-latest
outputs:
latest: ${{ steps.set-matrix.outputs.requireds }}
minors: ${{ steps.set-matrix.outputs.optionals }}
steps:
- uses: ljharb/actions/node/matrix@main
id: set-matrix
with:
type: 'majors'
preset: '>= 6' # preset: '>=4' # see https://github.com/import-js/eslint-plugin-import/issues/2053
versionsAsRoot: true

tests:
needs: [matrix]
name: 'packages'
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
eslint:
- 8
- 7
package:
- resolvers/node
- resolvers/webpack
# - memo-parser
# - utils

steps:
- uses: actions/checkout@v3
- uses: ljharb/actions/node/install@main
name: 'nvm install ${{ matrix.node-version }} && npm install'
env:
NPM_CONFIG_LEGACY_PEER_DEPS: ${{ matrix.node-version == 11 && false || true }}
ESLINT_VERSION: ${{ matrix.eslint }}
TRAVIS_NODE_VERSION: ${{ matrix.node-version }}
with:
node-version: ${{ matrix.node-version }}
after_install: npm run copy-metafiles && ./tests/dep-time-travel.sh && cd ${{ matrix.package }} && npm install
skip-ls-check: true
- run: cd ${{ matrix.package }} && npm run tests-only
- uses: codecov/codecov-action@v3

packages:
name: 'packages: all tests'
needs: [tests]
runs-on: ubuntu-latest
steps:
- run: 'echo tests completed'
9 changes: 9 additions & 0 deletions .github/workflows/rebase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: Automatic Rebase

on: [pull_request_target]

jobs:
_:
uses: ljharb/actions/.github/workflows/rebase.yml@main
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
17 changes: 17 additions & 0 deletions .github/workflows/require-allow-edits.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Require “Allow Edits”

on: [pull_request_target]

permissions:
contents: read

jobs:
_:
permissions:
pull-requests: read # for ljharb/require-allow-edits to check 'allow edits' on PR
name: "Require “Allow Edits”"

runs-on: ubuntu-latest

steps:
- uses: ljharb/require-allow-edits@main
21 changes: 19 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -13,12 +13,26 @@ lib-cov
# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Compiled binary addons (http://nodejs.org/api/addons.html)
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Copied from ./LICENSE for the npm module releases
memo-parser/LICENSE
resolvers/node/LICENSE
resolvers/webpack/LICENSE
utils/LICENSE
memo-parser/.npmrc
memo-parser/.nycrc
resolvers/node/.npmrc
resolvers/node/.nycrc
resolvers/webpack/.npmrc
resolvers/webpack/.nycrc
utils/.npmrc
utils/.nycrc

# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
@@ -39,3 +53,6 @@ lib/
yarn.lock
package-lock.json
npm-shrinkwrap.json

# macOS
.DS_Store
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
package-lock=false
install-links=false
19 changes: 19 additions & 0 deletions .nycrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "lcov", "text", "html", "json"],
"require": [
"babel-register"
],
"sourceMap": true,
"instrument": false,
"exclude": [
"coverage",
"test",
"tests",
"resolvers/*/test",
"scripts",
"memo-parser",
"lib"
]
}
55 changes: 13 additions & 42 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,14 @@
language: node_js
node_js:
- '10'
- '8'
- '6'
- '4'

os: linux

env:
- ESLINT_VERSION=5
- ESLINT_VERSION=4
- ESLINT_VERSION=3
- ESLINT_VERSION=2

# osx backlog is often deep, so to be polite we can just hit these highlights
matrix:
include:
- env: PACKAGE=resolvers/node
node_js: 10
- env: PACKAGE=resolvers/node
node_js: 8
- env: PACKAGE=resolvers/node
node_js: 6
- env: PACKAGE=resolvers/node
node_js: 4
- env: PACKAGE=resolvers/webpack
node_js: 10
- env: PACKAGE=resolvers/webpack
node_js: 8
- env: PACKAGE=resolvers/webpack
node_js: 6
- env: PACKAGE=resolvers/webpack
node_js: 4

- os: osx
env: ESLINT_VERSION=5
node_js: 14
- os: osx
env: ESLINT_VERSION=5
node_js: 12
- os: osx
env: ESLINT_VERSION=5
node_js: 10
@@ -46,25 +22,20 @@ matrix:
env: ESLINT_VERSION=2
node_js: 4

exclude:
- node_js: '4'
env: ESLINT_VERSION=5

fast_finish: true
allow_failures:
# issues with typescript deps in this version intersection
- node_js: '4'
env: ESLINT_VERSION=4

before_install:
- 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash && . $NVM_DIR/nvm.sh'
- 'nvm install-latest-npm'
- 'if [ -n "${PACKAGE-}" ]; then cd "${PACKAGE}"; fi'
- 'NPM_CONFIG_LEGACY_PEER_DEPS=true npm install'
- 'npm run copy-metafiles'
install:
- npm install
- 'NPM_CONFIG_LEGACY_PEER_DEPS=true npm install'
- 'if [ -n "${ESLINT_VERSION}" ]; then ./tests/dep-time-travel.sh; fi'
- 'npm run pretest'

script:
- 'npm test'
- npm run tests-only

after_success:
- npm run coveralls
- bash <(curl -Os https://uploader.codecov.io/latest/linux/codecov)
1,657 changes: 1,305 additions & 352 deletions CHANGELOG.md

Large diffs are not rendered by default.

98 changes: 33 additions & 65 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,84 @@
# Contributing

Thanks for your interest in helping out! Here are a **few** _weird_ tricks to
~~cut your mortgage in half~~ maximize the global net efficiency of your efforts!
Thanks for your interest in helping out! Here are a **few** _weird_ tricks to ~~cut your mortgage in half~~ maximize the global net efficiency of your efforts!

## TL;DR: Checklist

When opening an [issue](#issues):

- [ ] search open/closed issues
- [ ] discuss bug/enhancement in new or old issue

[PR](#prs) time:

- [ ] write tests
- [ ] implement feature/fix bug
- [ ] update docs
- [ ] make a note in change log

Remember, you don't need to do it all yourself; any of these are helpful! 😎

## How to get started

If you are new to `eslint`, below are a few resources that will help you to familiarize yourself with the project.

- Watch [this presentation](https://www.youtube.com/watch?v=2W9tUnALrLg) to learn the fundamental concept of Abstract Syntax Trees (AST) and the way `eslint` works under the hood.
- Familiarize yourself with the [AST explorer](https://astexplorer.net/) tool. Look into rules in `docs/rules`, create patterns in the rules, then analyze its AST.
- Explore the blog posts on how to create a custom rule. [One blog post](https://blog.yonatan.dev/writing-a-custom-eslint-rule-to-spot-undeclared-props/). [Second blog post](https://betterprogramming.pub/creating-custom-eslint-rules-cdc579694608).
- Read the official `eslint` [developer guide](https://eslint.org/docs/latest/developer-guide/architecture/).

## Issues

### Search open + closed issues for similar cases.
### Search open + closed issues for similar cases

You may find an open issue that closely matches what you are thinking. You
may also find a closed issue with discussion that either solves your problem
or explains why we are unlikely to solve it in the near future.
You may find an open issue that closely matches what you are thinking. You may also find a closed issue with discussion that either solves your problem or explains why we are unlikely to solve it in the near future.

If you find a matching issue that is open, and marked `accepted` and/or `help
wanted`, you might want to [open a PR](#prs).
If you find a matching issue that is open, and marked `accepted` and/or `help wanted`, you might want to [open a PR](#prs).

### Open an issue.
### Open an issue

Let's discuss your issue. Could be as simple as unclear documentation or a
wonky config file.
If you're suggesting a feature, it might exist and need better
documentation, or it might be in process. Even given those, some discussion might
be warranted to ensure the enhancement is clear.
Let's discuss your issue. Could be as simple as unclear documentation or a wonky config file.
If you're suggesting a feature, it might exist and need better documentation, or it might be in process. Even given those, some discussion might be warranted to ensure the enhancement is clear.

You're welcome to jump right to a PR, but without a discussion, can't make any
guarantees about merging.
You're welcome to jump right to a PR, but without a discussion, can't make any guarantees about merging.

That said: sometimes seeing the code makes the discussion clearer.😄

This is a helpful contribution all by itself. Thanks!

## PRs

If you would like to implement something, firstly: thanks! Community contributions
are a magical thing. Like Redux or [the flux capacitor](https://youtu.be/SR5BfQ4rEqQ?t=2m25s),
they make open source possible.
If you would like to implement something, firstly: thanks! Community contributions are a magical thing. Like Redux or [the flux capacitor](https://youtu.be/SR5BfQ4rEqQ?t=2m25s), they make open source possible.

**Working on your first Pull Request?**
You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).

Here are some things to keep in mind when working on a PR:

#### Tests
**Trying to update an inactive Pull Request?**
If a PR is open, but unfortunately the author is, for any reason, not available to apply code review fixes or rebase the source branch, then please **do not open a new PR**.
Instead, paste a link to your own branch in the PR, and the maintainers can pull in your changes and update the existing PR in-place.

A PR that is just failing test cases for an existing issue is very helpful, as this
can take as much time (if not more) as it takes to implement a new feature or fix
a bug.
### Tests

If you only have enough time to write tests, fantastic! Submit away. This is a great
jumping-off point for a core contributor or even another PR to continue what you've started.
A PR that is just failing test cases for an existing issue is very helpful, as this can take as much time (if not more) as it takes to implement a new feature or fix a bug.

#### Docs
If you only have enough time to write tests, fantastic! Submit away. This is a great jumping-off point for a core contributor or even another PR to continue what you've started.

For enhancements to rules, please update the docs in `docs/rules` matching the rule
filename from `src/rules`.
### Docs

Also, take a quick look at the rule summary in [README.md] in case it could use tweaking,
or add a line if you've implemented a new rule.
For enhancements to rules, please update the docs in `docs/rules` matching the rule filename from `src/rules` or the rule description in `meta.docs.description`. Running `npm run update:eslint-docs` will update the [README.md] and rule doc header.

Bugfixes may not warrant docs changes, though it's worth skimming the existing
docs to see if there are any relevant caveats that need to be removed.
Bugfixes may not warrant docs changes, though it's worth skimming the existing docs to see if there are any relevant caveats that need to be removed.

#### Changelog
### Changelog

Please add a quick blurb to the [**Unreleased**](./CHANGELOG.md#unreleased) section of the change log. Give yourself
some credit, and please link back to the PR for future reference. This is especially
helpful for resolver changes, as the resolvers are less frequently modified and published.
Please add a quick blurb to the [**Unreleased**](./CHANGELOG.md#unreleased) section of the change log. Give yourself some credit, and please link back to the PR for future reference. This is especially helpful for resolver changes, as the resolvers are less frequently modified and published.

Note also that the change log can't magically link back to Github entities (i.e. PRs,
issues, users) or rules; there are a handful of footnote URL definitions at the bottom.
You may need to add one or more URL if you've square-bracketed any such items.
Note also that the change log can't magically link back to Github entities (i.e. PRs, issues, users) or rules; there are a handful of footnote URL definitions at the bottom. You may need to add one or more URL if you've square-bracketed any such items.

## Code of Conduct

This is not so much a set of guidelines as a reference for what I hope may become
a shared perspective on the project. I hope to write a longer essay to this end
in the future. Comments are welcome, I'd like this to be as clear as possible.

### Empathy

People have feelings and perspectives, and people say and believe things for good reasons.

If you find that you summarily disagree with a perspective stated by someone else,
you likely each have histories that have moved you in opposite directions on a continuum
that probably does not have a "wrong" or "right" end. It may be that you simply
are working toward different goals that require different strategies. Every decision
has pros and cons, and could result in some winners and some losers. It's great to
discuss this so that both are well-known, and realize that even with infinite discussion,
cons and losers will likely never go to zero.

Also note that we're not doing brain surgery here, so while it's fine if we spend some time
understanding each other, cordial disagreement should not be expensive in the
long run, and we can accept that we will get some things wrong before we get them right (if ever!).

If we can all get together behind the common goal of embracing empathy, everything else should be able to work itself out.

#### Attribution

Thanks for help from http://mozillascience.github.io/working-open-workshop/contributing/
for inspiration before I wrote this. --ben
Please familiarize yourself with the [Code of Conduct](https://github.com/import-js/.github/blob/main/CODE_OF_CONDUCT.md).

[README.md]: ./README.md
261 changes: 145 additions & 116 deletions README.md

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Release steps

1. create a `release-[x.y.z]` branch from tip of `master` (or whatever release commit)
1. create a `release-[x.y.z]` branch from tip of `main` (or whatever release commit)

```bash
git checkout master && git pull && git checkout -b release-2.1.0
git checkout main && git pull && git checkout -b release-2.1.0
```

2. bump `package.json` + update CHANGELOG version links for all releasing packages (i.e., root + any resolvers)
@@ -13,16 +13,16 @@
at last version's tag.

```markdown
[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.0.1...HEAD
[2.0.1]: https://github.com/benmosher/eslint-plugin-import/compare/v2.0.0...v2.0.1
[Unreleased]: https://github.com/import-js/eslint-plugin-import/compare/v2.0.1...HEAD
[2.0.1]: https://github.com/import-js/eslint-plugin-import/compare/v2.0.0...v2.0.1
```

becomes

```markdown
[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.1.0...HEAD
[2.1.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.0.1...v2.1.0
[2.0.1]: https://github.com/benmosher/eslint-plugin-import/compare/v2.0.0...v2.0.1
[Unreleased]: https://github.com/import-js/eslint-plugin-import/compare/v2.1.0...HEAD
[2.1.0]: https://github.com/import-js/eslint-plugin-import/compare/v2.0.1...v2.1.0
[2.0.1]: https://github.com/import-js/eslint-plugin-import/compare/v2.0.0...v2.0.1
```

Generally, don't use `npm version` for this because it creates a tag, which I normally
@@ -49,6 +49,6 @@
7. merge `release-[x.y.z]` into `release` (
- ideally fast-forward, probably with Git CLI instead of Github

8. merge `release` into `master`
8. merge `release` into `main`

Done!
11 changes: 11 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Security Policy

## Supported Versions

Latest major/minor version is supported only for security updates.

## Reporting a Vulnerability

To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.
179 changes: 143 additions & 36 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,57 +1,164 @@
configuration:
- Native
- WSL

# Test against this version of Node.js
environment:
matrix:
- nodejs_version: "10"
- nodejs_version: "8"
# - nodejs_version: "6"
# - nodejs_version: "4"
- nodejs_version: "16"
- nodejs_version: "14"
- nodejs_version: "12"
- nodejs_version: "10"
- nodejs_version: "8"
# - nodejs_version: "6"
# - nodejs_version: "4"

image: Visual Studio 2019
matrix:
fast_finish: true

# allow_failures:
# - nodejs_version: "4" # for eslint 5
fast_finish: false
exclude:
- configuration: WSL
nodejs_version: "8"
- configuration: WSL
nodejs_version: "6"
- configuration: WSL
nodejs_version: "4"

# platform:
# - x86
# - x64
allow_failures:
- nodejs_version: "4" # for eslint 5

# Install scripts. (runs after repo cloning)
install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version
platform:
- x86
- x64

# install modules
# Initialization scripts. (runs before repo cloning)
init:
# Declare version-numbers of packages to install
- ps: >-
if ($env:nodejs_version -eq "4") {
npm install -g npm@3;
$env:NPM_VERSION="3"
}
if ($env:nodejs_version -in @("8")) {
$env:NPM_VERSION="6"
}
if ($env:nodejs_version -in @("10", "12", "14", "16")) {
$env:NPM_VERSION="6" # TODO: use npm 7
$env:NPM_CONFIG_LEGACY_PEER_DEPS="true"
}
- ps: >-
$env:ESLINT_VERSION="7";
if ([int]$env:nodejs_version -le 8) {
$env:ESLINT_VERSION="6"
}
if ([int]$env:nodejs_version -le 7) {
$env:ESLINT_VERSION="5"
}
if ([int]$env:nodejs_version -le 6) {
$env:ESLINT_VERSION="4"
}
- npm install
- ps: $env:WINDOWS_NYC_VERSION = "15.0.1"
- ps: $env:TRAVIS_NODE_VERSION = $env:nodejs_version

# Add `ci`-command to `PATH` for running commands either using cmd or wsl depending on the configuration
- ps: $env:PATH += ";$(Join-Path $(pwd) "scripts")"

# Install scripts. (runs after repo cloning)
before_build:
# Install propert `npm`-version
- IF DEFINED NPM_VERSION ci sudo npm install -g npm@%NPM_VERSION%

# Install dependencies
- ci npm install
- ci npm run copy-metafiles
- bash ./tests/dep-time-travel.sh 2>&1

# fix symlinks
- cmd: git config core.symlinks true
- cmd: git reset --hard
- git config core.symlinks true
- git reset --hard
- ci git reset --hard

# todo: learn how to do this for all .\resolvers\* on Windows
- cd .\resolvers\webpack && npm install && cd ..\..
- cd .\resolvers\node && npm install && cd ..\..
# Install dependencies of resolvers
- ps: >-
$resolverDir = "./resolvers";
$resolvers = @();
Get-ChildItem -Directory $resolverDir |
ForEach {
$resolvers += "$(Resolve-Path $(Join-Path $resolverDir $_))";
}
$env:RESOLVERS = [string]::Join(";", $resolvers);
- FOR %%G in ("%RESOLVERS:;=";"%") do ( pushd %%~G & ci npm install & popd )

# Post-install test scripts.
test_script:
# Install proper `eslint`-version
- IF DEFINED ESLINT_VERSION ci npm install --no-save eslint@%ESLINT_VERSION%

# Build scripts (project isn't actually built)
build_script:
- ps: "# This Project isn't actually built"

# Test scripts
test_script:
# Output useful info for debugging.
- node --version
- npm --version
- ci node --version
- ci npm --version

# core tests
- npm test
# Run core tests
- ci npm run pretest
- ci npm run tests-only

# resolver tests
- cd .\resolvers\webpack && npm test && cd ..\..
- cd .\resolvers\node && npm test && cd ..\..
# Run resolver tests
- ps: >-
$resolverDir = "./resolvers";
$resolvers = @();
Get-ChildItem -Directory $resolverDir |
ForEach {
$resolvers += "$(Resolve-Path $(Join-Path $resolverDir $_))";
}
$env:RESOLVERS = [string]::Join(";", $resolvers);
- FOR %%G in ("%RESOLVERS:;=";"%") do ( pushd %%~G & ci npm test & popd )

on_success:
- npm run coveralls
# Configuration-specific steps
for:
- matrix:
except:
- configuration: WSL
install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version
before_test:
# Upgrade nyc
- ci npm i --no-save nyc@%WINDOWS_NYC_VERSION%
- ps: >-
$resolverDir = "./resolvers";
$resolvers = @();
Get-ChildItem -Directory $resolverDir |
ForEach {
Push-Location $(Resolve-Path $(Join-Path $resolverDir $_));
ci npm ls nyc > $null;
if ($?) {
$resolvers += "$(pwd)";
}
Pop-Location;
}
$env:RESOLVERS = [string]::Join(";", $resolvers);
- IF DEFINED RESOLVERS FOR %%G in ("%RESOLVERS:;=";"%") do ( pushd %%~G & ci npm install --no-save nyc@%WINDOWS_NYC_VERSION% & popd )
# TODO: enable codecov for native windows builds
#on_success:
#- ci $ProgressPreference = 'SilentlyContinue'
#- ci Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe
#- ci -Outfile codecov.exe
#- ci .\codecov.exe
- matrix:
only:
- configuration: WSL
# Install scripts. (runs after repo cloning)
install:
# Get a specific version of Node.js
- ps: $env:WSLENV += ":nodejs_version"
- ps: wsl curl -sL 'https://deb.nodesource.com/setup_${nodejs_version}.x' `| sudo APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 -E bash -
- wsl sudo DEBIAN_FRONTEND=noninteractive apt install -y nodejs
on_success:
- ci curl -Os https://uploader.codecov.io/latest/linux/codecov
- ci chmod +x codecov
- ci ./codecov

# Don't actually build.
build: off
build: on
2 changes: 1 addition & 1 deletion config/electron.js
Original file line number Diff line number Diff line change
@@ -5,4 +5,4 @@ module.exports = {
settings: {
'import/core-modules': ['electron'],
},
}
};
14 changes: 7 additions & 7 deletions config/errors.js
Original file line number Diff line number Diff line change
@@ -5,10 +5,10 @@
*/
module.exports = {
plugins: ['import'],
rules: { 'import/no-unresolved': 2
, 'import/named': 2
, 'import/namespace': 2
, 'import/default': 2
, 'import/export': 2
}
}
rules: { 'import/no-unresolved': 2,
'import/named': 2,
'import/namespace': 2,
'import/default': 2,
'import/export': 2,
},
};
2 changes: 1 addition & 1 deletion config/react-native.js
Original file line number Diff line number Diff line change
@@ -10,4 +10,4 @@ module.exports = {
},
},
},
}
};
2 changes: 1 addition & 1 deletion config/react.js
Original file line number Diff line number Diff line change
@@ -15,4 +15,4 @@ module.exports = {
ecmaFeatures: { jsx: true },
},

}
};
4 changes: 2 additions & 2 deletions config/recommended.js
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ module.exports = {
// red flags (thus, warnings)
'import/no-named-as-default': 'warn',
'import/no-named-as-default-member': 'warn',
'import/no-duplicates': 'warn'
'import/no-duplicates': 'warn',
},

// need all these for parsing dependencies (even if _your_ code doesn't need
@@ -25,4 +25,4 @@ module.exports = {
sourceType: 'module',
ecmaVersion: 2018,
},
}
};
4 changes: 2 additions & 2 deletions config/stage-0.js
Original file line number Diff line number Diff line change
@@ -8,5 +8,5 @@ module.exports = {
plugins: ['import'],
rules: {
'import/no-deprecated': 1,
}
}
},
};
27 changes: 18 additions & 9 deletions config/typescript.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
/**
* Adds `.jsx`, `.ts` and `.tsx` as an extension, and enables JSX/TSX parsing.
*/
var jsExtensions = ['.js', '.jsx'];
var tsExtensions = ['.ts', '.tsx'];
var allExtensions = jsExtensions.concat(tsExtensions);

// Omit `.d.ts` because 1) TypeScript compilation already confirms that
// types are resolved, and 2) it would mask an unresolved
// `.ts`/`.tsx`/`.js`/`.jsx` implementation.
const allExtensions = ['.ts', '.tsx', '.js', '.jsx'];

module.exports = {

settings: {
'import/extensions': allExtensions,
'import/external-module-folders': ['node_modules', 'node_modules/@types'],
'import/parsers': {
'@typescript-eslint/parser': tsExtensions
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
'import/resolver': {
'node': {
'extensions': allExtensions
}
}
}
'extensions': allExtensions,
},
},
},

rules: {
// analysis/correctness

}
// TypeScript compilation already ensures that named imports exist in the referenced module
'import/named': 'off',
},
};
2 changes: 1 addition & 1 deletion config/warnings.js
Original file line number Diff line number Diff line change
@@ -9,4 +9,4 @@ module.exports = {
'import/no-named-as-default-member': 1,
'import/no-duplicates': 1,
},
}
};
91 changes: 91 additions & 0 deletions docs/rules/consistent-type-specifier-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# import/consistent-type-specifier-style

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

In both Flow and TypeScript you can mark an import as a type-only import by adding a "kind" marker to the import. Both languages support two positions for marker.

**At the top-level** which marks all names in the import as type-only and applies to named, default, and namespace (for TypeScript) specifiers:

```ts
import type Foo from 'Foo';
import type {Bar} from 'Bar';
// ts only
import type * as Bam from 'Bam';
// flow only
import typeof Baz from 'Baz';
```

**Inline** with to the named import, which marks just the specific name in the import as type-only. An inline specifier is only valid for named specifiers, and not for default or namespace specifiers:

```ts
import {type Foo} from 'Foo';
// flow only
import {typeof Bar} from 'Bar';
```

## Rule Details

This rule either enforces or bans the use of inline type-only markers for named imports.

This rule includes a fixer that will automatically convert your specifiers to the correct form - however the fixer will not respect your preferences around de-duplicating imports. If this is important to you, consider using the [`import/no-duplicates`] rule.

[`import/no-duplicates`]: ./no-duplicates.md

## Options

The rule accepts a single string option which may be one of:

- `'prefer-inline'` - enforces that named type-only specifiers are only ever written with an inline marker; and never as part of a top-level, type-only import.
- `'prefer-top-level'` - enforces that named type-only specifiers only ever written as part of a top-level, type-only import; and never with an inline marker.

By default the rule will use the `prefer-inline` option.

## Examples

### `prefer-top-level`

❌ Invalid with `["error", "prefer-top-level"]`

```ts
import {type Foo} from 'Foo';
import Foo, {type Bar} from 'Foo';
// flow only
import {typeof Foo} from 'Foo';
```

✅ Valid with `["error", "prefer-top-level"]`

```ts
import type {Foo} from 'Foo';
import type Foo, {Bar} from 'Foo';
// flow only
import typeof {Foo} from 'Foo';
```

### `prefer-inline`

❌ Invalid with `["error", "prefer-inline"]`

```ts
import type {Foo} from 'Foo';
import type Foo, {Bar} from 'Foo';
// flow only
import typeof {Foo} from 'Foo';
```

✅ Valid with `["error", "prefer-inline"]`

```ts
import {type Foo} from 'Foo';
import Foo, {type Bar} from 'Foo';
// flow only
import {typeof Foo} from 'Foo';
```

## When Not To Use It

If you aren't using Flow or TypeScript 4.5+, then this rule does not apply and need not be used.

If you don't care about, and don't want to standardize how named specifiers are imported then you should not use this rule.
4 changes: 4 additions & 0 deletions docs/rules/default.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# import/default

💼 This rule is enabled in the following configs: ❗ `errors`, ☑️ `recommended`.

<!-- end auto-generated rule header -->

If a default import is requested, this rule will report if there is no default
export in the imported module.

18 changes: 10 additions & 8 deletions docs/rules/dynamic-import-chunkname.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# dynamic imports require a leading comment with a webpackChunkName (dynamic-import-chunkname)
# import/dynamic-import-chunkname

<!-- end auto-generated rule header -->

This rule reports any dynamic imports without a webpackChunkName specified in a leading block comment in the proper format.

@@ -11,7 +13,7 @@ You can also configure the regex format you'd like to accept for the webpackChun
{
"dynamic-import-chunkname": [2, {
importFunctions: ["dynamicImport"],
webpackChunknameFormat: "[a-zA-Z0-57-9-/_]"
webpackChunknameFormat: "[a-zA-Z0-57-9-/_]+"
}]
}
```
@@ -39,12 +41,6 @@ import(
'someModule',
);

// using single quotes instead of double quotes
import(
/* webpackChunkName: 'someModule' */
'someModule',
);

// invalid syntax for webpack comment
import(
/* totally not webpackChunkName: "someModule" */
@@ -78,6 +74,12 @@ The following patterns are valid:
/* webpackChunkName: "someModule", webpackPrefetch: true */
'someModule',
);

// using single quotes instead of double quotes
import(
/* webpackChunkName: 'someModule' */
'someModule',
);
```

## When Not To Use It
4 changes: 4 additions & 0 deletions docs/rules/export.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# import/export

💼 This rule is enabled in the following configs: ❗ `errors`, ☑️ `recommended`.

<!-- end auto-generated rule header -->

Reports funny business with exports, like repeated exports of names or defaults.

## Rule Details
2 changes: 2 additions & 0 deletions docs/rules/exports-last.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# import/exports-last

<!-- end auto-generated rule header -->

This rule enforces that all exports are declared at the bottom of the file. This rule will report any export declarations that comes before any non-export statements.


32 changes: 27 additions & 5 deletions docs/rules/extensions.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# import/extensions - Ensure consistent use of file extension within the import path
# import/extensions

<!-- end auto-generated rule header -->

Some file resolve algorithms allow you to omit the file extension within the import source path. For example the `node` resolver can resolve `./foo/bar` to the absolute path `/User/someone/foo/bar.js` because the `.js` extension is resolved automatically by default. Depending on the resolver you can configure more extensions to get resolved automatically.

@@ -29,13 +31,31 @@ By providing both a string and an object, the string will set the default settin
<severity>,
"never" | "always" | "ignorePackages",
{
<extension>: "never" | "always" | "ignorePackages"
<extension>: "never" | "always" | "ignorePackages"
}
]
```

For example, `["error", "never", { "svg": "always" }]` would require that all extensions are omitted, except for "svg".

`ignorePackages` can be set as a separate boolean option like this:

```
"import/extensions": [
<severity>,
"never" | "always" | "ignorePackages",
{
ignorePackages: true | false,
pattern: {
<extension>: "never" | "always" | "ignorePackages"
}
}
]
```

In that case, if you still want to specify extensions, you can do so inside the **pattern** property.
Default value of `ignorePackages` is `false`.

### Exception

When disallowing the use of certain extensions this rule makes an exception and allows the use of extension when the file would not be resolvable without extension.
@@ -93,7 +113,7 @@ import bar from './bar';

import Component from './Component';

import express from 'express';
import foo from '@/foo';
```

The following patterns are not considered problems when configuration set to "always":
@@ -105,9 +125,9 @@ import bar from './bar.json';

import Component from './Component.jsx';

import express from 'express/index.js';

import * as path from 'path';

import foo from '@/foo.js';
```

The following patterns are considered problems when configuration set to "ignorePackages":
@@ -132,6 +152,7 @@ import Component from './Component.jsx';

import express from 'express';

import foo from '@/foo'
```

The following patterns are not considered problems when configuration set to `['error', 'always', {ignorePackages: true} ]`:
@@ -143,6 +164,7 @@ import baz from 'foo/baz.js';

import express from 'express';

import foo from '@/foo';
```

## When Not To Use It
8 changes: 6 additions & 2 deletions docs/rules/first.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# import/first

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

This rule reports any imports that come after non-import
statements.

@@ -45,7 +49,7 @@ A directive in this case is assumed to be a single statement that contains only
a literal string-valued expression.

`'use strict'` would be a good example, except that [modules are always in strict
mode](http://www.ecma-international.org/ecma-262/6.0/#sec-strict-mode-code) so it would be surprising to see a `'use strict'` sharing a file with `import`s and
mode](https://262.ecma-international.org/6.0/#sec-strict-mode-code) so it would be surprising to see a `'use strict'` sharing a file with `import`s and
`export`s.

Given that, see [#255] for the reasoning.
@@ -67,4 +71,4 @@ enable this rule.
- Issue [#255]

[`import/order`]: ./order.md
[#255]: https://github.com/benmosher/eslint-plugin-import/issues/255
[#255]: https://github.com/import-js/eslint-plugin-import/issues/255
32 changes: 32 additions & 0 deletions docs/rules/group-exports.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# import/group-exports

<!-- end auto-generated rule header -->

Reports when named exports are not grouped together in a single `export` declaration or when multiple assignments to CommonJS `module.exports` or `exports` object are present in a single file.

**Rationale:** An `export` declaration or `module.exports` assignment can appear anywhere in the code. By requiring a single export declaration all your exports will remain at one place, making it easier to see what exports a module provides.
@@ -26,6 +28,12 @@ export {
}
```

```js
// Aggregating exports -> ok
export { default as module1 } from 'module-1'
export { default as module2 } from 'module-2'
```

```js
// A single exports assignment -> ok
module.exports = {
@@ -54,6 +62,15 @@ test.another = true
module.exports = test
```

```flow js
const first = true;
type firstType = boolean
// A single named export declaration (type exports handled separately) -> ok
export {first}
export type {firstType}
```


### Invalid

@@ -63,6 +80,12 @@ export const first = true
export const second = true
```

```js
// Aggregating exports from the same module -> not ok!
export { module1 } from 'module-1'
export { module2 } from 'module-1'
```

```js
// Multiple exports assignments -> not ok!
exports.first = true
@@ -82,6 +105,15 @@ module.exports.first = true
module.exports.second = true
```

```flow js
type firstType = boolean
type secondType = any
// Multiple named type export statements -> not ok!
export type {firstType}
export type {secondType}
```

## When Not To Use It

If you do not mind having your exports spread across the file, you can safely turn this rule off.
9 changes: 9 additions & 0 deletions docs/rules/imports-first.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# import/imports-first

❌ This rule is deprecated.

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

This rule was **deprecated** in eslint-plugin-import v2.0.0. Please use the corresponding rule [`first`](https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/first.md).
40 changes: 32 additions & 8 deletions docs/rules/max-dependencies.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
# import/max-dependencies

<!-- end auto-generated rule header -->

Forbid modules to have too many dependencies (`import` or `require` statements).

This is a useful rule because a module with too many dependencies is a code smell, and usually indicates the module is doing too much and/or should be broken up into smaller modules.

Importing multiple named exports from a single module will only count once (e.g. `import {x, y, z} from './foo'` will only count as a single dependency).

### Options

This rule takes the following option:
## Options

`max`: The maximum number of dependencies allowed. Anything over will trigger the rule. **Default is 10** if the rule is enabled and no `max` is specified.

You can set the option like this:
This rule has the following options, with these defaults:

```js
"import/max-dependencies": ["error", {"max": 10}]
"import/max-dependencies": ["error", {
"max": 10,
"ignoreTypeImports": false,
}]
```

### `max`

## Example
This option sets the maximum number of dependencies allowed. Anything over will trigger the rule. **Default is 10** if the rule is enabled and no `max` is specified.

Given a max value of `{"max": 2}`:

@@ -39,6 +41,28 @@ const anotherA = require('./a'); // still 1
import {x, y, z} from './foo'; // 2
```

### `ignoreTypeImports`

Ignores `type` imports. Type imports are a feature released in TypeScript 3.8, you can [read more here](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export). Defaults to `false`.

Given `{"max": 2, "ignoreTypeImports": true}`:

### Fail

```ts
import a from './a';
import b from './b';
import c from './c';
```

### Pass

```ts
import a from './a';
import b from './b';
import type c from './c'; // Doesn't count against max
```

## When Not To Use It

If you don't care how many dependencies a module has.
14 changes: 10 additions & 4 deletions docs/rules/named.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
# import/named

💼🚫 This rule is enabled in the following configs: ❗ `errors`, ☑️ `recommended`. This rule is _disabled_ in the ⌨️ `typescript` config.

<!-- end auto-generated rule header -->

Verifies that all named imports are part of the set of named exports in the referenced module.

For `export`, verifies that all named exports exist in the referenced module.

Note: for packages, the plugin will find exported names
from [`jsnext:main`], if present in `package.json`.
from [`jsnext:main`] (deprecated) or `module`, if present in `package.json`.
Redux's npm module includes this key, and thereby is lintable, for example.

A module path that is [ignored] or not [unambiguously an ES module] will not be reported when imported. Note that type imports, as used by [Flow], are always ignored.
A module path that is [ignored] or not [unambiguously an ES module] will not be reported when imported. Note that type imports and exports, as used by [Flow], are always ignored.

[ignored]: ../../README.md#importignore
[unambiguously an ES module]: https://github.com/bmeck/UnambiguousJavaScriptGrammar
@@ -91,8 +95,10 @@ runtime, you will likely see false positives with this rule.
## Further Reading

- [`import/ignore`] setting
- [`jsnext:main`] (Rollup)
- [`jsnext:main`] deprecation
- [`pkg.module`] (Rollup)


[`jsnext:main`]: https://github.com/rollup/rollup/wiki/jsnext:main
[`jsnext:main`]: https://github.com/jsforum/jsforum/issues/5
[`pkg.module`]: https://github.com/rollup/rollup/wiki/pkg.module
[`import/ignore`]: ../../README.md#importignore
4 changes: 4 additions & 0 deletions docs/rules/namespace.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# import/namespace

💼 This rule is enabled in the following configs: ❗ `errors`, ☑️ `recommended`.

<!-- end auto-generated rule header -->

Enforces names exist at the time they are dereferenced, when imported as a full namespace (i.e. `import * as foo from './foo'; foo.bar();` will report if `bar` is not exported by `./foo`.).

Will report at the import declaration if there are _no_ exported names found.
33 changes: 32 additions & 1 deletion docs/rules/newline-after-import.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
# import/newline-after-import

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Enforces having one or more empty lines after the last top-level import statement or require call.
+(fixable) The `--fix` option on the [command line] automatically fixes problems reported by this rule.

## Rule Details

This rule has one option, `count` which sets the number of newlines that are enforced after the last top-level import statement or require call. This option defaults to `1`.
This rule supports the following options:
- `count` which sets the number of newlines that are enforced after the last top-level import statement or require call. This option defaults to `1`.

- `considerComments` which enforces the rule on comments after the last import-statement as well when set to true. This option defaults to `false`.

Valid:

@@ -71,6 +78,30 @@ import defaultExport from './foo'
const FOO = 'BAR'
```

With `considerComments` set to `false` this will be considered valid:

```js
import defaultExport from './foo'
// some comment here.
const FOO = 'BAR'
```

With `considerComments` set to `true` this will be considered valid:

```js
import defaultExport from './foo'

// some comment here.
const FOO = 'BAR'
```

With `considerComments` set to `true` this will be considered invalid:

```js
import defaultExport from './foo'
// some comment here.
const FOO = 'BAR'
```

## Example options usage
```json
8 changes: 7 additions & 1 deletion docs/rules/no-absolute-path.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# import/no-absolute-path: Forbid import of modules using absolute paths
# import/no-absolute-path

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Node.js allows the import of modules using an absolute path such as `/home/xyz/file.js`. That is a bad practice as it ties the code using it to your computer, and therefore makes it unusable in packages distributed on `npm` for instance.

This rule forbids the import of modules using absolute paths.

## Rule Details

### Fail
2 changes: 2 additions & 0 deletions docs/rules/no-amd.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# import/no-amd

<!-- end auto-generated rule header -->

Reports `require([array], ...)` and `define([array], ...)` function calls at the
module scope. Will not report if !=2 arguments, or first argument is not a literal array.

8 changes: 8 additions & 0 deletions docs/rules/no-anonymous-default-export.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# import/no-anonymous-default-export

<!-- end auto-generated rule header -->

Reports if a module's default export is unnamed. This includes several types of unnamed data types; literals, object expressions, arrays, anonymous functions, arrow functions, and anonymous class declarations.

Ensuring that default exports are named helps improve the grepability of the codebase by encouraging the re-use of the same identifier for the module's default export at its declaration site and at its import sites.
@@ -17,6 +19,7 @@ The complete default configuration looks like this.
"allowAnonymousClass": false,
"allowAnonymousFunction": false,
"allowCallExpression": true, // The true value here is for backward compatibility
"allowNew": false,
"allowLiteral": false,
"allowObject": false
}]
@@ -40,6 +43,8 @@ export default foo(bar)
export default 123

export default {}

export default new Foo()
```

### Pass
@@ -70,4 +75,7 @@ export default 123

/* eslint import/no-anonymous-default-export: [2, {"allowObject": true}] */
export default {}

/* eslint import/no-anonymous-default-export: [2, {"allowNew": true}] */
export default new Foo()
```
21 changes: 19 additions & 2 deletions docs/rules/no-commonjs.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# import/no-commonjs

<!-- end auto-generated rule header -->

Reports `require([string])` function calls. Will not report if >1 argument,
or single argument is not a literal string.

@@ -27,15 +29,30 @@ If `allowRequire` option is set to `true`, `require` calls are valid:

```js
/*eslint no-commonjs: [2, { allowRequire: true }]*/
var mod = require('./mod');
```

but `module.exports` is reported as usual.

### Allow conditional require

By default, conditional requires are allowed:

```js
var a = b && require("c")

if (typeof window !== "undefined") {
require('that-ugly-thing');
}

var fs = null;
try {
fs = require("fs")
} catch (error) {}
```

but `module.exports` is reported as usual.
If the `allowConditionalRequire` option is set to `false`, they will be reported.

This is useful for conditional requires.
If you don't rely on synchronous module loading, check out [dynamic import](https://github.com/airbnb/babel-plugin-dynamic-import-node).

### Allow primitive modules
53 changes: 51 additions & 2 deletions docs/rules/no-cycle.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
# import/no-cycle

<!-- end auto-generated rule header -->

Ensures that there is no resolvable path back to this module via its dependencies.

This includes cycles of depth 1 (imported module imports me) to `Infinity`, if the
This includes cycles of depth 1 (imported module imports me) to `"∞"` (or `Infinity`), if the
[`maxDepth`](#maxdepth) option is not set.

```js
// dep-b.js
import './dep-a.js'

export function b() { /* ... */ }
```

```js
// dep-a.js
import { b } from './dep-b.js' // reported: Dependency cycle detected.
```

This rule does _not_ detect imports that resolve directly to the linted module;
for that, see [`no-self-import`].

This rule ignores type-only imports in Flow and TypeScript syntax (`import type` and `import typeof`), which have no runtime effect.


## Rule Details

@@ -36,19 +42,59 @@ There is a `maxDepth` option available to prevent full expansion of very deep de

// dep-c.js
import './dep-a.js'
```

```js
// dep-b.js
import './dep-c.js'

export function b() { /* ... */ }
```

```js
// dep-a.js
import { b } from './dep-b.js' // not reported as the cycle is at depth 2
```

This is not necessarily recommended, but available as a cost/benefit tradeoff mechanism
for reducing total project lint time, if needed.

#### `ignoreExternal`

An `ignoreExternal` option is available to prevent the cycle detection to expand to external modules:

```js
/*eslint import/no-cycle: [2, { ignoreExternal: true }]*/

// dep-a.js
import 'module-b/dep-b.js'

export function a() { /* ... */ }
```

```js
// node_modules/module-b/dep-b.js
import { a } from './dep-a.js' // not reported as this module is external
```

Its value is `false` by default, but can be set to `true` for reducing total project lint time, if needed.

#### `allowUnsafeDynamicCyclicDependency`

This option disable reporting of errors if a cycle is detected with at least one dynamic import.

```js
// bar.js
import { foo } from './foo';
export const bar = foo;

// foo.js
export const foo = 'Foo';
export function getBar() { return import('./bar'); }
```

> Cyclic dependency are **always** a dangerous anti-pattern as discussed extensively in [#2265](https://github.com/import-js/eslint-plugin-import/issues/2265). Please be extra careful about using this option.
## When Not To Use It

This rule is comparatively computationally expensive. If you are pressed for lint
@@ -57,7 +103,10 @@ this rule enabled.

## Further Reading

- [Original inspiring issue](https://github.com/benmosher/eslint-plugin-import/issues/941)
- [Original inspiring issue](https://github.com/import-js/eslint-plugin-import/issues/941)
- Rule to detect that module imports itself: [`no-self-import`]
- [`import/external-module-folders`] setting

[`no-self-import`]: ./no-self-import.md

[`import/external-module-folders`]: ../../README.md#importexternal-module-folders
4 changes: 3 additions & 1 deletion docs/rules/no-default-export.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# `import/no-default-export`
# import/no-default-export

<!-- end auto-generated rule header -->

Prohibit default exports. Mostly an inverse of [`prefer-default-export`].

4 changes: 3 additions & 1 deletion docs/rules/no-deprecated.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# `import/no-deprecated`
# import/no-deprecated

<!-- end auto-generated rule header -->

Reports use of a deprecated name, as indicated by a JSDoc block with a `@deprecated`
tag or TomDoc `Deprecated: ` comment.
62 changes: 60 additions & 2 deletions docs/rules/no-duplicates.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
# import/no-duplicates

⚠️ This rule _warns_ in the following configs: ☑️ `recommended`, 🚸 `warnings`.

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Reports if a resolved path is imported more than once.
+(fixable) The `--fix` option on the [command line] automatically fixes some problems reported by this rule.

ESLint core has a similar rule ([`no-duplicate-imports`](http://eslint.org/docs/rules/no-duplicate-imports)), but this version
ESLint core has a similar rule ([`no-duplicate-imports`](https://eslint.org/docs/rules/no-duplicate-imports)), but this version
is different in two key ways:

1. the paths in the source code don't have to exactly match, they just have to point to the same module on the filesystem. (i.e. `./foo` and `./foo.js`)
2. this version distinguishes Flow `type` imports from standard imports. ([#334](https://github.com/benmosher/eslint-plugin-import/pull/334))
2. this version distinguishes Flow `type` imports from standard imports. ([#334](https://github.com/import-js/eslint-plugin-import/pull/334))

## Rule Details

@@ -36,6 +42,58 @@ The motivation is that this is likely a result of two developers importing diffe
names from the same module at different times (and potentially largely different
locations in the file.) This rule brings both (or n-many) to attention.

### Query Strings

By default, this rule ignores query strings (i.e. paths followed by a question mark), and thus imports from `./mod?a` and `./mod?b` will be considered as duplicates. However you can use the option `considerQueryString` to handle them as different (primarily because browsers will resolve those imports differently).

Config:

```json
"import/no-duplicates": ["error", {"considerQueryString": true}]
```

And then the following code becomes valid:
```js
import minifiedMod from './mod?minify'
import noCommentsMod from './mod?comments=0'
import originalMod from './mod'
```

It will still catch duplicates when using the same module and the exact same query string:
```js
import SomeDefaultClass from './mod?minify'

// This is invalid, assuming `./mod` and `./mod.js` are the same target:
import * from './mod.js?minify'
```

### Inline Type imports

TypeScript 4.5 introduced a new [feature](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#type-on-import-names) that allows mixing of named value and type imports. In order to support fixing to an inline type import when duplicate imports are detected, `prefer-inline` can be set to true.

Config:

```json
"import/no-duplicates": ["error", {"prefer-inline": true}]
```

<!--tabs-->

❌ Invalid `["error", "prefer-inline"]`

```js
import { AValue, type AType } from './mama-mia'
import type { BType } from './mama-mia'
```

✅ Valid with `["error", "prefer-inline"]`

```js
import { AValue, type AType, type BType } from './mama-mia'
```

<!--tabs-->

## When Not To Use It

If the core ESLint version is good enough (i.e. you're _not_ using Flow and you _are_ using [`import/extensions`](./extensions.md)), keep it and don't use this.
6 changes: 4 additions & 2 deletions docs/rules/no-dynamic-require.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# import/no-dynamic-require: Forbid `require()` calls with expressions
# import/no-dynamic-require

<!-- end auto-generated rule header -->

The `require` method from CommonJS is used to import modules from different files. Unlike the ES6 `import` syntax, it can be given expressions that will be resolved at runtime. While this is sometimes necessary and useful, in most cases it isn't. Using expressions (for instance, concatenating a path and variable) as the argument makes it harder for tools to do static code analysis, or to find where in the codebase a module is used.

This rule checks every call to `require()` that uses expressions for the module name argument.
This rule forbids every call to `require()` that uses expressions for the module name argument.

## Rule Details

43 changes: 43 additions & 0 deletions docs/rules/no-empty-named-blocks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# import/no-empty-named-blocks

🔧💡 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) and manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).

<!-- end auto-generated rule header -->

Reports the use of empty named import blocks.

## Rule Details

### Valid
```js
import { mod } from 'mod'
import Default, { mod } from 'mod'
```

When using typescript
```js
import type { mod } from 'mod'
```

When using flow
```js
import typeof { mod } from 'mod'
```

### Invalid
```js
import {} from 'mod'
import Default, {} from 'mod'
```

When using typescript
```js
import type Default, {} from 'mod'
import type {} from 'mod'
```

When using flow
```js
import typeof {} from 'mod'
import typeof Default, {} from 'mod'
```
36 changes: 31 additions & 5 deletions docs/rules/no-extraneous-dependencies.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# import/no-extraneous-dependencies: Forbid the use of extraneous packages
# import/no-extraneous-dependencies

Forbid the import of external modules that are not declared in the `package.json`'s `dependencies`, `devDependencies`, `optionalDependencies` or `peerDependencies`.
The closest parent `package.json` will be used. If no `package.json` is found, the rule will not lint anything. This behaviour can be changed with the rule option `packageDir`.
<!-- end auto-generated rule header -->

Forbid the import of external modules that are not declared in the `package.json`'s `dependencies`, `devDependencies`, `optionalDependencies`, `peerDependencies`, or `bundledDependencies`.
The closest parent `package.json` will be used. If no `package.json` is found, the rule will not lint anything. This behavior can be changed with the rule option `packageDir`. Normally ignores imports of modules marked internal, but this can be changed with the rule option `includeInternal`. Type imports can be verified by specifying `includeTypes`.

Modules have to be installed for this rule to work.

@@ -13,7 +15,9 @@ This rule supports the following options:

`optionalDependencies`: If set to `false`, then the rule will show an error when `optionalDependencies` are imported. Defaults to `true`.

`peerDependencies`: If set to `false`, then the rule will show an error when `peerDependencies` are imported. Defaults to `false`.
`peerDependencies`: If set to `false`, then the rule will show an error when `peerDependencies` are imported. Defaults to `true`.

`bundledDependencies`: If set to `false`, then the rule will show an error when `bundledDependencies` are imported. Defaults to `true`.

You can set the options like this:

@@ -29,6 +33,12 @@ You can also use an array of globs instead of literal booleans:

When using an array of globs, the setting will be set to `true` (no errors reported) if the name of the file being linted matches a single glob in the array, and `false` otherwise.

There are 2 boolean options to opt into checking extra imports that are normally ignored: `includeInternal`, which enables the checking of internal modules, and `includeTypes`, which enables checking of type imports in TypeScript.

```js
"import/no-extraneous-dependencies": ["error", {"includeInternal": true, "includeTypes": true}]
```

Also there is one more option called `packageDir`, this option is to specify the path to the folder containing package.json.

If provided as a relative path string, will be computed relative to the current working directory at linter execution time. If this is not ideal (does not work with some editor integrations), consider using `__dirname` to provide a path relative to your configuration.
@@ -70,7 +80,10 @@ Given the following `package.json`:
},
"peerDependencies": {
"react": ">=15.0.0 <16.0.0"
}
},
"bundledDependencies": [
"@generated/foo",
]
}
```

@@ -90,6 +103,17 @@ var test = require('ava');
/* eslint import/no-extraneous-dependencies: ["error", {"optionalDependencies": false}] */
import isArray from 'lodash.isarray';
var isArray = require('lodash.isarray');

/* eslint import/no-extraneous-dependencies: ["error", {"bundledDependencies": false}] */
import foo from '"@generated/foo"';
var foo = require('"@generated/foo"');

/* eslint import/no-extraneous-dependencies: ["error", {"includeInternal": true}] */
import foo from './foo';
var foo = require('./foo');

/* eslint import/no-extraneous-dependencies: ["error", {"includeTypes": true}] */
import type { MyType } from 'foo';
```


@@ -103,6 +127,8 @@ var foo = require('./foo');
import test from 'ava';
import find from 'lodash.find';
import isArray from 'lodash.isarray';
import foo from '"@generated/foo"';
import type { MyType } from 'foo';

/* eslint import/no-extraneous-dependencies: ["error", {"peerDependencies": true}] */
import react from 'react';
78 changes: 78 additions & 0 deletions docs/rules/no-import-module-exports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# import/no-import-module-exports

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Reports the use of import declarations with CommonJS exports in any module
except for the [main module](https://docs.npmjs.com/files/package.json#main).

If you have multiple entry points or are using `js:next` this rule includes an
`exceptions` option which you can use to exclude those files from the rule.

## Options

#### `exceptions`
- An array of globs. The rule will be omitted from any file that matches a glob
in the options array. For example, the following setting will omit the rule
in the `some-file.js` file.

```json
"import/no-import-module-exports": ["error", {
"exceptions": ["**/*/some-file.js"]
}]
```

## Rule Details

### Fail

```js
import { stuff } from 'starwars'
module.exports = thing

import * as allThings from 'starwars'
exports.bar = thing

import thing from 'other-thing'
exports.foo = bar

import thing from 'starwars'
const baz = module.exports = thing
console.log(baz)
```

### Pass
Given the following package.json:

```json
{
"main": "lib/index.js",
}
```

```js
import thing from 'other-thing'
export default thing

const thing = require('thing')
module.exports = thing

const thing = require('thing')
exports.foo = bar

import thing from 'otherthing'
console.log(thing.module.exports)

// in lib/index.js
import foo from 'path';
module.exports = foo;

// in some-file.js
// eslint import/no-import-module-exports: ["error", {"exceptions": ["**/*/some-file.js"]}]
import foo from 'path';
module.exports = foo;
```

### Further Reading
- [webpack issue #4039](https://github.com/webpack/webpack/issues/4039)
74 changes: 72 additions & 2 deletions docs/rules/no-internal-modules.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# import/no-internal-modules

<!-- end auto-generated rule header -->

Use this rule to prevent importing the submodules of other modules.

## Rule Details

This rule has one option, `allow` which is an array of [minimatch/glob patterns](https://github.com/isaacs/node-glob#glob-primer) patterns that whitelist paths and import statements that can be imported with reaching.
This rule has two mutally exclusive options that are arrays of [minimatch/glob patterns](https://github.com/isaacs/node-glob#glob-primer) patterns:

- `allow` that include paths and import statements that can be imported with reaching.
- `forbid` that exclude paths and import statements that can be imported with reaching.

### Examples

@@ -33,7 +38,7 @@ And the .eslintrc file:
...
"rules": {
"import/no-internal-modules": [ "error", {
"allow": [ "**/actions/*", "source-map-support/*" ]
"allow": [ "**/actions/*", "source-map-support/*" ],
} ]
}
}
@@ -49,6 +54,9 @@ The following patterns are considered problems:
import { settings } from './app/index'; // Reaching to "./app/index" is not allowed
import userReducer from './reducer/user'; // Reaching to "./reducer/user" is not allowed
import configureStore from './redux/configureStore'; // Reaching to "./redux/configureStore" is not allowed

export { settings } from './app/index'; // Reaching to "./app/index" is not allowed
export * from './reducer/user'; // Reaching to "./reducer/user" is not allowed
```

The following patterns are NOT considered problems:
@@ -61,4 +69,66 @@ The following patterns are NOT considered problems:
import 'source-map-support/register';
import { settings } from '../app';
import getUser from '../actions/getUser';

export * from 'source-map-support/register';
export { settings } from '../app';
```

Given the following folder structure:

```
my-project
├── actions
│ └── getUser.js
│ └── updateUser.js
├── reducer
│ └── index.js
│ └── user.js
├── redux
│ └── index.js
│ └── configureStore.js
└── app
│ └── index.js
│ └── settings.js
└── entry.js
```

And the .eslintrc file:
```
{
...
"rules": {
"import/no-internal-modules": [ "error", {
"forbid": [ "**/actions/*", "source-map-support/*" ],
} ]
}
}
```

The following patterns are considered problems:

```js
/**
* in my-project/entry.js
*/

import 'source-map-support/register';
import getUser from '../actions/getUser';

export * from 'source-map-support/register';
export getUser from '../actions/getUser';
```

The following patterns are NOT considered problems:

```js
/**
* in my-project/entry.js
*/

import 'source-map-support';
import { getUser } from '../actions';

export * from 'source-map-support';
export { getUser } from '../actions';
```
6 changes: 4 additions & 2 deletions docs/rules/no-mutable-exports.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# import/no-mutable-exports

<!-- end auto-generated rule header -->

Forbids the use of mutable exports with `var` or `let`.

## Rule Details
@@ -44,8 +46,8 @@ want to enable the following core ESLint rules:
- [no-func-assign]
- [no-class-assign]

[no-func-assign]: http://eslint.org/docs/rules/no-func-assign
[no-class-assign]: http://eslint.org/docs/rules/no-class-assign
[no-func-assign]: https://eslint.org/docs/rules/no-func-assign
[no-class-assign]: https://eslint.org/docs/rules/no-class-assign

## When Not To Use It

6 changes: 5 additions & 1 deletion docs/rules/no-named-as-default-member.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# import/no-named-as-default-member

⚠️ This rule _warns_ in the following configs: ☑️ `recommended`, 🚸 `warnings`.

<!-- end auto-generated rule header -->

Reports use of an exported name as a property on the default export.

Rationale: Accessing a property that has a name that is shared by an exported
@@ -14,7 +18,7 @@ fixed in Babel 6. Before upgrading an existing codebase to Babel 6, it can be
useful to run this lint rule.


[blog]: https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0
[blog]: https://kentcdodds.com/blog/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution


## Rule Details
6 changes: 5 additions & 1 deletion docs/rules/no-named-as-default.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# import/no-named-as-default

⚠️ This rule _warns_ in the following configs: ☑️ `recommended`, 🚸 `warnings`.

<!-- end auto-generated rule header -->

Reports use of an exported name as the locally imported name of a default export.

Rationale: using an exported name as the name of the default export is likely...
@@ -31,7 +35,7 @@ For post-ES2015 `export` extensions, this also prevents exporting the default fr

```js
// valid:
export foo from './foo.js'
export foo from './foo.js';

// message: Using exported name 'bar' as identifier for default export.
export bar from './foo.js';
6 changes: 6 additions & 0 deletions docs/rules/no-named-default.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# import/no-named-default

<!-- end auto-generated rule header -->

Reports use of a default export as a locally named import.

Rationale: the syntax exists to import default exports expressively, let's use it.

Note that type imports, as used by [Flow], are always ignored.

[Flow]: https://flow.org/

## Rule Details

Given:
4 changes: 3 additions & 1 deletion docs/rules/no-named-export.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# `import/no-named-export`
# import/no-named-export

<!-- end auto-generated rule header -->

Prohibit named exports. Mostly an inverse of [`no-default-export`].

25 changes: 23 additions & 2 deletions docs/rules/no-namespace.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# import/no-namespace

Reports if namespace import is used.
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Enforce a convention of not using namespace (a.k.a. "wildcard" `*`) imports.

+(fixable) The `--fix` option on the [command line] automatically fixes problems reported by this rule, provided that the namespace object is only used for direct member access, e.g. `namespace.a`.
The `--fix` functionality for this rule requires ESLint 5 or newer.

### Options

This rule supports the following options:

- `ignore`: array of glob strings for modules that should be ignored by the rule.

## Rule Details

@@ -12,10 +25,18 @@ import { a, b } from './bar'
import defaultExport, { a, b } from './foobar'
```

...whereas here imports will be reported:
```js
/* eslint import/no-namespace: ["error", {ignore: ['*.ext']}] */
import * as bar from './ignored-module.ext';
```

Invalid:

```js
import * as foo from 'foo';
```

```js
import defaultExport, * as foo from 'foo';
```

4 changes: 3 additions & 1 deletion docs/rules/no-nodejs-modules.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# import/no-nodejs-modules: No Node.js builtin modules
# import/no-nodejs-modules

<!-- end auto-generated rule header -->

Forbid the use of Node.js builtin modules. Can be useful for client-side web projects that do not have access to those modules.

71 changes: 71 additions & 0 deletions docs/rules/no-relative-packages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# import/no-relative-packages

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Use this rule to prevent importing packages through relative paths.

It's useful in Yarn/Lerna workspaces, were it's possible to import a sibling
package using `../package` relative path, while direct `package` is the correct one.

+(fixable) The `--fix` option on the [command line] automatically fixes problems reported by this rule.

### Examples

Given the following folder structure:

```
my-project
├── packages
│ ├── foo
│ │ ├── index.js
│ │ └── package.json
│ └── bar
│ ├── index.js
│ └── package.json
└── entry.js
```

And the .eslintrc file:
```
{
...
"rules": {
"import/no-relative-packages": "error"
}
}
```

The following patterns are considered problems:

```js
/**
* in my-project/packages/foo.js
*/

import bar from '../bar'; // Import sibling package using relative path
import entry from '../../entry.js'; // Import from parent package using relative path

/**
* in my-project/entry.js
*/

import bar from './packages/bar'; // Import child package using relative path
```

The following patterns are NOT considered problems:

```js
/**
* in my-project/packages/foo.js
*/

import bar from 'bar'; // Import sibling package using package name

/**
* in my-project/entry.js
*/

import bar from 'bar'; // Import sibling package using package name
```
2 changes: 2 additions & 0 deletions docs/rules/no-relative-parent-imports.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# import/no-relative-parent-imports

<!-- end auto-generated rule header -->

Use this rule to prevent imports to folders in relative parent paths.

This rule is useful for enforcing tree-like folder structures instead of complex graph-like folder structures. While this restriction might be a departure from Node's default resolution style, it can lead large, complex codebases to be easier to maintain. If you've ever had debates over "where to put files" this rule is for you.
163 changes: 161 additions & 2 deletions docs/rules/no-restricted-paths.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# import/no-restricted-paths: Restrict which files can be imported in a given folder
# import/no-restricted-paths

<!-- end auto-generated rule header -->

Some projects contain files which are not always meant to be executed in the same environment.
For example consider a web application that contains specific code for the server and some specific code for the browser/client. In this case you don’t want to import server-only files in your client code.
@@ -9,7 +11,21 @@ In order to prevent such scenarios this rule allows you to define restricted zon

This rule has one option. The option is an object containing the definition of all restricted `zones` and the optional `basePath` which is used to resolve relative paths within.
The default value for `basePath` is the current working directory.
Each zone consists of the `target` path and a `from` path. The `target` is the path where the restricted imports should be applied. The `from` path defines the folder that is not allowed to be used in an import.

Each zone consists of the `target` paths, a `from` paths, and an optional `except` and `message` attribute.
- `target` contains the paths where the restricted imports should be applied. It can be expressed by
- directory string path that matches all its containing files
- glob pattern matching all the targeted files
- an array of multiple of the two types above
- `from` paths define the folders that are not allowed to be used in an import. It can be expressed by
- directory string path that matches all its containing files
- glob pattern matching all the files restricted to be imported
- an array of multiple directory string path
- an array of multiple glob patterns
- `except` may be defined for a zone, allowing exception paths that would otherwise violate the related `from`. Note that it does not alter the behaviour of `target` in any way.
- in case `from` contains only glob patterns, `except` must be an array of glob patterns as well
- in case `from` contains only directory path, `except` is relative to `from` and cannot backtrack to a parent directory
- `message` - will be displayed in case of the rule violation.

### Examples

@@ -37,3 +53,146 @@ The following patterns are not considered problems when configuration set to `{
```js
import baz from '../client/baz';
```

---------------

Given the following folder structure:

```
my-project
├── client
│ └── foo.js
│ └── baz.js
└── server
├── one
│ └── a.js
│ └── b.js
└── two
```

and the current file being linted is `my-project/server/one/a.js`.

and the current configuration is set to:

```
{ "zones": [ {
"target": "./tests/files/restricted-paths/server/one",
"from": "./tests/files/restricted-paths/server",
"except": ["./one"]
} ] }
```

The following pattern is considered a problem:

```js
import a from '../two/a'
```

The following pattern is not considered a problem:

```js
import b from './b'

```

---------------

Given the following folder structure:

```
my-project
├── client
└── foo.js
└── sub-module
└── bar.js
└── baz.js

```

and the current configuration is set to:

```
{ "zones": [ {
"target": "./tests/files/restricted-paths/client/!(sub-module)/**/*",
"from": "./tests/files/restricted-paths/client/sub-module/**/*",
} ] }
```

The following import is considered a problem in `my-project/client/foo.js`:

```js
import a from './sub-module/baz'
```

The following import is not considered a problem in `my-project/client/sub-module/bar.js`:

```js
import b from './baz'
```

---------------

Given the following folder structure:

```
my-project
└── one
└── a.js
└── b.js
└── two
└── a.js
└── b.js
└── three
└── a.js
└── b.js
```

and the current configuration is set to:

```
{
"zones": [
{
"target": ["./tests/files/restricted-paths/two/*", "./tests/files/restricted-paths/three/*"],
"from": ["./tests/files/restricted-paths/one", "./tests/files/restricted-paths/three"],
}
]
}
```

The following patterns are not considered a problem in `my-project/one/b.js`:

```js
import a from '../three/a'
```

```js
import a from './a'
```

The following pattern is not considered a problem in `my-project/two/b.js`:

```js
import a from './a'
```

The following patterns are considered a problem in `my-project/two/a.js`:

```js
import a from '../one/a'
```

```js
import a from '../three/a'
```

The following patterns are considered a problem in `my-project/three/b.js`:

```js
import a from '../one/a'
```

```js
import a from './a'
```

4 changes: 3 additions & 1 deletion docs/rules/no-self-import.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Forbid a module from importing itself (`import/no-self-import`)
# import/no-self-import

<!-- end auto-generated rule header -->

Forbid a module from importing itself. This can sometimes happen during refactoring.

4 changes: 3 additions & 1 deletion docs/rules/no-unassigned-import.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# import/no-unassigned-import: Forbid unassigned imports
# import/no-unassigned-import

<!-- end auto-generated rule header -->

With both CommonJS' `require` and the ES6 modules' `import` syntax, it is possible to import a module but not to use its result. This can be done explicitly by not assigning the module to as variable. Doing so can mean either of the following things:
- The module is imported but not used
29 changes: 24 additions & 5 deletions docs/rules/no-unresolved.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# import/no-unresolved

💼 This rule is enabled in the following configs: ❗ `errors`, ☑️ `recommended`.

<!-- end auto-generated rule header -->

Ensures an imported module can be resolved to a module on the local filesystem,
as defined by standard Node `require.resolve` behavior.

See [settings](../../README.md#settings) for customization options for the resolution (i.e.
additional filetypes, `NODE_PATH`, etc.)

This rule can also optionally report on unresolved modules in CommonJS `require('./foo')` calls and AMD `require(['./foo'], function (foo){...})` and `define(['./foo'], function (foo){...})`.
This rule can also optionally report on unresolved modules in CommonJS `require('./foo')` calls and AMD `require(['./foo'], function (foo) {...})` and `define(['./foo'], function (foo) {...})`.

To enable this, send `{ commonjs: true/false, amd: true/false }` as a rule option.
Both are disabled by default.
@@ -60,7 +64,7 @@ This rule has its own ignore list, separate from [`import/ignore`]. This is beca
To suppress errors from files that may not be properly resolved by your [resolver settings](../../README.md#resolver-plugins), you may add an `ignore` key with an array of `RegExp` pattern strings:

```js
/*eslint import/no-unresolved: [2, { ignore: ['\.img$'] }]*/
/*eslint import/no-unresolved: [2, { ignore: ['\\.img$'] }]*/

import { x } from './mod' // may be reported, if not resolved to a module

@@ -76,14 +80,29 @@ By default, this rule will report paths whose case do not match the underlying f
const { default: x } = require('./foo') // reported if './foo' is actually './Foo' and caseSensitive: true
```

#### `caseSensitiveStrict`

The `caseSensitive` option does not detect case for the current working directory. The `caseSensitiveStrict` option allows checking `cwd` in resolved path. By default, the option is disabled.


```js
/*eslint import/no-unresolved: [2, { caseSensitiveStrict: true }]*/

// Absolute paths
import Foo from `/Users/fOo/bar/file.js` // reported, /Users/foo/bar/file.js
import Foo from `d:/fOo/bar/file.js` // reported, d:/foo/bar/file.js

// Relative paths, cwd is Users/foo/
import Foo from `./../fOo/bar/file.js` // reported
```

## When Not To Use It

If you're using a module bundler other than Node or Webpack, you may end up with
a lot of false positive reports of missing dependencies.
If you're using a module bundler other than Node or Webpack, you may end up with a lot of false positive reports of missing dependencies.

## Further Reading

- [Resolver plugins](../../README.md#resolver-plugins)
- [Resolver plugins](../../README.md#resolvers)
- [Node resolver](https://npmjs.com/package/eslint-import-resolver-node) (default)
- [Webpack resolver](https://npmjs.com/package/eslint-import-resolver-webpack)
- [`import/ignore`] global setting
46 changes: 27 additions & 19 deletions docs/rules/no-unused-modules.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,52 @@
# import/no-unused-modules

<!-- end auto-generated rule header -->

Reports:
- modules without any exports
- individual exports not being statically `import`ed or `require`ed from other modules in the same project
- dynamic imports are supported if argument is a literal string

Note: dynamic imports are currently not supported.

## Rule Details

### Usage

In order for this plugin to work, one of the options `missingExports` or `unusedExports` must be enabled (see "Options" section below). In the future, these options will be enabled by default (see https://github.com/import-js/eslint-plugin-import/issues/1324)

Example:
```
"rules: {
...otherRules,
"import/no-unused-modules": [1, {"unusedExports": true}]
}
```

### Options

This rule takes the following option:

- **`missingExports`**: if `true`, files without any exports are reported (defaults to `false`)
- **`unusedExports`**: if `true`, exports without any static usage within other modules are reported (defaults to `false`)
- `src`: an array with files/paths to be analyzed. It only applies to unused exports. Defaults to `process.cwd()`, if not provided
- `ignoreExports`: an array with files/paths for which unused exports will not be reported (e.g module entry points in a published package)
- `missingExports`: if `true`, files without any exports are reported
- `unusedExports`: if `true`, exports without any static usage within other modules are reported.
- `ignoreExports`: an array with files/paths for which unused exports will not be reported (e.g module entry points in a published package)


### Example for missing exports
#### The following will be reported
```js
const class MyClass { /*...*/ }
const class MyClass { /*...*/ }

function makeClass() { return new MyClass(...arguments) }
```

#### The following will not be reported

```js
export default function () { /*...*/ }
export default function () { /*...*/ }
```
```js
export const foo = function () { /*...*/ }
export const foo = function () { /*...*/ }
```
```js
export { foo, bar }
@@ -47,28 +60,22 @@ given file-f:
```js
import { e } from 'file-a'
import { f } from 'file-b'
import * from 'file-c'
export * from 'file-d'
export { default, i0 } from 'file-e' // both will be reported
import * as fileC from 'file-c'
export { default, i0 } from 'file-d' // both will be reported

export const j = 99 // will be reported
export const j = 99 // will be reported
```
and file-e:
and file-d:
```js
export const i0 = 9 // will not be reported
export const i1 = 9 // will be reported
export default () => {} // will not be reported
```
and file-d:
and file-c:
```js
export const h = 8 // will not be reported
export default () => {} // will be reported, as export * only considers named exports and ignores default exports
```
and file-c:
```js
export const g = 7 // will not be reported
export default () => {} // will not be reported
```
and file-b:
```js
import two, { b, c, doAnything } from 'file-a'
@@ -94,7 +101,8 @@ export function doAnything() {
export default 5 // will not be reported
```


#### Important Note
Exports from files listed as a main file (`main`, `browser`, or `bin` fields in `package.json`) will be ignored by default. This only applies if the `package.json` is not set to `private: true`

## When not to use

19 changes: 14 additions & 5 deletions docs/rules/no-useless-path-segments.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# import/no-useless-path-segments

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Use this rule to prevent unnecessary path segments in import and require statements.

## Rule Details
@@ -14,6 +18,7 @@ my-project
└── helpers.js
└── helpers
└── index.js
├── index.js
└── pages
├── about.js
├── contact.js
@@ -27,10 +32,10 @@ The following patterns are considered problems:
* in my-project/app.js
*/

import "./../pages/about.js"; // should be "./pages/about.js"
import "./../pages/about"; // should be "./pages/about"
import "../pages/about.js"; // should be "./pages/about.js"
import "../pages/about"; // should be "./pages/about"
import "./../my-project/pages/about.js"; // should be "./pages/about.js"
import "./../my-project/pages/about"; // should be "./pages/about"
import "../my-project/pages/about.js"; // should be "./pages/about.js"
import "../my-project/pages/about"; // should be "./pages/about"
import "./pages//about"; // should be "./pages/about"
import "./pages/"; // should be "./pages"
import "./pages/index"; // should be "./pages" (except if there is a ./pages.js file)
@@ -72,4 +77,8 @@ import "./pages/index"; // should be "./pages" (auto-fixable)
import "./pages/index.js"; // should be "./pages" (auto-fixable)
```

Note: `noUselessIndex` only avoids ambiguous imports for `.js` files if you haven't specified other resolved file extensions. See [Settings: import/extensions](https://github.com/benmosher/eslint-plugin-import#importextensions) for details.
Note: `noUselessIndex` only avoids ambiguous imports for `.js` files if you haven't specified other resolved file extensions. See [Settings: import/extensions](https://github.com/import-js/eslint-plugin-import#importextensions) for details.

### commonjs

When set to `true`, this rule checks CommonJS imports. Default to `false`.
6 changes: 4 additions & 2 deletions docs/rules/no-webpack-loader-syntax.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# import/no-webpack-loader-syntax

<!-- end auto-generated rule header -->

Forbid Webpack loader syntax in imports.

[Webpack](http://webpack.github.io) allows specifying the [loaders](http://webpack.github.io/docs/loaders.html) to use in the import source string using a special syntax like this:
[Webpack](https://webpack.js.org) allows specifying the [loaders](https://webpack.js.org/concepts/loaders/) to use in the import source string using a special syntax like this:
```js
var moduleWithOneLoader = require("my-loader!./my-awesome-module");
```

This syntax is non-standard, so it couples the code to Webpack. The recommended way to specify Webpack loader configuration is in a [Webpack configuration file](http://webpack.github.io/docs/loaders.html#loaders-by-config).
This syntax is non-standard, so it couples the code to Webpack. The recommended way to specify Webpack loader configuration is in a [Webpack configuration file](https://webpack.js.org/concepts/loaders/#configuration).

## Rule Details

224 changes: 207 additions & 17 deletions docs/rules/order.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# import/order: Enforce a convention in module import order
# import/order

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Enforce a convention in the order of `require()` / `import` statements.
+(fixable) The `--fix` option on the [command line] automatically fixes problems reported by this rule.
The order is as shown in the following example:

```js
With the [`groups`](#groups-array) option set to `["builtin", "external", "internal", "parent", "sibling", "index", "object", "type"]` the order is as shown in the following example:

```ts
// 1. node "builtin" modules
import fs from 'fs';
import path from 'path';
@@ -22,6 +27,10 @@ import bar from './bar';
import baz from './bar/baz';
// 6. "index" of the current directory
import main from './';
// 7. "object"-imports (only available in TypeScript)
import log = console.log;
// 8. "type" imports (only available in Flow and TypeScript)
import type { Foo } from 'foo';
```

Unassigned imports are ignored, as the order they are imported in may be important.
@@ -31,7 +40,7 @@ Statements using the ES6 `import` syntax must appear before any `require()` stat

## Fail

```js
```ts
import _ from 'lodash';
import path from 'path'; // `path` import should occur before import of `lodash`

@@ -49,7 +58,7 @@ import foo from './foo'; // `import` statements must be before `require` stateme

## Pass

```js
```ts
import path from 'path';
import _ from 'lodash';

@@ -77,44 +86,156 @@ This rule supports the following options:

### `groups: [array]`:

How groups are defined, and the order to respect. `groups` must be an array of `string` or [`string`]. The only allowed `string`s are: `"builtin"`, `"external"`, `"internal"`, `"parent"`, `"sibling"`, `"index"`. The enforced order is the same as the order of each element in a group. Omitted types are implicitly grouped together as the last element. Example:
```js
How groups are defined, and the order to respect. `groups` must be an array of `string` or [`string`]. The only allowed `string`s are:
`"builtin"`, `"external"`, `"internal"`, `"unknown"`, `"parent"`, `"sibling"`, `"index"`, `"object"`, `"type"`.
The enforced order is the same as the order of each element in a group. Omitted types are implicitly grouped together as the last element. Example:
```ts
[
'builtin', // Built-in types are first
['sibling', 'parent'], // Then sibling and parent types. They can be mingled together
'index', // Then the index file
'object',
// Then the rest: internal and external type
]
```
The default value is `["builtin", "external", "parent", "sibling", "index"]`.

You can set the options like this:

```js
"import/order": ["error", {"groups": ["index", "sibling", "parent", "internal", "external", "builtin"]}]
```ts
"import/order": [
"error",
{
"groups": [
"index",
"sibling",
"parent",
"internal",
"external",
"builtin",
"object",
"type"
]
}
]
```

### `newlines-between: [ignore|always|always-and-inside-groups|never]`:
### `pathGroups: [array of objects]`:

To be able to group by paths mostly needed with aliases pathGroups can be defined.

Properties of the objects

| property | required | type | description |
|----------------|:--------:|--------|---------------|
| pattern | x | string | minimatch pattern for the paths to be in this group (will not be used for builtins or externals) |
| patternOptions | | object | options for minimatch, default: { nocomment: true } |
| group | x | string | one of the allowed groups, the pathGroup will be positioned relative to this group |
| position | | string | defines where around the group the pathGroup will be positioned, can be 'after' or 'before', if not provided pathGroup will be positioned like the group |

```json
{
"import/order": ["error", {
"pathGroups": [
{
"pattern": "~/**",
"group": "external"
}
]
}]
}
```

### `distinctGroup: [boolean]`:

This changes how `pathGroups[].position` affects grouping. The property is most useful when `newlines-between` is set to `always` and at least 1 `pathGroups` entry has a `position` property set.

By default, in the context of a particular `pathGroup` entry, when setting `position`, a new "group" will silently be created. That is, even if the `group` is specified, a newline will still separate imports that match that `pattern` with the rest of the group (assuming `newlines-between` is `always`). This is undesirable if your intentions are to use `position` to position _within_ the group (and not create a new one). Override this behavior by setting `distinctGroup` to `false`; this will keep imports within the same group as intended.

Note that currently, `distinctGroup` defaults to `true`. However, in a later update, the default will change to `false`

Example:
```json
{
"import/order": ["error", {
"newlines-between": "always",
"pathGroups": [
{
"pattern": "@app/**",
"group": "external",
"position": "after"
}
],
"distinctGroup": false
}]
}
```

### `pathGroupsExcludedImportTypes: [array]`:

This defines import types that are not handled by configured pathGroups.
This is mostly needed when you want to handle path groups that look like external imports.

Example:
```json
{
"import/order": ["error", {
"pathGroups": [
{
"pattern": "@app/**",
"group": "external",
"position": "after"
}
],
"pathGroupsExcludedImportTypes": ["builtin"]
}]
}
```

You can also use `patterns`(e.g., `react`, `react-router-dom`, etc).

Example:
```json
{
"import/order": [
"error",
{
"pathGroups": [
{
"pattern": "react",
"group": "builtin",
"position": "before"
}
],
"pathGroupsExcludedImportTypes": ["react"]
}
]
}
```
The default value is `["builtin", "external", "object"]`.

### `newlines-between: [ignore|always|always-and-inside-groups|never]`:

Enforces or forbids new lines between import groups:

- If set to `ignore`, no errors related to new lines between import groups will be reported (default).
- If set to `ignore`, no errors related to new lines between import groups will be reported.
- If set to `always`, at least one new line between each group will be enforced, and new lines inside a group will be forbidden. To prevent multiple lines between imports, core `no-multiple-empty-lines` rule can be used.
- If set to `always-and-inside-groups`, it will act like `always` except newlines are allowed inside import groups.
- If set to `never`, no new lines are allowed in the entire import section.

The default value is `"ignore"`.

With the default group setting, the following will be invalid:

```js
```ts
/* eslint import/order: ["error", {"newlines-between": "always"}] */
import fs from 'fs';
import path from 'path';
import index from './';
import sibling from './foo';
```

```js
```ts
/* eslint import/order: ["error", {"newlines-between": "always-and-inside-groups"}] */
import fs from 'fs';

@@ -123,7 +244,7 @@ import index from './';
import sibling from './foo';
```

```js
```ts
/* eslint import/order: ["error", {"newlines-between": "never"}] */
import fs from 'fs';
import path from 'path';
@@ -135,7 +256,7 @@ import sibling from './foo';

while those will be valid:

```js
```ts
/* eslint import/order: ["error", {"newlines-between": "always"}] */
import fs from 'fs';
import path from 'path';
@@ -145,7 +266,7 @@ import index from './';
import sibling from './foo';
```

```js
```ts
/* eslint import/order: ["error", {"newlines-between": "always-and-inside-groups"}] */
import fs from 'fs';

@@ -156,16 +277,85 @@ import index from './';
import sibling from './foo';
```

```js
```ts
/* eslint import/order: ["error", {"newlines-between": "never"}] */
import fs from 'fs';
import path from 'path';
import index from './';
import sibling from './foo';
```

### `alphabetize: {order: asc|desc|ignore, orderImportKind: asc|desc|ignore, caseInsensitive: true|false}`:

Sort the order within each group in alphabetical manner based on **import path**:

- `order`: use `asc` to sort in ascending order, and `desc` to sort in descending order (default: `ignore`).
- `orderImportKind`: use `asc` to sort in ascending order various import kinds, e.g. imports prefixed with `type` or `typeof`, with same import path. Use `desc` to sort in descending order (default: `ignore`).
- `caseInsensitive`: use `true` to ignore case, and `false` to consider case (default: `false`).

Example setting:
```ts
alphabetize: {
order: 'asc', /* sort in ascending order. Options: ['ignore', 'asc', 'desc'] */
caseInsensitive: true /* ignore case. Options: [true, false] */
}
```

This will fail the rule check:

```ts
/* eslint import/order: ["error", {"alphabetize": {"order": "asc", "caseInsensitive": true}}] */
import React, { PureComponent } from 'react';
import aTypes from 'prop-types';
import { compose, apply } from 'xcompose';
import * as classnames from 'classnames';
import blist from 'BList';
```

While this will pass:

```ts
/* eslint import/order: ["error", {"alphabetize": {"order": "asc", "caseInsensitive": true}}] */
import blist from 'BList';
import * as classnames from 'classnames';
import aTypes from 'prop-types';
import React, { PureComponent } from 'react';
import { compose, apply } from 'xcompose';
```

### `warnOnUnassignedImports: true|false`:

* default: `false`

Warns when unassigned imports are out of order. These warning will not be fixed
with `--fix` because unassigned imports are used for side-effects and changing the
import of order of modules with side effects can not be done automatically in a
way that is safe.

This will fail the rule check:

```ts
/* eslint import/order: ["error", {"warnOnUnassignedImports": true}] */
import fs from 'fs';
import './styles.css';
import path from 'path';
```

While this will pass:

```ts
/* eslint import/order: ["error", {"warnOnUnassignedImports": true}] */
import fs from 'fs';
import path from 'path';
import './styles.css';
```

## Related

- [`import/external-module-folders`] setting

- [`import/internal-regex`] setting

[`import/external-module-folders`]: ../../README.md#importexternal-module-folders

[`import/internal-regex`]: ../../README.md#importinternal-regex
132 changes: 130 additions & 2 deletions docs/rules/prefer-default-export.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,45 @@
# import/prefer-default-export

When there is only a single export from a module, prefer using default export over named export.
<!-- end auto-generated rule header -->

In exporting files, this rule checks if there is default export or not.

## Rule Details

##### rule schema:

```javascript
"import/prefer-default-export": [
( "off" | "warn" | "error" ),
{ "target": "single" | "any" } // default is "single"
]
```

### Config Options

There are two options available: `single` and `any`. By default, if you do not specify the option, rule will assume it is `single`.

#### single

**Definition**: When there is only a single export from a module, prefer using default export over named export.

How to setup config file for this rule:

```javascript
// you can manually specify it
"rules": {
"import/prefer-default-export": [
( "off" | "warn" | "error" ),
{ "target": "single" }
]
}

// config setup below will also work
"rules": {
"import/prefer-default-export": "off" | "warn" | "error"
}
```

The following patterns are considered warnings:

```javascript
@@ -22,7 +58,7 @@ The following patterns are not warnings:
// There is a default export.
export const foo = 'foo';
const bar = 'bar';
export default 'bar';
export default bar;
```

```javascript
@@ -56,3 +92,95 @@ export { foo as default }
// Any batch export will disable this rule. The remote module is not inspected.
export * from './other-module'
```

#### any

**Definition**: any exporting file must contain a default export.

How to setup config file for this rule:

```javascript
// you have to manually specify it
"rules": {
"import/prefer-default-export": [
( "off" | "warn" | "error" ),
{ "target": "any" }
]
}
```


The following patterns are *not* considered warnings:

```javascript
// good1.js

//has default export
export default function bar() {};
```

```javascript
// good2.js

// has default export
let foo;
export { foo as default }
```

```javascript
// good3.js

//contains multiple exports AND default export
export const a = 5;
export function bar(){};
let foo;
export { foo as default }
```

```javascript
// good4.js

// does not contain any exports => file is not checked by the rule
import * as foo from './foo';
```

```javascript
// export-star.js

// Any batch export will disable this rule. The remote module is not inspected.
export * from './other-module'
```

The following patterns are considered warnings:

```javascript
// bad1.js

//has 2 named exports, but no default export
export const foo = 'foo';
export const bar = 'bar';
```

```javascript
// bad2.js

// does not have default export
let foo, bar;
export { foo, bar }
```

```javascript
// bad3.js

// does not have default export
export { a, b } from "foo.js"
```

```javascript
// bad4.js

// does not have default export
let item;
export const foo = item;
export { item };
```
Loading