browserslist 4.11.0 → 4.12.2

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/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](http://semver.org/).
3
3
 
4
+ ## 4.12.2
5
+ * Update Firefox ESR.
6
+
7
+ ## 4.12.1
8
+ * Update `package.json` scanning tool for `--update-db` (by Luke Edwards).
9
+ * Improve docs (by Mukundan Senthil).
10
+
11
+ ## 4.12
12
+ * Add environments to shared configs (by Yevgeny Petukhov).
13
+ * Fix docs (by Dmitry Statsenko and Thomas Pozzo di Borgo).
14
+
15
+ ## 4.11.1
16
+ * FIx Node.js 6 support.
17
+
4
18
  ## 4.11
5
19
  * Add `npx browserslist --mobile-to-desktop` (by James Ross).
6
20
 
package/README.md CHANGED
@@ -17,12 +17,12 @@ front-end tools. It is used in:
17
17
  All tools will find target browsers automatically,
18
18
  when you add the following to `package.json`:
19
19
 
20
- ```js
20
+ ```json
21
21
  "browserslist": [
22
22
  "defaults",
23
23
  "not IE 11",
24
24
  "not IE_Mob 11",
25
- "maintained node versions",
25
+ "maintained node versions"
26
26
  ]
27
27
  ```
28
28
 
@@ -68,16 +68,24 @@ Browserslist will take queries from tool option,
68
68
 
69
69
  ## Table of Contents
70
70
 
71
- 1. [Tools](#tools)
72
- 2. [Best Practices](#best-practices)
73
- 3. [Queries](#queries)
74
- 4. [Config File](#config-file)
75
- 5. [Shareable Configs](#shareable-configs)
76
- 6. [Configuring for Different Environments](#configuring-for-different-environments)
77
- 7. [Custom Usage Data](#custom-usage-data)
78
- 8. [JS API](#js-api)
79
- 9. [Environment Variables](#environment-variables)
80
- 10. [Cache](#cache)
71
+ * [Tools](#tools)
72
+ * [Best Practices](#best-practices)
73
+ * [Queries](#queries)
74
+ * [Query Composition](#query-composition)
75
+ * [Full List](#full-list)
76
+ * [Debug](#debug)
77
+ * [Browsers](#browsers)
78
+ * [Config File](#config-file)
79
+ * [`package.json`](#packagejson)
80
+ * [`.browserslistrc`](#browserslistrc)
81
+ * [Shareable Configs](#shareable-configs)
82
+ * [Configuring for Different Environments](#configuring-for-different-environments)
83
+ * [Custom Usage Data](#custom-usage-data)
84
+ * [JS API](#js-api)
85
+ * [Environment Variables](#environment-variables)
86
+ * [Cache](#cache)
87
+ * [Security Contact](#security-contact)
88
+ * [For Enterprise](#for-enterprise)
81
89
 
82
90
  ## Tools
83
91
 
@@ -162,13 +170,16 @@ There is 3 different ways to combine queries as depicted below. First you start
162
170
  with a single query and then we combine the queries to get our final list.
163
171
 
164
172
  Obviously you can *not* start with a `not` combiner, since there is no left-hand
165
- side query to combine it with.
173
+ side query to combine it with. The left-hand is always resolved as `and`
174
+ combiner even if `or` is used (this is an API implementation specificity).
175
+
176
+ `and` combiner has precedence over `or` combiner.
166
177
 
167
178
  | Query combiner type | Illustration | Example |
168
179
  | ------------------- | :----------: | ------- |
169
180
  |`or`/`,` combiner <br> (union) | ![Union of queries](img/union.svg) | `> .5% or last 2 versions` <br> `> .5%, last 2 versions` |
170
181
  | `and` combiner <br> (intersection) | ![intersection of queries](img/intersection.svg) | `> .5% and last 2 versions` |
171
- | `not` combiner <br> (relative complement) | ![Relative complement of queries](img/complement.svg) | `> .5% and not last 2 versions` <br> `> .5% or not last 2 versions` <br> `> .5%, not last 2 versions` |
182
+ | `not` combiner <br> (relative complement) | ![Relative complement of queries](img/complement.svg) | All those three are equivalent to the first one <br> `> .5% and not last 2 versions` <br> `> .5% or not last 2 versions` <br> `> .5%, not last 2 versions` |
172
183
 
173
184
  _A quick way to test your query is to do `npx browserslist '> 0.5%, not IE 11'`
174
185
  in your terminal._
@@ -212,7 +223,7 @@ You can specify the browser and Node.js versions by queries (case insensitive):
212
223
  * `since 2015` or `last 2 years`: all versions released since year 2015
213
224
  (also `since 2015-03` and `since 2015-03-10`).
214
225
  * `dead`: browsers without official support or updates for 24 months.
215
- Right now it is `IE 10`, `IE_Mob 10`, `BlackBerry 10`, `BlackBerry 7`,
226
+ Right now it is `IE 10`, `IE_Mob 11`, `BlackBerry 10`, `BlackBerry 7`,
216
227
  `Samsung 4` and `OperaMobile 12.1`.
217
228
  * `last 2 versions`: the last 2 versions for *each* browser.
218
229
  * `last 2 Chrome versions`: the last 2 versions of Chrome browser.
@@ -303,7 +314,8 @@ browsers in `package.json` with `browserslist` key:
303
314
  ### `.browserslistrc`
304
315
 
305
316
  Separated Browserslist config should be named `.browserslistrc`
306
- and have browsers queries split by a new line. Comments starts with `#` symbol:
317
+ and have browsers queries split by a new line.
318
+ Each line is combined with the `or` combiner. Comments starts with `#` symbol:
307
319
 
308
320
  ```yaml
309
321
  # Browsers that we support
@@ -365,8 +377,25 @@ module.exports = [
365
377
  ```
366
378
 
367
379
  You can also include a `browserslist-stats.json` file as part of your shareable
368
- config at the root and query it using `> 5% in browserslist-config-mycompany stats`.
369
- It uses the same format as `extends` and the `dangerousExtend` property as above.
380
+ config at the root and query it using
381
+ `> 5% in browserslist-config-mycompany stats`. It uses the same format
382
+ as `extends` and the `dangerousExtend` property as above.
383
+
384
+ You can export configs for different environments and select environment
385
+ by `BROWSERSLIST_ENV` or `env` option in your tool:
386
+
387
+ ```js
388
+ module.exports = {
389
+ development: [
390
+ 'last 1 version'
391
+ ],
392
+ production: [
393
+ 'last 1 version',
394
+ '> 1%',
395
+ 'ie 10'
396
+ ]
397
+ }
398
+ ```
370
399
 
371
400
 
372
401
  ## Configuring for Different Environments
@@ -598,3 +627,14 @@ To report a security vulnerability, please use the [Tidelift security contact].
598
627
  Tidelift will coordinate the fix and disclosure.
599
628
 
600
629
  [Tidelift security contact]: https://tidelift.com/security
630
+
631
+
632
+ ## For Enterprise
633
+
634
+ Available as part of the Tidelift Subscription.
635
+
636
+ The maintainers of `browserslist` and thousands of other packages are working
637
+ with Tidelift to deliver commercial support and maintenance for the open source
638
+ dependencies you use to build your applications. Save time, reduce risk,
639
+ and improve code health, while paying the maintainers of the exact dependencies
640
+ you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-browserslist?utm_source=npm-browserslist&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
package/index.js CHANGED
@@ -424,7 +424,8 @@ function browserslist (queries, opts) {
424
424
  var context = {
425
425
  ignoreUnknownVersions: opts.ignoreUnknownVersions,
426
426
  dangerousExtend: opts.dangerousExtend,
427
- mobileToDesktop: opts.mobileToDesktop
427
+ mobileToDesktop: opts.mobileToDesktop,
428
+ env: opts.env
428
429
  }
429
430
 
430
431
  env.oldDataWarning(browserslist.data)
@@ -645,7 +646,7 @@ var QUERIES = [
645
646
  {
646
647
  regexp: /^last\s+(\d+)\s+electron\s+major\s+versions?$/i,
647
648
  select: function (context, versions) {
648
- var validVersions = getMajorVersions(Object.keys(e2c).reverse(), versions)
649
+ var validVersions = getMajorVersions(Object.keys(e2c), versions)
649
650
  return validVersions.map(function (i) {
650
651
  return 'chrome ' + e2c[i]
651
652
  })
@@ -989,7 +990,7 @@ var QUERIES = [
989
990
  {
990
991
  regexp: /^(firefox|ff|fx)\s+esr$/i,
991
992
  select: function () {
992
- return ['firefox 68']
993
+ return ['firefox 68', 'firefox 78']
993
994
  }
994
995
  },
995
996
  {
package/node.js CHANGED
@@ -156,12 +156,18 @@ module.exports = {
156
156
  if (!context.dangerousExtend) checkExtend(name)
157
157
  // eslint-disable-next-line security/detect-non-literal-require
158
158
  var queries = require(require.resolve(name, { paths: ['.'] }))
159
- if (!Array.isArray(queries)) {
160
- throw new BrowserslistError(
161
- '`' + name + '` config exports not an array of queries'
162
- )
159
+ if (queries) {
160
+ if (Array.isArray(queries)) {
161
+ return queries
162
+ } else if (typeof queries === 'object') {
163
+ if (!queries.defaults) queries.defaults = []
164
+ return pickEnv(queries, context, name)
165
+ }
163
166
  }
164
- return queries
167
+ throw new BrowserslistError(
168
+ '`' + name + '` config exports not an array of queries' +
169
+ ' or an object of envs'
170
+ )
165
171
  },
166
172
 
167
173
  loadStat: function loadStat (context, name, data) {
@@ -342,10 +348,9 @@ module.exports = {
342
348
  var halfYearAgo = Date.now() - TIME_TO_UPDATE_CANIUSE
343
349
 
344
350
  if (latest !== 0 && latest < halfYearAgo) {
345
- var command = 'npx browserslist --update-db'
346
351
  console.warn(
347
- 'Browserslist: caniuse-lite is outdated. ' +
348
- 'Please run the following command: `' + command + '`'
352
+ 'Browserslist: caniuse-lite is outdated. Please run:\n' +
353
+ 'npx browserslist@latest --update-db'
349
354
  )
350
355
  }
351
356
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browserslist",
3
- "version": "4.11.0",
3
+ "version": "4.12.2",
4
4
  "description": "Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-env-preset",
5
5
  "keywords": [
6
6
  "caniuse",
@@ -15,17 +15,17 @@
15
15
  "license": "MIT",
16
16
  "repository": "browserslist/browserslist",
17
17
  "dependencies": {
18
- "caniuse-lite": "^1.0.30001035",
19
- "electron-to-chromium": "^1.3.380",
20
- "node-releases": "^1.1.52",
21
- "pkg-up": "^3.1.0"
18
+ "caniuse-lite": "^1.0.30001088",
19
+ "electron-to-chromium": "^1.3.483",
20
+ "escalade": "^3.0.1",
21
+ "node-releases": "^1.1.58"
22
+ },
23
+ "engines": {
24
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
22
25
  },
23
26
  "bin": "./cli.js",
24
27
  "browser": {
25
28
  "./node.js": "./browser.js",
26
29
  "path": false
27
- },
28
- "eslintIgnore": [
29
- "test/fixtures"
30
- ]
30
+ }
31
31
  }
package/update-db.js CHANGED
@@ -1,30 +1,33 @@
1
1
  var childProcess = require('child_process')
2
- var pkgUp = require('pkg-up')
2
+ var escalade = require('escalade/sync')
3
3
  var path = require('path')
4
4
  var fs = require('fs')
5
5
 
6
6
  var BrowserslistError = require('./error')
7
7
 
8
8
  function detectLockfile () {
9
- var packagePath = pkgUp.sync()
10
- if (!packagePath) {
9
+ var packageDir = escalade('.', function (dir, names) {
10
+ return names.indexOf('package.json') !== -1 ? dir : ''
11
+ })
12
+
13
+ if (!packageDir) {
11
14
  throw new BrowserslistError(
12
15
  'Cannot find package.json. ' +
13
16
  'Is it a right project to run npx browserslist --update-db?'
14
17
  )
15
18
  }
16
19
 
17
- var rootDir = path.dirname(packagePath)
18
- var lockfileNpm = path.join(rootDir, 'package-lock.json')
19
- var lockfileYarn = path.join(rootDir, 'yarn.lock')
20
- var lockfilePnpm = path.join(rootDir, 'pnpm-lock.yaml')
20
+ var lockfileNpm = path.join(packageDir, 'package-lock.json')
21
+ var lockfileYarn = path.join(packageDir, 'yarn.lock')
22
+ var lockfilePnpm = path.join(packageDir, 'pnpm-lock.yaml')
21
23
 
22
- if (fs.existsSync(lockfileNpm)) {
24
+ /* istanbul ignore next */
25
+ if (fs.existsSync(lockfilePnpm)) {
26
+ return { mode: 'pnpm', file: lockfilePnpm }
27
+ } else if (fs.existsSync(lockfileNpm)) {
23
28
  return { mode: 'npm', file: lockfileNpm }
24
29
  } else if (fs.existsSync(lockfileYarn)) {
25
30
  return { mode: 'yarn', file: lockfileYarn }
26
- } else if (fs.existsSync(lockfilePnpm)) {
27
- return { mode: 'pnpm', file: lockfilePnpm }
28
31
  } else {
29
32
  throw new BrowserslistError(
30
33
  'No lockfile found. Run "npm install", "yarn install" or "pnpm install"'
@@ -34,7 +37,11 @@ function detectLockfile () {
34
37
 
35
38
  function getCurrentVersion (lock) {
36
39
  var match
37
- if (lock.mode === 'npm') {
40
+ /* istanbul ignore if */
41
+ if (lock.mode === 'pnpm') {
42
+ match = /\/caniuse-lite\/([^:]+):/.exec(lock.content)
43
+ if (match[1]) return match[1]
44
+ } else if (lock.mode === 'npm') {
38
45
  var dependencies = JSON.parse(lock.content).dependencies
39
46
  if (dependencies && dependencies['caniuse-lite']) {
40
47
  return dependencies['caniuse-lite'].version
@@ -42,9 +49,6 @@ function getCurrentVersion (lock) {
42
49
  } else if (lock.mode === 'yarn') {
43
50
  match = /caniuse-lite@[^:]+:\n\s+version\s+"([^"]+)"/.exec(lock.content)
44
51
  if (match[1]) return match[1]
45
- } else if (lock.mode === 'pnpm') {
46
- match = /\/caniuse-lite\/([^:]+):/.exec(lock.content)
47
- if (match[1]) return match[1]
48
52
  }
49
53
  return null
50
54
  }
@@ -62,22 +66,8 @@ function updateLockfile (lock, latest) {
62
66
  } else {
63
67
  var lines = lock.content.split('\n')
64
68
  var i
65
- if (lock.mode === 'yarn') {
66
- for (i = 0; i < lines.length; i++) {
67
- if (lines[i].indexOf('caniuse-lite@') !== -1) {
68
- lines[i + 1] = lines[i + 1].replace(
69
- /version "[^"]+"/, 'version "' + latest.version + '"'
70
- )
71
- lines[i + 2] = lines[i + 2].replace(
72
- /resolved "[^"]+"/, 'resolved "' + latest.dist.tarball + '"'
73
- )
74
- lines[i + 3] = lines[i + 3].replace(
75
- /integrity .+/, 'integrity ' + latest.dist.integrity
76
- )
77
- i += 4
78
- }
79
- }
80
- } else if (lock.mode === 'pnpm') {
69
+ /* istanbul ignore if */
70
+ if (lock.mode === 'pnpm') {
81
71
  for (i = 0; i < lines.length; i++) {
82
72
  if (lines[i].indexOf('caniuse-lite:') >= 0) {
83
73
  lines[i] = lines[i].replace(/: .*$/, ': ' + latest.version)
@@ -94,6 +84,21 @@ function updateLockfile (lock, latest) {
94
84
  }
95
85
  }
96
86
  }
87
+ } else if (lock.mode === 'yarn') {
88
+ for (i = 0; i < lines.length; i++) {
89
+ if (lines[i].indexOf('caniuse-lite@') !== -1) {
90
+ lines[i + 1] = lines[i + 1].replace(
91
+ /version "[^"]+"/, 'version "' + latest.version + '"'
92
+ )
93
+ lines[i + 2] = lines[i + 2].replace(
94
+ /resolved "[^"]+"/, 'resolved "' + latest.dist.tarball + '"'
95
+ )
96
+ lines[i + 3] = lines[i + 3].replace(
97
+ /integrity .+/, 'integrity ' + latest.dist.integrity
98
+ )
99
+ i += 4
100
+ }
101
+ }
97
102
  }
98
103
  return lines.join('\n')
99
104
  }