Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat!: add support for Node.js ESM resolution #4

Merged
merged 5 commits into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/coverage
/docs
/node_modules
/lib/converted-esm
3 changes: 2 additions & 1 deletion .nycrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
],
"exclude": [
"lib/rules/no-hide-core-modules.js",
"lib/rules/no-unsupported-features.js"
"lib/rules/no-unsupported-features.js",
"lib/converted-esm/*.js"
],
"reporter": [
"lcov",
Expand Down
81 changes: 37 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

> forked from [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node) v11.1.0. as the original repository seems [no longer maintained](https://github.com/mysticatea/eslint-plugin-node/issues/300).

[![npm version](https://img.shields.io/npm/v/eslint-plugin-n.svg)](https://www.npmjs.com/package/eslint-plugin-n)
[![Downloads/month](https://img.shields.io/npm/dm/eslint-plugin-n.svg)](http://www.npmtrends.com/eslint-plugin-n)
[![Build Status](https://github.com/weiran-zsd/eslint-plugin-node/workflows/CI/badge.svg)](https://github.com/weiran-zsd/eslint-plugin-node/actions)
[![Coverage Status](https://codecov.io/gh/weiran-zsd/eslint-plugin-node/branch/master/graph/badge.svg)](https://codecov.io/gh/weiran-zsd/eslint-plugin-node)
[![Dependency Status](https://david-dm.org/weiran-zsd/eslint-plugin-node.svg)](https://david-dm.org/weiran-zsd/eslint-plugin-node)
[![npm version](https://img.shields.io/npm/v/eslint-plugin-n.svg)](https://www.npmjs.com/package/eslint-plugin-n) [![Downloads/month](https://img.shields.io/npm/dm/eslint-plugin-n.svg)](http://www.npmtrends.com/eslint-plugin-n) [![Build Status](https://github.com/weiran-zsd/eslint-plugin-node/workflows/CI/badge.svg)](https://github.com/weiran-zsd/eslint-plugin-node/actions) [![Coverage Status](https://codecov.io/gh/weiran-zsd/eslint-plugin-node/branch/master/graph/badge.svg)](https://codecov.io/gh/weiran-zsd/eslint-plugin-node) [![Dependency Status](https://david-dm.org/weiran-zsd/eslint-plugin-node.svg)](https://david-dm.org/weiran-zsd/eslint-plugin-node)

Additional ESLint's rules for Node.js

Expand All @@ -16,19 +12,16 @@ Additional ESLint's rules for Node.js
$ npm install --save-dev eslint eslint-plugin-n
```

- Requires Node.js `>=12.22.0`
- Requires ESLint `>=7.0.0`
- Requires Node.js `>=12.22.0`
- Requires ESLint `>=7.0.0`

**Note:** It recommends a use of [the "engines" field of package.json](https://docs.npmjs.com/files/package.json#engines). The "engines" field is used by `n/no-unsupported-features/*` rules.

**.eslintrc.json** (An example)

```jsonc
{
"extends": [
"eslint:recommended",
"plugin:n/recommended"
],
"extends": ["eslint:recommended", "plugin:n/recommended"],
"parserOptions": {
// Only ESLint 6.2.0 and later support ES2020.
"ecmaVersion": 2020
Expand Down Expand Up @@ -62,8 +55,8 @@ $ npm install --save-dev eslint eslint-plugin-n

## 📖 Rules

- ⭐️ - the mark of recommended rules.
- ✒️ - the mark of fixable rules.
- ⭐️ - the mark of recommended rules.
- ✒️ - the mark of fixable rules.

<!--RULES_TABLE_START-->
### Possible Errors
Expand Down Expand Up @@ -133,48 +126,48 @@ These rules have been deprecated in accordance with the [deprecation policy](htt

This plugin provides three configs:

- `plugin:n/recommended` considers both CommonJS and ES Modules. If [`"type":"module"` field](https://medium.com/@nodejs/announcing-a-new-experimental-modules-1be8d2d6c2ff#b023) existed in package.json then it considers files as ES Modules. Otherwise it considers files as CommonJS. In addition, it considers `*.mjs` files as ES Modules and `*.cjs` files as CommonJS.
- `plugin:n/recommended-module` considers all files as ES Modules.
- `plugin:n/recommended-script` considers all files as CommonJS.
- `plugin:n/recommended` considers both CommonJS and ES Modules. If [`"type":"module"` field](https://medium.com/@nodejs/announcing-a-new-experimental-modules-1be8d2d6c2ff#b023) existed in package.json then it considers files as ES Modules. Otherwise it considers files as CommonJS. In addition, it considers `*.mjs` files as ES Modules and `*.cjs` files as CommonJS.
- `plugin:n/recommended-module` considers all files as ES Modules.
- `plugin:n/recommended-script` considers all files as CommonJS.

Those preset config:

- enable [no-process-exit](http://eslint.org/docs/rules/no-process-exit) rule because [the official document](https://nodejs.org/api/process.html#process_process_exit_code) does not recommend a use of `process.exit()`.
- enable plugin rules which are given :star: in the above table.
- add `{ecmaVersion: 2019}` and etc into `parserOptions`.
- add proper globals into `globals`.
- add this plugin into `plugins`.
- enable [no-process-exit](http://eslint.org/docs/rules/no-process-exit) rule because [the official document](https://nodejs.org/api/process.html#process_process_exit_code) does not recommend a use of `process.exit()`.
- enable plugin rules which are given :star: in the above table.
- add `{ecmaVersion: 2019}` and etc into `parserOptions`.
- add proper globals into `globals`.
- add this plugin into `plugins`.

## 👫 FAQ

- Q: The `no-missing-import` / `no-missing-require` rules don't work with nested folders in SublimeLinter-eslint
- A: See [context.getFilename() in rule returns relative path](https://github.com/roadhump/SublimeLinter-eslint#contextgetfilename-in-rule-returns-relative-path) in the SublimeLinter-eslint FAQ.
- Q: The `no-missing-import` / `no-missing-require` rules don't work with nested folders in SublimeLinter-eslint
- A: See [context.getFilename() in rule returns relative path](https://github.com/roadhump/SublimeLinter-eslint#contextgetfilename-in-rule-returns-relative-path) in the SublimeLinter-eslint FAQ.

## 🚥 Semantic Versioning Policy

`eslint-plugin-n` follows [semantic versioning](http://semver.org/) and [ESLint's Semantic Versioning Policy](https://github.com/eslint/eslint#semantic-versioning-policy).

- Patch release (intended to not break your lint build)
- A bug fix in a rule that results in it reporting fewer errors.
- Improvements to documentation.
- Non-user-facing changes such as refactoring code, adding, deleting, or modifying tests, and increasing test coverage.
- Re-releasing after a failed release (i.e., publishing a release that doesn't work for anyone).
- Minor release (might break your lint build)
- A bug fix in a rule that results in it reporting more errors.
- A new rule is created.
- A new option to an existing rule is created.
- An existing rule is deprecated.
- Major release (likely to break your lint build)
- A support for old Node version is dropped.
- A support for old ESLint version is dropped.
- An existing rule is changed in it reporting more errors.
- An existing rule is removed.
- An existing option of a rule is removed.
- An existing config is updated.
- Patch release (intended to not break your lint build)
- A bug fix in a rule that results in it reporting fewer errors.
- Improvements to documentation.
- Non-user-facing changes such as refactoring code, adding, deleting, or modifying tests, and increasing test coverage.
- Re-releasing after a failed release (i.e., publishing a release that doesn't work for anyone).
- Minor release (might break your lint build)
- A bug fix in a rule that results in it reporting more errors.
- A new rule is created.
- A new option to an existing rule is created.
- An existing rule is deprecated.
- Major release (likely to break your lint build)
- A support for old Node version is dropped.
- A support for old ESLint version is dropped.
- An existing rule is changed in it reporting more errors.
- An existing rule is removed.
- An existing option of a rule is removed.
- An existing config is updated.

## 📰 Changelog

- [GitHub Releases](https://github.com/weiran-zsd/eslint-plugin-n/releases)
- [GitHub Releases](https://github.com/weiran-zsd/eslint-plugin-n/releases)

## ❤️ Contributing

Expand All @@ -184,6 +177,6 @@ Please use GitHub's Issues/PRs.

### Development Tools

- `npm test` runs tests and measures coverage.
- `npm run coverage` shows the coverage result of `npm test` command.
- `npm run clean` removes the coverage result of `npm test` command.
- `npm test` runs tests and measures coverage.
- `npm run coverage` shows the coverage result of `npm test` command.
- `npm run clean` removes the coverage result of `npm test` command.
23 changes: 0 additions & 23 deletions docs/rules/file-extension-in-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ This rule has a string option and an object option.
"error",
"always" or "never",
{
"tryExtensions": [".js", ".json", ".node"],
".xxx": "always" or "never",
}
]
Expand All @@ -36,7 +35,6 @@ This rule has a string option and an object option.

- `"always"` (default) requires file extensions in `import`/`export` declarations.
- `"never"` disallows file extensions in `import`/`export` declarations.
- `tryExtensions` is the file extensions to resolve import paths. Default is `[".js", ".json", ".node"]`.
- `.xxx` is the overriding setting for specific file extensions. You can use arbitrary property names which start with `.`.

#### always
Expand Down Expand Up @@ -90,27 +88,6 @@ import styles from "./styles.css"
import logo from "./logo.png"
```

### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `tryExtensions`

```js
// .eslintrc.js
module.exports = {
"settings": {
"node": {
"tryExtensions": [".js", ".json", ".node"]
}
},
"rules": {
"n/file-extension-in-import": "error"
}
}
```

## 🔎 Implementation

- [Rule source](../../lib/rules/file-extension-in-import.js)
Expand Down
12 changes: 1 addition & 11 deletions docs/rules/no-extraneous-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ This rule warns `import` declarations of extraneous modules.
"rules": {
"n/no-extraneous-import": ["error", {
"allowModules": [],
"resolvePaths": [],
"tryExtensions": []
"resolvePaths": []
}]
}
}
Expand Down Expand Up @@ -48,21 +47,13 @@ If a path is relative, it will be resolved from CWD.

Default is `[]`

#### tryExtensions

When an import path does not exist, this rule checks whether or not any of `path.js`, `path.json`, and `path.node` exists.
`tryExtensions` option is the extension list this rule uses at the time.

Default is `[".js", ".json", ".node"]`.

### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `allowModules`
- `resolvePaths`
- `tryExtensions`

```js
// .eslintrc.js
Expand All @@ -71,7 +62,6 @@ module.exports = {
"node": {
"allowModules": ["electron"],
"resolvePaths": [__dirname],
"tryExtensions": [".js", ".json", ".node"]
}
},
"rules": {
Expand Down
12 changes: 1 addition & 11 deletions docs/rules/no-missing-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ import existingModule from "existing-module";
"rules": {
"n/no-missing-import": ["error", {
"allowModules": [],
"resolvePaths": ["/path/to/a/modules/directory"],
"tryExtensions": [".js", ".json", ".node"]
"resolvePaths": ["/path/to/a/modules/directory"]
}]
}
}
Expand Down Expand Up @@ -68,21 +67,13 @@ If a path is relative, it will be resolved from CWD.

Default is `[]`

#### tryExtensions

When an import path does not exist, this rule checks whether or not any of `path.js`, `path.json`, and `path.node` exists.
`tryExtensions` option is the extension list this rule uses at the time.

Default is `[".js", ".json", ".node"]`.

### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `allowModules`
- `resolvePaths`
- `tryExtensions`

```js
// .eslintrc.js
Expand All @@ -91,7 +82,6 @@ module.exports = {
"node": {
"allowModules": ["electron"],
"resolvePaths": [__dirname],
"tryExtensions": [".js", ".json", ".node"]
}
},
"rules": {
Expand Down
17 changes: 3 additions & 14 deletions docs/rules/no-unpublished-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ Then this rule warns `import` declarations in \*published\* files if the `import
"rules": {
"n/no-unpublished-import": ["error", {
"allowModules": [],
"convertPath": null,
"tryExtensions": [".js", ".json", ".node"]
"convertPath": null
}]
}
}
Expand Down Expand Up @@ -63,8 +62,7 @@ For example:
"n/no-unpublished-import": ["error", {
"convertPath": {
"src/**/*.jsx": ["^src/(.+?)\\.jsx$", "lib/$1.js"]
},
"tryExtensions": [".js", ".jsx", ".json"]
}
}]
}
}
Expand Down Expand Up @@ -104,21 +102,13 @@ For example:
In this style, this option has the following shape as the same expression as above: `{include: [<targetFiles>], replace: [<fromRegExp>, <toString>]}`.
In addition, we can specify glob patterns to exclude files.

#### tryExtensions

When an import path does not exist, this rule checks whether or not any of `path.js`, `path.json`, and `path.node` exists.
`tryExtensions` option is the extension list this rule uses at the time.

Default is `[".js", ".json", ".node"]`.

### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `allowModules`
- `convertPath`
- `tryExtensions`

For Example:

Expand All @@ -129,8 +119,7 @@ For Example:
"allowModules": ["electron"],
"convertPath": {
"src/**/*.jsx": ["^src/(.+?)\\.jsx$", "lib/$1.js"]
},
"tryExtensions": [".js", ".jsx", ".json"]
}
}
},
"rules": {
Expand Down