Skip to content

Commit a7e393c

Browse files
fiskersindresorhus
andauthored
Add prefer-module rule (#1141)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 65378cb commit a7e393c

File tree

10 files changed

+2073
-11
lines changed

10 files changed

+2073
-11
lines changed

docs/rules/prefer-module.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Prefer JavaScript modules (ESM) over CommonJS
2+
3+
Prefer using the [JavaScript module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) format over the legacy CommonJS module format.
4+
5+
1. Forbids `'use strict'` directive.
6+
7+
JavaScript modules use “Strict Mode” by default.
8+
9+
1. Forbids “Global Return”.
10+
11+
This is a CommonJS-only feature.
12+
13+
1. Forbids the global variables `__dirname` and `__filename`.
14+
15+
They are [not available in JavaScript modules](https://nodejs.org/api/esm.html#esm_no_filename_or_dirname).
16+
17+
Replacements:
18+
19+
```js
20+
import {fileURLToPath} from 'url';
21+
import path from 'path';
22+
23+
const __filename = fileURLToPath(import.meta.url);
24+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
25+
```
26+
27+
However, in most cases, this is better:
28+
29+
```js
30+
import {fileURLToPath} from 'url';
31+
32+
const foo = fileURLToPath(new URL('foo.js', import.meta.url));
33+
```
34+
35+
And many Node.js APIs accept `URL` directly, so you can just do this:
36+
37+
```js
38+
const foo = new URL('foo.js', import.meta.url);
39+
```
40+
41+
1. Forbids `require(…)`.
42+
43+
`require(…)` can be replaced by `import …` or `import(…)`.
44+
45+
1. Forbids `exports` and `module.exports`.
46+
47+
`export …` should be used in JavaScript modules.
48+
49+
## Fail
50+
51+
```js
52+
'use strict';
53+
54+
//
55+
```
56+
57+
```js
58+
if (foo) {
59+
return;
60+
}
61+
62+
//
63+
```
64+
65+
```js
66+
const file = path.join(__dirname, 'foo.js');
67+
```
68+
69+
```js
70+
const content = fs.readFileSync(__filename, 'utf8');
71+
```
72+
73+
```js
74+
const {fromPairs} = require('lodash');
75+
```
76+
77+
```js
78+
module.exports = foo;
79+
```
80+
81+
```js
82+
exports.foo = foo;
83+
```
84+
85+
## Pass
86+
87+
```js
88+
function run() {
89+
if (foo) {
90+
return;
91+
}
92+
93+
//
94+
}
95+
96+
run();
97+
```
98+
99+
```js
100+
const file = fileURLToPath(new URL('foo.js', import.meta.url));
101+
```
102+
103+
```js
104+
import {fromPairs} from 'lodash-es';
105+
```
106+
107+
```js
108+
export default foo;
109+
```
110+
111+
```js
112+
export {foo};
113+
```
114+
115+
## Resources
116+
117+
- [Get Ready For ESM](https://blog.sindresorhus.com/get-ready-for-esm-aa53530b3f77) by @sindresorhus

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ module.exports = {
9999
'unicorn/prefer-keyboard-event-key': 'error',
100100
'unicorn/prefer-math-trunc': 'error',
101101
'unicorn/prefer-modern-dom-apis': 'error',
102+
'unicorn/prefer-module': 'error',
102103
'unicorn/prefer-negative-index': 'error',
103104
'unicorn/prefer-number-properties': 'error',
104105
'unicorn/prefer-optional-catch-binding': 'error',

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Configure it in `package.json`.
9090
"unicorn/prefer-keyboard-event-key": "error",
9191
"unicorn/prefer-math-trunc": "error",
9292
"unicorn/prefer-modern-dom-apis": "error",
93+
"unicorn/prefer-module": "error",
9394
"unicorn/prefer-negative-index": "error",
9495
"unicorn/prefer-number-properties": "error",
9596
"unicorn/prefer-optional-catch-binding": "error",
@@ -181,6 +182,7 @@ Each rule has emojis denoting:
181182
| [prefer-keyboard-event-key](docs/rules/prefer-keyboard-event-key.md) | Prefer `KeyboardEvent#key` over `KeyboardEvent#keyCode`. || 🔧 |
182183
| [prefer-math-trunc](docs/rules/prefer-math-trunc.md) | Enforce the use of `Math.trunc` instead of bitwise operators. || 🔧 |
183184
| [prefer-modern-dom-apis](docs/rules/prefer-modern-dom-apis.md) | Prefer `.before()` over `.insertBefore()`, `.replaceWith()` over `.replaceChild()`, prefer one of `.before()`, `.after()`, `.append()` or `.prepend()` over `insertAdjacentText()` and `insertAdjacentElement()`. || 🔧 |
185+
| [prefer-module](docs/rules/prefer-module.md) | Prefer JavaScript modules (ESM) over CommonJS. || 🔧 |
184186
| [prefer-negative-index](docs/rules/prefer-negative-index.md) | Prefer negative index over `.length - index` for `{String,Array,TypedArray}#slice()` and `Array#splice()`. || 🔧 |
185187
| [prefer-number-properties](docs/rules/prefer-number-properties.md) | Prefer `Number` static properties over global ones. || 🔧 |
186188
| [prefer-optional-catch-binding](docs/rules/prefer-optional-catch-binding.md) | Prefer omitting the `catch` binding parameter. || 🔧 |

0 commit comments

Comments
 (0)