browserslist 4.12.2 → 4.14.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,19 +1,33 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](http://semver.org/).
3
3
 
4
+ ## 4.14.2
5
+ * Fixed `--update-db` on Windows (by James Ross).
6
+ * Improved `--update-db` output.
7
+
8
+ ## 4.14.1
9
+ * Added `--update-db` explanation (by Justin Zelinsky).
10
+
11
+ ## 4.14
12
+ * Add `BROWSERSLIST_DANGEROUS_EXTEND` support (by Timo Mayer).
13
+
14
+ ## 4.13
15
+ * Added `supports` query to select browsers (by Jesús Leganés-Combarro).
16
+
4
17
  ## 4.12.2
5
18
  * Update Firefox ESR.
6
19
 
7
20
  ## 4.12.1
8
21
  * Update `package.json` scanning tool for `--update-db` (by Luke Edwards).
9
22
  * Improve docs (by Mukundan Senthil).
23
+ * Drop Node.js 13.0-13.6 support because of ES modules bug in that versions.
10
24
 
11
25
  ## 4.12
12
26
  * Add environments to shared configs (by Yevgeny Petukhov).
13
27
  * Fix docs (by Dmitry Statsenko and Thomas Pozzo di Borgo).
14
28
 
15
29
  ## 4.11.1
16
- * FIx Node.js 6 support.
30
+ * Fix Node.js 6 support.
17
31
 
18
32
  ## 4.11
19
33
  * Add `npx browserslist --mobile-to-desktop` (by James Ross).
package/README.md CHANGED
@@ -70,6 +70,7 @@ Browserslist will take queries from tool option,
70
70
 
71
71
  * [Tools](#tools)
72
72
  * [Best Practices](#best-practices)
73
+ * [Browsers Data Updating](#browsers-data-updating)
73
74
  * [Queries](#queries)
74
75
  * [Query Composition](#query-composition)
75
76
  * [Full List](#full-list)
@@ -143,6 +144,46 @@ Browserslist will take queries from tool option,
143
144
  and desktop Safari combined.
144
145
 
145
146
 
147
+ ## Browsers Data Updating
148
+
149
+ `npx browserslist@latest --update-db` updates `caniuse-lite` version
150
+ in your npm, yarn or pnpm lock file.
151
+
152
+ You need to do it regularly for two reasons:
153
+
154
+ 1. To use the latest browser’s versions and statistics in queries like
155
+ `last 2 versions` or `>1%`. For example, if you created your project
156
+ 2 years ago and did not update your dependencies, `last 1 version`
157
+ will return 2 year old browsers.
158
+ 2. `caiuse-lite` deduplication: to synchronize version in different tools.
159
+
160
+ > What is deduplication?
161
+
162
+ Due to how npm architecture is setup, you may have a situation
163
+ where you have multiple versions of a single dependency required.
164
+
165
+ Imagine you begin a project, and you add `autoprefixer` as a dependency.
166
+ npm looks for the latest `caniuse-lite` version (1.0.30000700) and adds it to
167
+ `package-lock.json` under `autoprefixer` dependencies.
168
+
169
+ A year later, you decide to add Babel. At this moment, we have a
170
+ new version of `canuse-lite` (1.0.30000900). npm took the latest version
171
+ and added it to your lock file under `@babel/preset-env` dependencies.
172
+
173
+ Now your lock file looks like this:
174
+
175
+ ```ocaml
176
+ autoprefixer 7.1.4
177
+ browserslist 3.1.1
178
+ caniuse-lite 1.0.30000700
179
+ @babel/preset-env 7.10.0
180
+ browserslist 4.13.0
181
+ caniuse-lite 1.0.30000900
182
+ ```
183
+
184
+ As you can see, we now have two versions of `caniuse-lite` installed.
185
+
186
+
146
187
  ## Queries
147
188
 
148
189
  Browserslist will use browsers and Node.js versions query
@@ -164,7 +205,9 @@ An `or` combiner can use the keyword `or` as well as `,`.
164
205
  `last 1 version or > 1%` is equal to `last 1 version, > 1%`.
165
206
 
166
207
  `and` query combinations are also supported to perform an
167
- intersection of the previous query: `last 1 version and > 1%`.
208
+ intersection of all the previous queries:
209
+ `last 1 version or chrome > 75 and > 1%` will select
210
+ (`browser last version` or `Chrome since 76`) and `more than 1% marketshare`.
168
211
 
169
212
  There is 3 different ways to combine queries as depicted below. First you start
170
213
  with a single query and then we combine the queries to get our final list.
@@ -173,8 +216,6 @@ Obviously you can *not* start with a `not` combiner, since there is no left-hand
173
216
  side query to combine it with. The left-hand is always resolved as `and`
174
217
  combiner even if `or` is used (this is an API implementation specificity).
175
218
 
176
- `and` combiner has precedence over `or` combiner.
177
-
178
219
  | Query combiner type | Illustration | Example |
179
220
  | ------------------- | :----------: | ------- |
180
221
  |`or`/`,` combiner <br> (union) | ![Union of queries](img/union.svg) | `> .5% or last 2 versions` <br> `> .5%, last 2 versions` |
@@ -184,7 +225,6 @@ combiner even if `or` is used (this is an API implementation specificity).
184
225
  _A quick way to test your query is to do `npx browserslist '> 0.5%, not IE 11'`
185
226
  in your terminal._
186
227
 
187
-
188
228
  ### Full List
189
229
 
190
230
  You can specify the browser and Node.js versions by queries (case insensitive):
@@ -193,45 +233,51 @@ You can specify the browser and Node.js versions by queries (case insensitive):
193
233
  (`> 0.5%, last 2 versions, Firefox ESR, not dead`).
194
234
  * `> 5%`: browsers versions selected by global usage statistics.
195
235
  `>=`, `<` and `<=` work too.
196
- * `> 5% in US`: uses USA usage statistics. It accepts [two-letter country code].
197
- * `> 5% in alt-AS`: uses Asia region usage statistics. List of all region codes
198
- can be found at [`caniuse-lite/data/regions`].
199
- * `> 5% in my stats`: uses [custom usage data].
200
- * `> 5% in browserslist-config-mycompany stats`: uses [custom usage data]
201
- from `browserslist-config-mycompany/browserslist-stats.json`.
202
- * `cover 99.5%`: most popular browsers that provide coverage.
203
- * `cover 99.5% in US`: same as above, with [two-letter country code].
204
- * `cover 99.5% in my stats`: uses [custom usage data].
205
- * `maintained node versions`: all Node.js versions, which are [still maintained]
206
- by Node.js Foundation.
236
+ * `> 5% in US`: uses USA usage statistics.
237
+ It accepts [two-letter country code].
238
+ * `> 5% in alt-AS`: uses Asia region usage statistics.
239
+ List of all region codes can be found at [`caniuse-lite/data/regions`].
240
+ * `> 5% in my stats`: uses [custom usage data].
241
+ * `> 5% in browserslist-config-mycompany stats`: uses [custom usage data]
242
+ from `browserslist-config-mycompany/browserslist-stats.json`.
243
+ * `cover 99.5%`: most popular browsers that provide coverage.
244
+ * `cover 99.5% in US`: same as above, with [two-letter country code].
245
+ * `cover 99.5% in my stats`: uses [custom usage data].
246
+ * `dead`: browsers without official support or updates for 24 months.
247
+ Right now it is `IE 10`, `IE_Mob 11`, `BlackBerry 10`, `BlackBerry 7`,
248
+ `Samsung 4` and `OperaMobile 12.1`.
249
+ * `last 2 versions`: the last 2 versions for *each* browser.
250
+ * `last 2 Chrome versions`: the last 2 versions of Chrome browser.
251
+ * `last 2 major versions` or `last 2 iOS major versions`:
252
+ all minor/patch releases of last 2 major versions.
207
253
  * `node 10` and `node 10.4`: selects latest Node.js `10.x.x`
208
254
  or `10.4.x` release.
209
- * `current node`: Node.js version used by Browserslist right now.
255
+ * `current node`: Node.js version used by Browserslist right now.
256
+ * `maintained node versions`: all Node.js versions, which are [still maintained]
257
+ by Node.js Foundation.
258
+ * `iOS 7`: the iOS browser version 7 directly.
259
+ * `Firefox > 20`: versions of Firefox newer than 20.
260
+ `>=`, `<` and `<=` work too. It also works with Node.js.
261
+ * `ie 6-8`: selects an inclusive range of versions.
262
+ * `Firefox ESR`: the latest [Firefox ESR] version.
263
+ * `PhantomJS 2.1` and `PhantomJS 1.9`: selects Safari versions similar
264
+ to PhantomJS runtime.
210
265
  * `extends browserslist-config-mycompany`: take queries from
211
266
  `browserslist-config-mycompany` npm package.
212
- * `ie 6-8`: selects an inclusive range of versions.
213
- * `Firefox > 20`: versions of Firefox newer than 20.
214
- `>=`, `<` and `<=` work too. It also works with Node.js.
215
- * `iOS 7`: the iOS browser version 7 directly.
216
- * `Firefox ESR`: the latest [Firefox ESR] version.
217
- * `PhantomJS 2.1` and `PhantomJS 1.9`: selects Safari versions similar
218
- to PhantomJS runtime.
219
- * `unreleased versions` or `unreleased Chrome versions`:
220
- alpha and beta versions.
221
- * `last 2 major versions` or `last 2 iOS major versions`:
222
- all minor/patch releases of last 2 major versions.
267
+ * `supports es6-module`: browsers with support for specific features.
268
+ `es6-module` here is the `feat` parameter at the URL of the [Can I Use]
269
+ page. A list of all available features can be found at
270
+ [`caniuse-lite/data/features`].
223
271
  * `since 2015` or `last 2 years`: all versions released since year 2015
224
272
  (also `since 2015-03` and `since 2015-03-10`).
225
- * `dead`: browsers without official support or updates for 24 months.
226
- Right now it is `IE 10`, `IE_Mob 11`, `BlackBerry 10`, `BlackBerry 7`,
227
- `Samsung 4` and `OperaMobile 12.1`.
228
- * `last 2 versions`: the last 2 versions for *each* browser.
229
- * `last 2 Chrome versions`: the last 2 versions of Chrome browser.
273
+ * `unreleased versions` or `unreleased Chrome versions`:
274
+ alpha and beta versions.
230
275
  * `not ie <= 8`: exclude browsers selected by previous queries.
231
276
 
232
277
  You can add `not ` to any query.
233
278
 
234
279
  [`caniuse-lite/data/regions`]: https://github.com/ben-eb/caniuse-lite/tree/master/data/regions
280
+ [`caniuse-lite/data/features`]: https://github.com/ben-eb/caniuse-lite/tree/master/data/features
235
281
  [two-letter country code]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
236
282
  [custom usage data]: #custom-usage-data
237
283
  [still maintained]: https://github.com/nodejs/Release
@@ -349,10 +395,11 @@ naming or prefixing the module with `@scope/browserslist-config`, such as
349
395
  `@scope/browserslist-config` or `@scope/browserslist-config-mycompany`.
350
396
 
351
397
  If you don’t accept Browserslist queries from users, you can disable the
352
- validation by using the `dangerousExtend` option:
398
+ validation by using the or `BROWSERSLIST_DANGEROUS_EXTEND` environment variable
399
+ or `dangerousExtend` option.
353
400
 
354
- ```js
355
- browserslist(queries, { path, dangerousExtend: true })
401
+ ```sh
402
+ BROWSERSLIST_DANGEROUS_EXTEND=1 npx webpack
356
403
  ```
357
404
 
358
405
  Because this uses `npm`'s resolution, you can also reference specific files
@@ -574,32 +621,39 @@ with [environment variables]:
574
621
  * `BROWSERSLIST` with browsers queries.
575
622
 
576
623
  ```sh
577
- BROWSERSLIST="> 5%" gulp css
624
+ BROWSERSLIST="> 5%" npx webpack
578
625
  ```
579
626
 
580
627
  * `BROWSERSLIST_CONFIG` with path to config file.
581
628
 
582
629
  ```sh
583
- BROWSERSLIST_CONFIG=./config/browserslist gulp css
630
+ BROWSERSLIST_CONFIG=./config/browserslist npx webpack
584
631
  ```
585
632
 
586
633
  * `BROWSERSLIST_ENV` with environments string.
587
634
 
588
635
  ```sh
589
- BROWSERSLIST_ENV="development" gulp css
636
+ BROWSERSLIST_ENV="development" npx webpack
590
637
  ```
591
638
 
592
639
  * `BROWSERSLIST_STATS` with path to the custom usage data
593
640
  for `> 1% in my stats` query.
594
641
 
595
642
  ```sh
596
- BROWSERSLIST_STATS=./config/usage_data.json gulp css
643
+ BROWSERSLIST_STATS=./config/usage_data.json npx webpack
597
644
  ```
598
645
 
599
646
  * `BROWSERSLIST_DISABLE_CACHE` if you want to disable config reading cache.
600
647
 
601
648
  ```sh
602
- BROWSERSLIST_DISABLE_CACHE=1 gulp css
649
+ BROWSERSLIST_DISABLE_CACHE=1 npx webpack
650
+ ```
651
+
652
+ * `BROWSERSLIST_DANGEROUS_EXTEND` to disable security shareable config
653
+ name check.
654
+
655
+ ```sh
656
+ BROWSERSLIST_DANGEROUS_EXTEND=1 npx webpack
603
657
  ```
604
658
 
605
659
  [environment variables]: https://en.wikipedia.org/wiki/Environment_variable
package/browser.js CHANGED
@@ -21,10 +21,15 @@ module.exports = {
21
21
 
22
22
  loadCountry: function loadCountry () {
23
23
  throw new BrowserslistError(
24
- 'Country statistics is not supported ' +
24
+ 'Country statistics are not supported ' +
25
25
  'in client-side build of Browserslist')
26
26
  },
27
27
 
28
+ loadFeature: function loadFeature () {
29
+ throw new BrowserslistError(
30
+ 'Supports queries are not available in client-side build of Browserslist')
31
+ },
32
+
28
33
  currentNode: function currentNode (resolve, context) {
29
34
  return resolve(['maintained node versions'], context)[0]
30
35
  },
package/index.js CHANGED
@@ -505,6 +505,7 @@ function flatten (array) {
505
505
  }
506
506
 
507
507
  // Will be filled by Can I Use data below
508
+ browserslist.cache = { }
508
509
  browserslist.data = { }
509
510
  browserslist.usage = {
510
511
  global: { },
@@ -887,6 +888,20 @@ var QUERIES = [
887
888
  return result
888
889
  }
889
890
  },
891
+ {
892
+ regexp: /^supports\s+([\w-]+)$/,
893
+ select: function (context, feature) {
894
+ env.loadFeature(browserslist.cache, feature)
895
+ var features = browserslist.cache[feature]
896
+ return Object.keys(features).reduce(function (result, version) {
897
+ var flags = features[version]
898
+ if (flags.indexOf('y') >= 0 || flags.indexOf('a') >= 0) {
899
+ result.push(version)
900
+ }
901
+ return result
902
+ }, [])
903
+ }
904
+ },
890
905
  {
891
906
  regexp: /^electron\s+([\d.]+)\s*-\s*([\d.]+)$/i,
892
907
  select: function (context, from, to) {
package/node.js CHANGED
@@ -1,3 +1,4 @@
1
+ var feature = require('caniuse-lite/dist/unpacker/feature').default
1
2
  var region = require('caniuse-lite/dist/unpacker/region').default
2
3
  var path = require('path')
3
4
  var fs = require('fs')
@@ -152,8 +153,10 @@ function normalizeUsageData (usageData, data) {
152
153
  }
153
154
 
154
155
  module.exports = {
155
- loadQueries: function loadQueries (context, name) {
156
- if (!context.dangerousExtend) checkExtend(name)
156
+ loadQueries: function loadQueries (ctx, name) {
157
+ if (!ctx.dangerousExtend && !process.env.BROWSERSLIST_DANGEROUS_EXTEND) {
158
+ checkExtend(name)
159
+ }
157
160
  // eslint-disable-next-line security/detect-non-literal-require
158
161
  var queries = require(require.resolve(name, { paths: ['.'] }))
159
162
  if (queries) {
@@ -161,7 +164,7 @@ module.exports = {
161
164
  return queries
162
165
  } else if (typeof queries === 'object') {
163
166
  if (!queries.defaults) queries.defaults = []
164
- return pickEnv(queries, context, name)
167
+ return pickEnv(queries, ctx, name)
165
168
  }
166
169
  }
167
170
  throw new BrowserslistError(
@@ -170,8 +173,10 @@ module.exports = {
170
173
  )
171
174
  },
172
175
 
173
- loadStat: function loadStat (context, name, data) {
174
- if (!context.dangerousExtend) checkExtend(name)
176
+ loadStat: function loadStat (ctx, name, data) {
177
+ if (!ctx.dangerousExtend && !process.env.BROWSERSLIST_DANGEROUS_EXTEND) {
178
+ checkExtend(name)
179
+ }
175
180
  // eslint-disable-next-line security/detect-non-literal-require
176
181
  var stats = require(
177
182
  require.resolve(
@@ -237,6 +242,21 @@ module.exports = {
237
242
  }
238
243
  },
239
244
 
245
+ loadFeature: function loadFeature (features, name) {
246
+ name = name.replace(/[^\w-]/g, '')
247
+ if (features[name]) return
248
+
249
+ // eslint-disable-next-line security/detect-non-literal-require
250
+ var compressed = require('caniuse-lite/data/features/' + name + '.js')
251
+ var stats = feature(compressed).stats
252
+ features[name] = { }
253
+ for (var i in stats) {
254
+ for (var j in stats[i]) {
255
+ features[name][i + ' ' + j] = stats[i][j]
256
+ }
257
+ }
258
+ },
259
+
240
260
  parseConfig: function parseConfig (string) {
241
261
  var result = { defaults: [] }
242
262
  var sections = ['defaults']
@@ -337,6 +357,8 @@ module.exports = {
337
357
  dataTimeChecked = false
338
358
  filenessCache = { }
339
359
  configCache = { }
360
+
361
+ this.cache = { }
340
362
  },
341
363
 
342
364
  oldDataWarning: function oldDataWarning (agentsObj) {
@@ -350,7 +372,10 @@ module.exports = {
350
372
  if (latest !== 0 && latest < halfYearAgo) {
351
373
  console.warn(
352
374
  'Browserslist: caniuse-lite is outdated. Please run:\n' +
353
- 'npx browserslist@latest --update-db'
375
+ 'npx browserslist@latest --update-db\n' +
376
+ '\n' +
377
+ 'Why you should do it regularly:\n' +
378
+ 'https://github.com/browserslist/browserslist#browsers-data-updating'
354
379
  )
355
380
  }
356
381
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browserslist",
3
- "version": "4.12.2",
3
+ "version": "4.14.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,10 +15,10 @@
15
15
  "license": "MIT",
16
16
  "repository": "browserslist/browserslist",
17
17
  "dependencies": {
18
- "caniuse-lite": "^1.0.30001088",
19
- "electron-to-chromium": "^1.3.483",
20
- "escalade": "^3.0.1",
21
- "node-releases": "^1.1.58"
18
+ "caniuse-lite": "^1.0.30001125",
19
+ "electron-to-chromium": "^1.3.564",
20
+ "escalade": "^3.0.2",
21
+ "node-releases": "^1.1.61"
22
22
  },
23
23
  "engines": {
24
24
  "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
package/update-db.js CHANGED
@@ -47,13 +47,13 @@ function getCurrentVersion (lock) {
47
47
  return dependencies['caniuse-lite'].version
48
48
  }
49
49
  } else if (lock.mode === 'yarn') {
50
- match = /caniuse-lite@[^:]+:\n\s+version\s+"([^"]+)"/.exec(lock.content)
50
+ match = /caniuse-lite@[^:]+:\r?\n\s+version\s+"([^"]+)"/.exec(lock.content)
51
51
  if (match[1]) return match[1]
52
52
  }
53
53
  return null
54
54
  }
55
55
 
56
- function getLastestInfo () {
56
+ function getLatestInfo () {
57
57
  return JSON.parse(
58
58
  childProcess.execSync('npm show caniuse-lite --json').toString()
59
59
  )
@@ -119,18 +119,29 @@ module.exports = function updateDB (print) {
119
119
  lock.content = fs.readFileSync(lock.file).toString()
120
120
 
121
121
  var current = getCurrentVersion(lock)
122
- var latest = getLastestInfo()
122
+ var latest = getLatestInfo()
123
123
 
124
124
  if (typeof current === 'string') {
125
125
  print('Current version: ' + current + '\n')
126
126
  }
127
127
  print(
128
128
  'New version: ' + latest.version + '\n' +
129
- 'Updating caniuse-lite…\n'
129
+ 'Removing old caniuse-lite from lock file…\n'
130
130
  )
131
131
 
132
132
  fs.writeFileSync(lock.file, updateLockfile(lock, latest))
133
- childProcess.execSync(lock.mode + ' install')
134
133
 
135
- print('caniuse-lite has been successfully updated')
134
+ print(
135
+ 'Installing new caniuse-lite version…\n' +
136
+ '$ ' + lock.mode + ' install\n'
137
+ )
138
+ try {
139
+ childProcess.execSync(lock.mode + ' install')
140
+ } catch (e) /* istanbul ignore next */ {
141
+ print(e.stack)
142
+ print('\nProblem with `' + lock.mode + ' install` call. Run it manually.\n')
143
+ process.exit(1)
144
+ }
145
+
146
+ print('caniuse-lite has been successfully updated\n')
136
147
  }