es-check 9.7.2 → 9.8.1
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/README.md +16 -4
- package/lib/browserslist.js +54 -6
- package/lib/check-runner/index.js +2 -1
- package/lib/check-runner/utils.js +41 -15
- package/lib/constants/es-features/browserSupport.js +2421 -0
- package/lib/constants/es-features/index.js +2 -0
- package/lib/constants/featureParserMapping.js +7 -2
- package/lib/constants/polyfillableFeatures.js +7 -10
- package/lib/constants/versions.js +18 -0
- package/lib/detectFeatures.js +25 -9
- package/lib/helpers/browserSupport.js +89 -0
- package/package.json +24 -23
package/README.md
CHANGED
|
@@ -140,13 +140,13 @@ Here's a comprehensive list of all available options:
|
|
|
140
140
|
| `--quiet` | Quiet mode: only displays warn and error messages (default: false) |
|
|
141
141
|
| `--looseGlobMatching` | Doesn't fail if no files are found in some globs/files (default: false) |
|
|
142
142
|
| `--silent` | Silent mode: does not output anything, giving no indication of success or failure other than the exit code (default: false) |
|
|
143
|
-
| `--checkFeatures` | Check
|
|
143
|
+
| `--checkFeatures` | Check ES features; with `--checkBrowser`, also check support in target browsers (default: false) |
|
|
144
144
|
| `--checkForPolyfills` | Consider polyfills when checking features (only works with --checkFeatures) (default: false) |
|
|
145
145
|
| `--ignorePolyfillable [lib]` | Ignore polyfillable features; optionally specify library (e.g., `core-js`) to limit scope |
|
|
146
146
|
| `--ignore <features>` | Comma-separated list of features to ignore, e.g., "ErrorCause,TopLevelAwait" |
|
|
147
147
|
| `--ignoreFile <path>` | Path to JSON file containing features to ignore |
|
|
148
148
|
| `--allowList <features>` | Comma-separated list of features to allow even in lower ES versions, e.g., "const,let" |
|
|
149
|
-
| `--checkBrowser` |
|
|
149
|
+
| `--checkBrowser` | Select an ES target from Browserslist; add `--checkFeatures` for per-browser feature checks (default: false) |
|
|
150
150
|
| `--browserslistQuery <query>` | Custom browserslist query (e.g., "last 2 versions") |
|
|
151
151
|
| `--browserslistPath <path>` | Path to custom browserslist configuration (default: uses standard browserslist config resolution) |
|
|
152
152
|
| `--browserslistEnv <env>` | Browserslist environment to use (default: production) |
|
|
@@ -229,6 +229,16 @@ es-check --checkBrowser --browserslistQuery="last 2 versions" ./dist/**/*.js
|
|
|
229
229
|
es-check --checkBrowser --browserslistQuery=">0.5%, not dead" --checkFeatures ./dist/**/*.js
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
+
When `--checkBrowser` is combined with `--checkFeatures`, every detected feature is also checked
|
|
233
|
+
against the individual browser versions resolved from browserslist using
|
|
234
|
+
[MDN browser-compat-data](https://github.com/mdn/browser-compat-data). For example
|
|
235
|
+
`--browserslistQuery="ios_saf 15.0"` maps to ES2022, but `Object.hasOwn` and class static blocks are still
|
|
236
|
+
reported because iOS Safari added them in 15.4 and 16.4. Failures name the browser that lacks support:
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
Unsupported features detected: ObjectHasOwn (safari_ios 15.0 requires 15.4). These require a higher ES version than 13 or are not supported by the target browsers.
|
|
240
|
+
```
|
|
241
|
+
|
|
232
242
|
**Using browserlist just like an es version**
|
|
233
243
|
|
|
234
244
|
```sh
|
|
@@ -332,12 +342,12 @@ Here's an example of what an `.escheckrc` file will look like:
|
|
|
332
342
|
| `not` | Array | Files or glob patterns to exclude |
|
|
333
343
|
| `allowHashBang` | Boolean | Whether to allow hash bang in files |
|
|
334
344
|
| `looseGlobMatching` | Boolean | Whether to ignore missing files in globs |
|
|
335
|
-
| `checkFeatures` | Boolean |
|
|
345
|
+
| `checkFeatures` | Boolean | Check ES features and, with `checkBrowser`, support in target browsers |
|
|
336
346
|
| `checkForPolyfills` | Boolean | Whether to consider polyfills when checking features |
|
|
337
347
|
| `ignorePolyfillable` | Boolean/String | Ignore polyfillable features; set to library name (e.g., `"core-js"`) to limit scope |
|
|
338
348
|
| `ignore` | Array | Features to ignore when checking |
|
|
339
349
|
| `allowList` | Array | Features to allow even in lower ES versions |
|
|
340
|
-
| `checkBrowser` | Boolean |
|
|
350
|
+
| `checkBrowser` | Boolean | Select an ES target from Browserslist; use with `checkFeatures` for browser checks |
|
|
341
351
|
| `browserslistQuery` | String | Custom browserslist query to use |
|
|
342
352
|
| `browserslistPath` | String | Path to custom browserslist configuration |
|
|
343
353
|
| `browserslistEnv` | String | Browserslist environment to use |
|
|
@@ -513,6 +523,8 @@ es-check --checkBrowser --browserslistEnv="production" ./dist/**/*.js
|
|
|
513
523
|
|
|
514
524
|
**Combining with feature checking:**
|
|
515
525
|
|
|
526
|
+
Add `--checkFeatures` to check detected features against individual target browser versions using MDN compatibility data, as well as the selected ES version:
|
|
527
|
+
|
|
516
528
|
```sh
|
|
517
529
|
es-check --checkBrowser --checkFeatures ./dist/**/*.js
|
|
518
530
|
```
|
package/lib/browserslist.js
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
const browserslist = require("browserslist");
|
|
2
|
-
const { BROWSER_TO_ES_VERSION } = require("./constants/versions");
|
|
2
|
+
const { BROWSER_TO_ES_VERSION, BROWSERSLIST_TO_BCD } = require("./constants/versions");
|
|
3
|
+
|
|
4
|
+
const UNVERSIONED_BROWSER_VERSIONS = new Set(["all", "TP"]);
|
|
5
|
+
|
|
6
|
+
function resolveBrowsers(options = {}) {
|
|
7
|
+
const { browserslistPath, browserslistEnv, browserslistQuery } = options;
|
|
8
|
+
|
|
9
|
+
return browserslist(browserslistQuery ?? null, {
|
|
10
|
+
config: browserslistPath,
|
|
11
|
+
env: browserslistEnv,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
3
14
|
|
|
4
15
|
function getESVersionForBrowser(browser, version) {
|
|
5
16
|
const defaultVersion = 5;
|
|
@@ -42,13 +53,10 @@ function getESVersionForBrowser(browser, version) {
|
|
|
42
53
|
}
|
|
43
54
|
|
|
44
55
|
function getESVersionFromBrowserslist(options = {}) {
|
|
45
|
-
const { browserslistPath, browserslistEnv
|
|
56
|
+
const { browserslistPath, browserslistEnv } = options;
|
|
46
57
|
|
|
47
58
|
try {
|
|
48
|
-
const browsers =
|
|
49
|
-
config: browserslistPath,
|
|
50
|
-
env: browserslistEnv,
|
|
51
|
-
});
|
|
59
|
+
const browsers = resolveBrowsers(options);
|
|
52
60
|
|
|
53
61
|
const hasNoBrowsers = !browsers || browsers.length === 0;
|
|
54
62
|
if (hasNoBrowsers) {
|
|
@@ -99,7 +107,47 @@ function getESVersionFromBrowserslist(options = {}) {
|
|
|
99
107
|
}
|
|
100
108
|
}
|
|
101
109
|
|
|
110
|
+
function parseBrowserVersion(version) {
|
|
111
|
+
const hasVersion = typeof version === "string" && version.length > 0;
|
|
112
|
+
if (!hasVersion) return null;
|
|
113
|
+
|
|
114
|
+
const lowerBound = version.split("-")[0];
|
|
115
|
+
const isUnversioned = UNVERSIONED_BROWSER_VERSIONS.has(lowerBound);
|
|
116
|
+
if (isUnversioned) return null;
|
|
117
|
+
|
|
118
|
+
return lowerBound;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function toTargetBrowser(entry) {
|
|
122
|
+
const [browserslistName, version] = entry.split(" ");
|
|
123
|
+
const name = BROWSERSLIST_TO_BCD[browserslistName];
|
|
124
|
+
const parsedVersion = parseBrowserVersion(version);
|
|
125
|
+
|
|
126
|
+
const isUnknownBrowser = !name;
|
|
127
|
+
const isUnknownVersion = parsedVersion === null;
|
|
128
|
+
const isUnknownTarget = isUnknownBrowser || isUnknownVersion;
|
|
129
|
+
if (isUnknownTarget) return null;
|
|
130
|
+
|
|
131
|
+
return { name, version: parsedVersion, browserslistName };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function getTargetBrowsers(options = {}) {
|
|
135
|
+
let browsers;
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
browsers = resolveBrowsers(options);
|
|
139
|
+
} catch {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const hasNoBrowsers = !browsers || browsers.length === 0;
|
|
144
|
+
if (hasNoBrowsers) return [];
|
|
145
|
+
|
|
146
|
+
return browsers.map(toTargetBrowser).filter(Boolean);
|
|
147
|
+
}
|
|
148
|
+
|
|
102
149
|
module.exports = {
|
|
103
150
|
getESVersionFromBrowserslist,
|
|
104
151
|
getESVersionForBrowser,
|
|
152
|
+
getTargetBrowsers,
|
|
105
153
|
};
|
|
@@ -78,7 +78,7 @@ function processConfig(config, context) {
|
|
|
78
78
|
return { hasErrors: true, shouldContinue: true };
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
const { ecmaVersion } = versionResult;
|
|
81
|
+
const { ecmaVersion, targetBrowsers } = versionResult;
|
|
82
82
|
const useLatestForParsing = config.checkFeatures;
|
|
83
83
|
const targetEsVersion = parseInt(ecmaVersion, 10);
|
|
84
84
|
|
|
@@ -130,6 +130,7 @@ function processConfig(config, context) {
|
|
|
130
130
|
logger,
|
|
131
131
|
isDebug,
|
|
132
132
|
ecmaVersion,
|
|
133
|
+
targetBrowsers,
|
|
133
134
|
});
|
|
134
135
|
|
|
135
136
|
const results = processBatchedFiles(filteredFiles, processFile, batchSize);
|
|
@@ -199,18 +199,20 @@ function determineEcmaVersion(config, options) {
|
|
|
199
199
|
const isBrowserslistCheck = Boolean(expectedEcmaVersion === "checkBrowser" || checkBrowser);
|
|
200
200
|
|
|
201
201
|
if (isBrowserslistCheck) {
|
|
202
|
-
const
|
|
202
|
+
const browserslistOptions = {
|
|
203
|
+
browserslistQuery: config.browserslistQuery,
|
|
204
|
+
browserslistPath: config.browserslistPath,
|
|
205
|
+
browserslistEnv: config.browserslistEnv,
|
|
206
|
+
};
|
|
203
207
|
let browserslistError = null;
|
|
204
208
|
let ecmaVersion = null;
|
|
209
|
+
let targetBrowsers = [];
|
|
205
210
|
|
|
206
211
|
try {
|
|
207
|
-
const { getESVersionFromBrowserslist } = require("../browserslist");
|
|
208
|
-
const esVersionFromBrowserslist = getESVersionFromBrowserslist(
|
|
209
|
-
browserslistQuery,
|
|
210
|
-
browserslistPath: config.browserslistPath,
|
|
211
|
-
browserslistEnv: config.browserslistEnv,
|
|
212
|
-
});
|
|
212
|
+
const { getESVersionFromBrowserslist, getTargetBrowsers } = require("../browserslist");
|
|
213
|
+
const esVersionFromBrowserslist = getESVersionFromBrowserslist(browserslistOptions);
|
|
213
214
|
ecmaVersion = esVersionFromBrowserslist.toString();
|
|
215
|
+
targetBrowsers = getTargetBrowsers(browserslistOptions);
|
|
214
216
|
} catch (err) {
|
|
215
217
|
browserslistError = err;
|
|
216
218
|
}
|
|
@@ -220,7 +222,10 @@ function determineEcmaVersion(config, options) {
|
|
|
220
222
|
const shouldDebug = hasNoError && isDebug;
|
|
221
223
|
|
|
222
224
|
if (shouldDebug) {
|
|
223
|
-
|
|
225
|
+
const { formatTargetBrowsers } = require("../helpers/browserSupport");
|
|
226
|
+
logger.debug(
|
|
227
|
+
`ES-Check: Using ES${ecmaVersion} based on browserslist configuration (target browsers: ${formatTargetBrowsers(targetBrowsers)})`,
|
|
228
|
+
);
|
|
224
229
|
}
|
|
225
230
|
|
|
226
231
|
if (hasError) {
|
|
@@ -229,10 +234,10 @@ function determineEcmaVersion(config, options) {
|
|
|
229
234
|
isNodeAPI,
|
|
230
235
|
allErrors,
|
|
231
236
|
});
|
|
232
|
-
return { ecmaVersion: null, hasError: true };
|
|
237
|
+
return { ecmaVersion: null, targetBrowsers: [], hasError: true };
|
|
233
238
|
}
|
|
234
239
|
|
|
235
|
-
return { ecmaVersion, hasError: false };
|
|
240
|
+
return { ecmaVersion, targetBrowsers, hasError: false };
|
|
236
241
|
}
|
|
237
242
|
|
|
238
243
|
const mappedVersion = ECMA_VERSION_MAP[expectedEcmaVersion];
|
|
@@ -248,11 +253,11 @@ function determineEcmaVersion(config, options) {
|
|
|
248
253
|
|
|
249
254
|
if (isInvalidVersion) {
|
|
250
255
|
handleInvalidVersion({ logger, isNodeAPI, allErrors });
|
|
251
|
-
return { ecmaVersion: null, hasError: true };
|
|
256
|
+
return { ecmaVersion: null, targetBrowsers: [], hasError: true };
|
|
252
257
|
}
|
|
253
258
|
|
|
254
259
|
const ecmaVersion = String(ECMA_VERSION_TO_NUMBER[mappedVersion]);
|
|
255
|
-
return { ecmaVersion, hasError: false };
|
|
260
|
+
return { ecmaVersion, targetBrowsers: [], hasError: false };
|
|
256
261
|
}
|
|
257
262
|
|
|
258
263
|
function filterIgnoredFiles(files, pathsToIgnore, globOpts) {
|
|
@@ -283,7 +288,17 @@ function filterIgnoredFiles(files, pathsToIgnore, globOpts) {
|
|
|
283
288
|
return files.filter(shouldKeepFile);
|
|
284
289
|
}
|
|
285
290
|
|
|
286
|
-
function processFullAST(
|
|
291
|
+
function processFullAST(
|
|
292
|
+
code,
|
|
293
|
+
acornOpts,
|
|
294
|
+
file,
|
|
295
|
+
config,
|
|
296
|
+
ignoreList,
|
|
297
|
+
ecmaVersion,
|
|
298
|
+
isDebug,
|
|
299
|
+
logger,
|
|
300
|
+
targetBrowsers,
|
|
301
|
+
) {
|
|
287
302
|
const needsFullAST = config.checkFeatures;
|
|
288
303
|
const parserOptions = needsFullAST
|
|
289
304
|
? acornOpts
|
|
@@ -317,6 +332,7 @@ function processFullAST(code, acornOpts, file, config, ignoreList, ecmaVersion,
|
|
|
317
332
|
ast,
|
|
318
333
|
checkForPolyfills: config.checkForPolyfills,
|
|
319
334
|
ignorePolyfillable: config.ignorePolyfillable,
|
|
335
|
+
targetBrowsers,
|
|
320
336
|
});
|
|
321
337
|
foundFeatures = result.foundFeatures;
|
|
322
338
|
unsupportedFeatures = result.unsupportedFeatures;
|
|
@@ -398,7 +414,7 @@ function processFullAST(code, acornOpts, file, config, ignoreList, ecmaVersion,
|
|
|
398
414
|
}
|
|
399
415
|
|
|
400
416
|
function createFileProcessor(config, options) {
|
|
401
|
-
const { acornOpts, ignoreList, logger, isDebug, ecmaVersion } = options;
|
|
417
|
+
const { acornOpts, ignoreList, logger, isDebug, ecmaVersion, targetBrowsers } = options;
|
|
402
418
|
|
|
403
419
|
return (file) => {
|
|
404
420
|
const useCache = config.cache !== false;
|
|
@@ -411,7 +427,17 @@ function createFileProcessor(config, options) {
|
|
|
411
427
|
logger.debug(`ES-Check: checking ${file}`);
|
|
412
428
|
}
|
|
413
429
|
|
|
414
|
-
return processFullAST(
|
|
430
|
+
return processFullAST(
|
|
431
|
+
code,
|
|
432
|
+
acornOpts,
|
|
433
|
+
file,
|
|
434
|
+
config,
|
|
435
|
+
ignoreList,
|
|
436
|
+
ecmaVersion,
|
|
437
|
+
isDebug,
|
|
438
|
+
logger,
|
|
439
|
+
targetBrowsers,
|
|
440
|
+
);
|
|
415
441
|
};
|
|
416
442
|
}
|
|
417
443
|
|