@hs-web-team/eslint-config-node 2.1.2 → 3.0.0-next.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/main.yml +4 -4
- package/.github/workflows/pr.yml +3 -3
- package/.github/workflows/release.yml +16 -4
- package/CLAUDE.md +69 -0
- package/README.md +29 -14
- package/docs/MIGRATION-V3.md +290 -0
- package/index.js +66 -42
- package/package.json +13 -6
|
@@ -11,13 +11,13 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
strategy:
|
|
13
13
|
matrix:
|
|
14
|
-
node: [
|
|
14
|
+
node: [22, 24]
|
|
15
15
|
|
|
16
|
-
name: Node ${{ matrix.node }}
|
|
16
|
+
name: Node ${{ matrix.node }} lint
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v5
|
|
19
19
|
- name: Run unit tests
|
|
20
|
-
uses: actions/setup-node@
|
|
20
|
+
uses: actions/setup-node@v6
|
|
21
21
|
with:
|
|
22
22
|
node-version: ${{ matrix.node }}
|
|
23
23
|
- run: npm install
|
package/.github/workflows/pr.yml
CHANGED
|
@@ -11,13 +11,13 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
strategy:
|
|
13
13
|
matrix:
|
|
14
|
-
node: [
|
|
14
|
+
node: [22, 24]
|
|
15
15
|
|
|
16
16
|
name: Node ${{ matrix.node }} sample
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v5
|
|
19
19
|
- name: Run unit tests
|
|
20
|
-
uses: actions/setup-node@
|
|
20
|
+
uses: actions/setup-node@v6
|
|
21
21
|
with:
|
|
22
22
|
node-version: ${{ matrix.node }}
|
|
23
23
|
- run: npm install
|
|
@@ -7,12 +7,24 @@ jobs:
|
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
8
|
steps:
|
|
9
9
|
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
|
10
|
-
- uses: actions/checkout@
|
|
11
|
-
- uses: actions/setup-node@
|
|
10
|
+
- uses: actions/checkout@v5
|
|
11
|
+
- uses: actions/setup-node@v6
|
|
12
12
|
with:
|
|
13
|
-
node-version:
|
|
13
|
+
node-version: 24
|
|
14
14
|
registry-url: 'https://registry.npmjs.org'
|
|
15
15
|
- run: npm install
|
|
16
|
-
-
|
|
16
|
+
- name: Publish to npm
|
|
17
|
+
run: |
|
|
18
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
19
|
+
if [[ "$VERSION" =~ -next\. ]]; then
|
|
20
|
+
echo "Publishing prerelease version $VERSION with tag 'next'"
|
|
21
|
+
npm publish --tag next
|
|
22
|
+
elif [[ "$VERSION" =~ -(alpha|beta|rc)\. ]]; then
|
|
23
|
+
echo "Publishing prerelease version $VERSION with tag 'next'"
|
|
24
|
+
npm publish --tag next
|
|
25
|
+
else
|
|
26
|
+
echo "Publishing stable version $VERSION"
|
|
27
|
+
npm publish
|
|
28
|
+
fi
|
|
17
29
|
env:
|
|
18
30
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This is an ESLint configuration package (`@hs-web-team/eslint-config-node`) for HubSpot Marketing WebTeam Node.js projects. It provides shared ESLint rules and Prettier configuration for backend Node.js projects.
|
|
8
|
+
|
|
9
|
+
## Key Commands
|
|
10
|
+
|
|
11
|
+
### Linting
|
|
12
|
+
```bash
|
|
13
|
+
npm run lint
|
|
14
|
+
```
|
|
15
|
+
Runs ESLint on the codebase with auto-fix enabled. Uses the configuration defined in `index.js`.
|
|
16
|
+
|
|
17
|
+
### Testing in Projects
|
|
18
|
+
When testing changes to this package in downstream projects, you'll typically:
|
|
19
|
+
1. Make changes to the ESLint config in `index.js`
|
|
20
|
+
2. Run `npm link` in this repository
|
|
21
|
+
3. Run `npm link @hs-web-team/eslint-config-node` in the consuming project
|
|
22
|
+
4. Test the linting behavior in the consuming project
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
### Core Configuration File
|
|
27
|
+
- **`index.js`**: The main ESLint configuration export using ESLint 9's flat config format
|
|
28
|
+
- Uses `@eslint/js`, `typescript-eslint`, and `globals` packages
|
|
29
|
+
- Exports an array of configuration objects (flat config format)
|
|
30
|
+
- Structure:
|
|
31
|
+
1. Global ignores object
|
|
32
|
+
2. `js.configs.recommended` for JavaScript baseline
|
|
33
|
+
3. JavaScript-specific config for `**/*.{js,mjs,cjs}` files
|
|
34
|
+
4. Spreads `tseslint.configs.recommended` for TypeScript baseline
|
|
35
|
+
5. TypeScript-specific config for `**/*.{ts,mts,cts,tsx}` files
|
|
36
|
+
- Includes Node.js, ES2022, and Jest globals
|
|
37
|
+
- Common ignores: `node_modules`, `.serverless`, `.webpack`, `dist`, `eslint.config.js`
|
|
38
|
+
- Key custom rules: `no-console` (allows info/warn/error), `max-len` (120 chars), camelcase disabled
|
|
39
|
+
|
|
40
|
+
### Prettier Integration
|
|
41
|
+
- **`bin/add-prettier-scripts.js`**: Executable script that consuming projects can run to set up Prettier
|
|
42
|
+
- Uses CommonJS (`require`) syntax (different from the main package which is ESM)
|
|
43
|
+
- Adds `prettier:check` and `prettier:write` scripts to package.json
|
|
44
|
+
- Creates `.prettierrc.js` file that imports from this package's `.prettierrc.json`
|
|
45
|
+
- Creates `.prettierignore` file with sensible defaults (npm-shrinkwrap.json, package-lock.json, .eslintrc, *.html)
|
|
46
|
+
- **`.prettierrc.json`**: Shared Prettier configuration
|
|
47
|
+
- 120 char width, single quotes, 2-space tabs, trailing commas
|
|
48
|
+
- Arrow parens: avoid, LF line endings, single attribute per line
|
|
49
|
+
- Override for YAML files: uses double quotes instead of single
|
|
50
|
+
|
|
51
|
+
### Package Details
|
|
52
|
+
- **Type**: ESM module (`"type": "module"`)
|
|
53
|
+
- **Node requirement**: >= 22
|
|
54
|
+
- **Main export**: `index.js`
|
|
55
|
+
- **Binary command**: `add-prettier` maps to `bin/add-prettier-scripts.js`
|
|
56
|
+
|
|
57
|
+
### Migration Context
|
|
58
|
+
This package is currently on v3, which uses ESLint 9's flat config format. The project has migrated from:
|
|
59
|
+
- v1 → v2: See `docs/MIGRATION-V2.md`
|
|
60
|
+
- v2 → v3: See `docs/MIGRATION-V3.md` (ESLint 9 flat config migration requiring Node.js 22+)
|
|
61
|
+
|
|
62
|
+
## Important Notes
|
|
63
|
+
|
|
64
|
+
- This package is for **backend Node.js projects only**, not browser environments
|
|
65
|
+
- The configuration uses ESLint 9's flat config format (not the legacy `.eslintrc` format)
|
|
66
|
+
- Downstream projects extend this config in their `eslint.config.js` by spreading the imported config using `...wtConfig`
|
|
67
|
+
- Mixed module systems: `bin/add-prettier-scripts.js` uses CommonJS (`require`) while the main package is ESM
|
|
68
|
+
- CI runs on Node 22 and 24 (see `.github/workflows/pr.yml`)
|
|
69
|
+
- No automated tests currently (`npm test` will fail with "Error: no test specified")
|
package/README.md
CHANGED
|
@@ -19,23 +19,34 @@ This is a list of ESLint rules that are recommended for use with **Hubspot Marke
|
|
|
19
19
|
npm i -D @hs-web-team/eslint-config-node@latest
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
2. Add to
|
|
22
|
+
2. Add to `eslint.config.js` in project root directory
|
|
23
23
|
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
"extends": "@hs-web-team/eslint-config-node"
|
|
27
|
-
}
|
|
28
|
-
```
|
|
24
|
+
```typescript
|
|
25
|
+
import wtConfig from '@hs-web-team/eslint-config-node';
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
export default [
|
|
28
|
+
...wtConfig,
|
|
29
|
+
];
|
|
30
|
+
```
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
3. Extend the eslint on a project basis by adding rules to `eslint.config.js` e.g.
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import wtConfig from '@hs-web-team/eslint-config-node';
|
|
36
|
+
|
|
37
|
+
export default [
|
|
38
|
+
// Add project-specific ignores here
|
|
39
|
+
{
|
|
40
|
+
ignores: ['dist/**'],
|
|
41
|
+
},
|
|
42
|
+
// Add project-specific rules here
|
|
43
|
+
{
|
|
44
|
+
rules: {
|
|
45
|
+
'no-console': 'error',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
...wtConfig, // This will include the shared rules from @hs-web-team/eslint-config-node
|
|
49
|
+
];
|
|
39
50
|
```
|
|
40
51
|
|
|
41
52
|
## Where to use it
|
|
@@ -67,3 +78,7 @@ This package includes a utility script to automatically add Prettier configurati
|
|
|
67
78
|
## Migration from v1 to v2
|
|
68
79
|
|
|
69
80
|
See [MIGRATION-V2.md](./docs/MIGRATION-V2.md)
|
|
81
|
+
|
|
82
|
+
## Migration from v2 to v3
|
|
83
|
+
|
|
84
|
+
See [MIGRATION-V3.md](./docs/MIGRATION-V3.md)
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Migration from v2 to v3
|
|
2
|
+
|
|
3
|
+
## Steps to migrate
|
|
4
|
+
|
|
5
|
+
> **Note**
|
|
6
|
+
>
|
|
7
|
+
> This migration requires Node.js v22 or higher and a **manual migration** from `.eslintrc` to `eslint.config.mjs`.
|
|
8
|
+
|
|
9
|
+
- [ ] Upgrade to Node.js v22 or higher
|
|
10
|
+
- [ ] Update the package: `npm install -D @hs-web-team/eslint-config-node@latest`
|
|
11
|
+
- [ ] **Remove** `@hs-web-team/eslint-config-ts` from dependencies (no longer needed - TypeScript support is now included)
|
|
12
|
+
- [ ] Remove the `--ext .js,.ts` flag from the ESLint command in your project's package.json
|
|
13
|
+
- [ ] Manually create `eslint.config.mjs` (see [Manual Migration Guide](#manual-migration-guide) below)
|
|
14
|
+
- [ ] Delete `.eslintrc` file
|
|
15
|
+
- [ ] Run `npm run lint` to check for any errors
|
|
16
|
+
- [ ] Fix any linting errors
|
|
17
|
+
- [ ] Commit the changes
|
|
18
|
+
- [ ] Create a PR
|
|
19
|
+
- [ ] Get it approved
|
|
20
|
+
- [ ] Merge it into `main`
|
|
21
|
+
- [ ] Test everything in QA
|
|
22
|
+
- [ ] Celebrate! 🎉
|
|
23
|
+
|
|
24
|
+
> **Important**
|
|
25
|
+
>
|
|
26
|
+
> The automated migration script (`npx @eslint/migrate-config .eslintrc`) **will not work** for most projects migrating from ESLint 8 to ESLint 9. You must manually create the new `eslint.config.js` file.
|
|
27
|
+
>
|
|
28
|
+
> This is because:
|
|
29
|
+
> - ESLint 9 uses a completely different flat config format
|
|
30
|
+
> - The `@hs-web-team/eslint-config-ts` package is no longer needed (TypeScript support is built-in)
|
|
31
|
+
> - Many ESLint plugins have changed their configuration APIs
|
|
32
|
+
|
|
33
|
+
## Manual Migration Guide
|
|
34
|
+
|
|
35
|
+
### Before: Typical `.eslintrc` file
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"extends": [
|
|
40
|
+
"@hs-web-team/eslint-config-node",
|
|
41
|
+
"@hs-web-team/eslint-config-ts"
|
|
42
|
+
],
|
|
43
|
+
"rules": {
|
|
44
|
+
"no-restricted-syntax": 0,
|
|
45
|
+
"no-console": 0,
|
|
46
|
+
"no-param-reassign": 0,
|
|
47
|
+
"no-await-in-loop": 0,
|
|
48
|
+
"max-classes-per-file": 0,
|
|
49
|
+
"import/no-extraneous-dependencies": 0,
|
|
50
|
+
"@typescript-eslint/no-unused-vars": ["error", { "vars": "all", "args": "after-used", "ignoreRestSiblings": true }],
|
|
51
|
+
"@typescript-eslint/no-unnecessary-condition": "error"
|
|
52
|
+
},
|
|
53
|
+
"overrides": [
|
|
54
|
+
{
|
|
55
|
+
"files": ["*.test.ts", "*.spec.ts"],
|
|
56
|
+
"rules": {
|
|
57
|
+
"no-unused-expressions": "off"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"env": {
|
|
62
|
+
"jest": true
|
|
63
|
+
},
|
|
64
|
+
"parserOptions": {
|
|
65
|
+
"project": "./tsconfig.json"
|
|
66
|
+
},
|
|
67
|
+
"globals": {
|
|
68
|
+
"window": true
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### After: New `eslint.config.mjs` file
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
import wtConfig from '@hs-web-team/eslint-config-node';
|
|
77
|
+
import tseslint from 'typescript-eslint';
|
|
78
|
+
|
|
79
|
+
export default [
|
|
80
|
+
// Spread the base config (includes both JS and TS configs)
|
|
81
|
+
...wtConfig,
|
|
82
|
+
|
|
83
|
+
// Add custom rules for all files
|
|
84
|
+
{
|
|
85
|
+
rules: {
|
|
86
|
+
'no-restricted-syntax': 'off',
|
|
87
|
+
'no-console': 'off',
|
|
88
|
+
'no-param-reassign': 'off',
|
|
89
|
+
'no-await-in-loop': 'off',
|
|
90
|
+
'max-classes-per-file': 'off',
|
|
91
|
+
'import/no-extraneous-dependencies': 'off',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
// TypeScript-specific rules (applied only to TS files)
|
|
96
|
+
{
|
|
97
|
+
files: ['**/*.{ts,mts,cts,tsx}'],
|
|
98
|
+
languageOptions: {
|
|
99
|
+
parserOptions: {
|
|
100
|
+
project: './tsconfig.json',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
rules: {
|
|
104
|
+
'@typescript-eslint/no-unused-vars': [
|
|
105
|
+
'error',
|
|
106
|
+
{ vars: 'all', args: 'after-used', ignoreRestSiblings: true }
|
|
107
|
+
],
|
|
108
|
+
'@typescript-eslint/no-unnecessary-condition': 'error',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
// Test file overrides
|
|
113
|
+
{
|
|
114
|
+
files: ['**/*.test.{ts,js}', '**/*.spec.{ts,js}'],
|
|
115
|
+
rules: {
|
|
116
|
+
'no-unused-expressions': 'off',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// Global variables (if needed)
|
|
121
|
+
{
|
|
122
|
+
languageOptions: {
|
|
123
|
+
globals: {
|
|
124
|
+
window: 'readonly',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
];
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Key Migration Changes
|
|
132
|
+
|
|
133
|
+
1. **No separate TypeScript config needed**: TypeScript support is now included in `@hs-web-team/eslint-config-node`, so you can remove `@hs-web-team/eslint-config-ts` from your dependencies.
|
|
134
|
+
|
|
135
|
+
2. **Environment variables**: The `env` property is replaced with `languageOptions.globals`. Jest globals are already included in the base config, so you don't need to specify them again.
|
|
136
|
+
|
|
137
|
+
3. **Parser options**: Move `parserOptions` inside `languageOptions.parserOptions` and apply only to TypeScript files.
|
|
138
|
+
|
|
139
|
+
4. **Overrides become separate objects**: Instead of `overrides` array, create separate configuration objects with `files` patterns.
|
|
140
|
+
|
|
141
|
+
5. **Use `'off'` instead of `0`**: While numbers still work, the string values (`'off'`, `'warn'`, `'error'`) are more readable.
|
|
142
|
+
|
|
143
|
+
6. **Import as ES module**: Use `import` instead of `require`.
|
|
144
|
+
|
|
145
|
+
## Extending the Configuration
|
|
146
|
+
|
|
147
|
+
Once you've completed the migration, you can easily extend the configuration for specific needs:
|
|
148
|
+
|
|
149
|
+
### Adding Rules for Specific File Patterns
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
import wtConfig from '@hs-web-team/eslint-config-node';
|
|
153
|
+
|
|
154
|
+
export default [
|
|
155
|
+
...wtConfig,
|
|
156
|
+
{
|
|
157
|
+
files: ['src/**/*.js'],
|
|
158
|
+
rules: {
|
|
159
|
+
'no-restricted-imports': ['error', 'lodash'],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Adding Custom Plugins
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
import wtConfig from '@hs-web-team/eslint-config-node';
|
|
169
|
+
import securityPlugin from 'eslint-plugin-security';
|
|
170
|
+
|
|
171
|
+
export default [
|
|
172
|
+
...wtConfig,
|
|
173
|
+
{
|
|
174
|
+
plugins: {
|
|
175
|
+
security: securityPlugin,
|
|
176
|
+
},
|
|
177
|
+
rules: {
|
|
178
|
+
'security/detect-object-injection': 'warn',
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
];
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Adding Custom Ignores
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
import wtConfig from '@hs-web-team/eslint-config-node';
|
|
188
|
+
|
|
189
|
+
export default [
|
|
190
|
+
...wtConfig,
|
|
191
|
+
{
|
|
192
|
+
ignores: [
|
|
193
|
+
'**/coverage/**',
|
|
194
|
+
'**/build/**',
|
|
195
|
+
'**/*.config.js',
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
];
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Complex Example with Multiple Customizations
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
import wtConfig from '@hs-web-team/eslint-config-node';
|
|
205
|
+
import importPlugin from 'eslint-plugin-import';
|
|
206
|
+
|
|
207
|
+
export default [
|
|
208
|
+
...wtConfig,
|
|
209
|
+
|
|
210
|
+
// Global overrides
|
|
211
|
+
{
|
|
212
|
+
rules: {
|
|
213
|
+
'no-console': 'off',
|
|
214
|
+
'max-len': ['error', { code: 100 }],
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
// Import plugin configuration
|
|
219
|
+
{
|
|
220
|
+
plugins: {
|
|
221
|
+
import: importPlugin,
|
|
222
|
+
},
|
|
223
|
+
rules: {
|
|
224
|
+
'import/order': ['error', { 'newlines-between': 'always' }],
|
|
225
|
+
'import/no-duplicates': 'error',
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
|
|
229
|
+
// TypeScript-specific configuration
|
|
230
|
+
{
|
|
231
|
+
files: ['**/*.{ts,tsx}'],
|
|
232
|
+
languageOptions: {
|
|
233
|
+
parserOptions: {
|
|
234
|
+
project: './tsconfig.json',
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
rules: {
|
|
238
|
+
'@typescript-eslint/strict-boolean-expressions': 'error',
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
// Test files
|
|
243
|
+
{
|
|
244
|
+
files: ['**/*.test.{js,ts}', '**/__tests__/**'],
|
|
245
|
+
rules: {
|
|
246
|
+
'max-len': 'off',
|
|
247
|
+
'no-magic-numbers': 'off',
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
// Additional ignores
|
|
252
|
+
{
|
|
253
|
+
ignores: ['**/generated/**', '**/migrations/**'],
|
|
254
|
+
},
|
|
255
|
+
];
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Common Issues
|
|
259
|
+
|
|
260
|
+
### Module Type Warning
|
|
261
|
+
|
|
262
|
+
If you created `eslint.config.js` instead of `eslint.config.mjs`, you may see this warning when running ESLint:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
(node:40504) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///path/to/your/project/eslint.config.js?mtime=1762786140088 is not specified and it doesn't parse as CommonJS.
|
|
266
|
+
Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
|
|
267
|
+
To eliminate this warning, add "type": "module" to /path/to/your/project/package.json.
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Why this happens:** This ESLint config package uses ES modules (`"type": "module"`), and your `eslint.config.js` imports it using ES module syntax. If your project's `package.json` doesn't specify the module type, Node.js has to parse the file twice, causing the warning.
|
|
271
|
+
|
|
272
|
+
**Solution (choose one):**
|
|
273
|
+
|
|
274
|
+
**Option 1 (Recommended for CommonJS projects):** Rename the config file to explicitly mark it as an ES module:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
mv eslint.config.js eslint.config.mjs
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
This is the recommended approach because it doesn't require any changes to your existing codebase.
|
|
281
|
+
|
|
282
|
+
**Option 2 (Only if already using ES modules):** Add to your project's `package.json`:
|
|
283
|
+
|
|
284
|
+
```jsonc
|
|
285
|
+
{
|
|
286
|
+
"type": "module"
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
> **Warning:** Option 2 requires migrating your entire project from CommonJS to ES modules. All `.js` files must use ES module syntax (import/export) or be renamed to `.cjs`. Only use this option if your project is already using ES modules throughout.
|
package/index.js
CHANGED
|
@@ -1,45 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import globals from 'globals';
|
|
3
|
+
import tseslint from 'typescript-eslint';
|
|
4
|
+
|
|
5
|
+
// Base rules for all JavaScript files
|
|
6
|
+
const baseRules = {
|
|
7
|
+
'no-console': [
|
|
8
|
+
'error',
|
|
9
|
+
{
|
|
10
|
+
allow: ['info', 'warn', 'error'],
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
camelcase: 'off',
|
|
14
|
+
'comma-dangle': ['warn', 'always-multiline'],
|
|
15
|
+
'arrow-parens': 0,
|
|
16
|
+
'no-plusplus': 0,
|
|
17
|
+
'no-underscore-dangle': 0,
|
|
18
|
+
'no-confusing-arrow': 0,
|
|
19
|
+
'import/no-unresolved': 0,
|
|
20
|
+
'import/prefer-default-export': 0,
|
|
21
|
+
'no-trailing-spaces': ['error', { skipBlankLines: true }],
|
|
22
|
+
'no-unused-expressions': ['warn', { allowTernary: true }],
|
|
23
|
+
'max-len': [
|
|
24
|
+
2,
|
|
25
|
+
{
|
|
26
|
+
code: 120,
|
|
27
|
+
ignoreStrings: true,
|
|
28
|
+
ignoreTemplateLiterals: true,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
'operator-linebreak': 0,
|
|
32
|
+
'implicit-arrow-linebreaks': 0,
|
|
33
|
+
'implicit-arrow-linebreak': 0,
|
|
34
|
+
'object-curly-newline': 0,
|
|
35
|
+
'newline-per-chained-call': 0,
|
|
36
|
+
indent: 0,
|
|
37
|
+
'function-paren-newline': 0,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Common ignore patterns
|
|
41
|
+
const commonIgnores = [
|
|
42
|
+
'**/node_modules/**',
|
|
43
|
+
'**/.serverless/**',
|
|
44
|
+
'**/.webpack/**',
|
|
45
|
+
'**/dist/**',
|
|
46
|
+
'eslint.config.js',
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
export default [
|
|
50
|
+
// Global ignores
|
|
51
|
+
{
|
|
52
|
+
ignores: commonIgnores,
|
|
6
53
|
},
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
54
|
+
// Base config for all JavaScript files
|
|
55
|
+
js.configs.recommended,
|
|
56
|
+
{
|
|
57
|
+
files: ['**/*.{js,mjs,cjs}'],
|
|
58
|
+
languageOptions: {
|
|
59
|
+
globals: {...globals.node, ...globals.es2022, ...globals.jest},
|
|
60
|
+
},
|
|
61
|
+
rules: baseRules,
|
|
11
62
|
},
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
},
|
|
18
|
-
],
|
|
19
|
-
camelcase: 0,
|
|
20
|
-
'comma-dangle': 1,
|
|
21
|
-
'arrow-parens': 0,
|
|
22
|
-
'no-plusplus': 0,
|
|
23
|
-
'no-underscore-dangle': 0,
|
|
24
|
-
'no-confusing-arrow': 0,
|
|
25
|
-
'import/no-unresolved': 0,
|
|
26
|
-
'import/prefer-default-export': 0,
|
|
27
|
-
'no-trailing-spaces': [2, { skipBlankLines: true }],
|
|
28
|
-
'no-unused-expressions': [1, { allowTernary: true }],
|
|
29
|
-
'max-len': [
|
|
30
|
-
2,
|
|
31
|
-
{
|
|
32
|
-
code: 120,
|
|
33
|
-
ignoreStrings: true,
|
|
34
|
-
ignoreTemplateLiterals: true,
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
'operator-linebreak': 0,
|
|
38
|
-
'implicit-arrow-linebreaks': 0,
|
|
39
|
-
'implicit-arrow-linebreak': 0,
|
|
40
|
-
'object-curly-newline': 0,
|
|
41
|
-
'newline-per-chained-call': 0,
|
|
42
|
-
indent: 0,
|
|
43
|
-
'function-paren-newline': 0,
|
|
63
|
+
// TypeScript config that extends the base config
|
|
64
|
+
...tseslint.configs.recommended,
|
|
65
|
+
{
|
|
66
|
+
files: ['**/*.{ts,mts,cts,tsx}'],
|
|
67
|
+
rules: baseRules,
|
|
44
68
|
},
|
|
45
|
-
|
|
69
|
+
];
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hs-web-team/eslint-config-node",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-next.11",
|
|
4
4
|
"description": "HubSpot Marketing WebTeam ESLint rules for Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"lint": "npx eslint -c ./index.js *.js --fix",
|
|
8
9
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
"node": ">=22"
|
|
12
13
|
},
|
|
13
14
|
"bin": {
|
|
14
|
-
"add-prettier": "
|
|
15
|
+
"add-prettier": "bin/add-prettier-scripts.js"
|
|
15
16
|
},
|
|
16
17
|
"repository": {
|
|
17
18
|
"type": "git",
|
|
@@ -27,9 +28,15 @@
|
|
|
27
28
|
},
|
|
28
29
|
"homepage": "https://github.com/HubSpotWebTeam/wt-eslint-node#readme",
|
|
29
30
|
"dependencies": {
|
|
30
|
-
"eslint": "^
|
|
31
|
-
"eslint
|
|
32
|
-
"eslint-plugin
|
|
33
|
-
"
|
|
31
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
32
|
+
"@eslint/js": "^9.39.1",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^8.46.3",
|
|
34
|
+
"@typescript-eslint/parser": "^8.46.3",
|
|
35
|
+
"eslint": "^9.39.1",
|
|
36
|
+
"eslint-formatter-checkstyle": "^9.0.1",
|
|
37
|
+
"globals": "^16.5.0",
|
|
38
|
+
"jiti": "^2.6.1",
|
|
39
|
+
"prettier": "^3.6.2",
|
|
40
|
+
"typescript-eslint": "^8.46.3"
|
|
34
41
|
}
|
|
35
42
|
}
|