diff --git a/2016.js b/2016.js index af7bd3b..8a8cb91 100644 --- a/2016.js +++ b/2016.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2016 }); +module.exports = getBaselineVersions({ baselineYear: 2016 }); diff --git a/2017.js b/2017.js index b747d4b..68890ca 100644 --- a/2017.js +++ b/2017.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2017 }); +module.exports = getBaselineVersions({ baselineYear: 2017 }); diff --git a/2018.js b/2018.js index 60bc7da..b44edd8 100644 --- a/2018.js +++ b/2018.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2018 }); +module.exports = getBaselineVersions({ baselineYear: 2018 }); diff --git a/2019.js b/2019.js index 57cb20f..7bc72c5 100644 --- a/2019.js +++ b/2019.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2019 }); +module.exports = getBaselineVersions({ baselineYear: 2019 }); diff --git a/2020.js b/2020.js index 4dad364..aca52eb 100644 --- a/2020.js +++ b/2020.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2020 }); +module.exports = getBaselineVersions({ baselineYear: 2020 }); diff --git a/2021.js b/2021.js index a81df09..ce0de96 100644 --- a/2021.js +++ b/2021.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2021 }); +module.exports = getBaselineVersions({ baselineYear: 2021 }); diff --git a/2022.js b/2022.js index 71ed930..00bd2fa 100644 --- a/2022.js +++ b/2022.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2022 }); +module.exports = getBaselineVersions({ baselineYear: 2022 }); diff --git a/2023.js b/2023.js index a27a3f8..73b0628 100644 --- a/2023.js +++ b/2023.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2023 }); +module.exports = getBaselineVersions({ baselineYear: 2023 }); diff --git a/2024.js b/2024.js index bfc90d5..58d961c 100644 --- a/2024.js +++ b/2024.js @@ -1,2 +1,2 @@ const getBaselineVersions = require("./scripts/get-baseline-versions"); -module.exports = getBaselineVersions({ targetYear: 2024 }); +module.exports = getBaselineVersions({ baselineYear: 2024 }); diff --git a/README.md b/README.md index 9d66cc9..7105a4d 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,22 @@ To target Baseline Widely Available, add the following to your `package.json`: } ``` +If you want to see your list of chosen browsers every time `browserslist` calls `browserslist-baseline-config`, add a `browserslist-config-baseline` object to your `package.json` with `logConfigToConsole` set to `true`: + + +```json +{ + "browserslist": [ + "extends browserslist-config-baseline" + ], + "browserslist-config-baseline": { + "logConfigToConsole": true + } +} +``` + +The `logConfigToConsole` option works with both of the target configuration options mentioned below. + The data in this package changes frequently as new browser versions are released and new web-features become interoperable. Consider updating this module regularly by adding one of these commands to your build scripts: ```sh @@ -50,7 +66,16 @@ bun update browserslist-config-baseline@latest If you haven't updated `browserslist-config-baseline` in the last month and you are targeting Widely Available, the package will check for updates whenever you run a `browserslist`-compatible tool and prompt you to upgrade if there is a new version available. -## Baseline year feature sets +## Configuring `browserslist-config-baseline` + +There are two ways to configure `browserslist-config-basesline`: + +- [Add options to the end of your `extends` statement](#configuring-targets-using-the-extends-statement). +- Using a `browserslist-config-baseline` configuration object in your `package.json`. + +## Configuring targets using the `extends` statement + +### Baseline year feature sets Baseline year feature sets include all the web platform features that were fully supported in the core browser set at the end of a given calendar year. To use a Baseline year feature set, add the year in the format `/YYYY` to the end of your `extends` statement: @@ -81,7 +106,7 @@ This equates to the following `browserslist` config: The minimum browser versions that support these feature sets are usually the last version released in that year or a few versions earlier. The feature set > browser version mappings in this module were determined using [`baseline-browser-mapping`](https://npmjs.org/baseline-browser-mapping). -## Include Chromium downstream browsers +### Include Chromium downstream browsers To include browsers that implement Chromium where possible, insert `/with-downstream` into your `extends` statement immediately after the package name: @@ -118,6 +143,81 @@ This equates to the following `browserslist` config: The minimum browser versions of non-core browsers are provided by `baseline-browser-mapping` based on two sources: [`@mdn/browser-compat-data`](https://npmjs.org/@mdn/browsers-compat-data) where those engine version mappings exist, and parsed user agents from [`useragents.io`](https://useragents.io) where necessary. For more information on these mappings, please see [`baseline-browser-mapping`'s README](https://www.npmjs.com/package/baseline-browser-mapping#downstream-browsers). +## Configuring targets using a `browserslist-config-baseline` object in `package.json` + +You can add a `browserslist-config-baseline` object to your `package.json` to set your Baseline target. + +> **NOTE** +> The `browserslist-config-baseline` config in `package.json` only works if you use the basic `extends` statement. If you add a `YYYY` year and/or `with-downstream` to your `extends` statement, that will take precedence over the target settings in your `browserslist-config-baseline` object. The `logConfigToConsole` option works with both config methods. + +### Target Baseline year feature sets + +To target a Baseline year, set the `baselineYear` property to the desired year: + + +```json +{ + "browserslist": [ + "extends browserslist-config-baseline" + ], + "browserslist-config-baseline": { + "baselineYear": 2020 + } +} +``` + +> **NOTE** +> You cannot use the `baselineYear` and `widelyAvailableOnDate` options together. The `baseline-browser-mapping` module that supplies data to `browserslist-config-baseline` will throw an error. + +### Target Baseline Widely available on a particular date + +To target Baseline Widely available on a particular date, set the `widelyAvailableOnDate` property to the desired date in the format `YYYY-MM-DD`: + + +```json +{ + "browserslist": [ + "extends browserslist-config-baseline" + ], + "browserslist-config-baseline": { + "widelyAvailableOnDate": "2020-06-01" + } +} +``` + +> **NOTE** +> You cannot use the `baselineYear` and `widelyAvailableOnDate` options together. The `baseline-browser-mapping` module that supplies data to `browserslist-config-baseline` will throw an error. + +### Include downstream browsers + +To include browsers the implement Chromium, set the `includeDownstreamBrowsers` property to `true`: + + +```json +{ + "browserslist": [ + "extends browserslist-config-baseline" + ], + "browserslist-config-baseline": { + "includeDownstreamBrowsers": true + } +} +``` + +## Logging your config to the console + +To see the array of minimum browser versions that you are passing to `browserslist`, add `logConfigToConsole: true` to your `package.json` config: + +```json +{ + "browserslist-config-baseline": { + "logConfigToConsole": true + } +} +``` + +This works with both methods of setting your target browsers. + ## See also - [WebDX Baseline specification](https://github.com/web-platform-dx/web-features/blob/main/docs/baseline.md) diff --git a/package.json b/package.json index af9d438..ec32fc1 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@httptoolkit/esm": "^3.3.1", - "baseline-browser-mapping": "^2.1.0", + "baseline-browser-mapping": "^2.2.0", "compare-versions": "^6.1.1" } } diff --git a/scripts/get-baseline-versions.js b/scripts/get-baseline-versions.js index e6b9c76..a031c67 100644 --- a/scripts/get-baseline-versions.js +++ b/scripts/get-baseline-versions.js @@ -1,8 +1,22 @@ require = require("@httptoolkit/esm")(module); bbm = require("baseline-browser-mapping"); -let transform = function (bbm_versions) { - var browsers = { +const fs = require("fs"); +const path = require("path"); + +function readConfig(loc, name) { + do { + try { + const pkg = require(path.join(loc, "package.json")); + if (pkg.hasOwnProperty(name)) return pkg[name]; + } catch { } + } while (loc !== (loc = path.dirname(loc))); + + return null; +} + +function transform(bbm_versions) { + const browsers = { chrome: "Chrome", chrome_android: "ChromeAndroid", edge: "Edge", @@ -21,13 +35,110 @@ let transform = function (bbm_versions) { return bbm_versions .filter((version) => Object.keys(browsers).includes(version.browser)) .map((version) => `${browsers[version.browser]} >= ${version.version}`); -}; +} + +function reconcileConfigs(extendsConfig) { + const bbmConfig = {}; + + const pkgConfig = + readConfig(process.cwd(), "browserslist-config-baseline") ?? {}; + + // Handle correct configurations + if (pkgConfig.widelyAvailableOnDate && !extendsConfig.baselineYear) + bbmConfig.widelyAvailableOnDate = pkgConfig.widelyAvailableOnDate; + + if (pkgConfig.baselineYear && !extendsConfig.baselineYear) + bbmConfig.targetYear = pkgConfig.baselineYear; + + if (extendsConfig.baselineYear && !pkgConfig.baselineYear) + bbmConfig.targetYear = extendsConfig.baselineYear; + + if ( + (extendsConfig.includeDownstreamBrowsers && + !pkgConfig.includeDownstreamBrowsers) || + (!extendsConfig.includeDownstreamBrowsers && + pkgConfig.includeDownstreamBrowsers) || + (extendsConfig.includeDownstreamBrowsers && + pkgConfig.includeDownstreamBrowsers) + ) + bbmConfig.includeDownstreamBrowsers = true; + + // Check to see if there are two configured target years + if (pkgConfig.baselineYear && extendsConfig.baselineYear) { + bbmConfig.targetYear = Math.min( + pkgConfig.baselineYear, + extendsConfig.baselineYear, + ); + + console.warn( + `[browserslist-config-baseline] You’ve set baselineYear: ` + + `${pkgConfig.baselineYear} in your package.json, but extended this ` + + `config as \`browserslist-config-baseline/${extendsConfig.baselineYear}\`.\n` + + `Proceeding with the lower option, baselineYear: ${bbmConfig.targetYear}.\n` + + `Remove baselineYear in package.json or use \`extend browserslist-config-baseline\` ` + + `to suppress this warning.`, + ); + } + + // Check to see if widelyAvailableOnDate is being used alongside extends .../YYYY + if (pkgConfig.widelyAvailableOnDate && extendsConfig.baselineYear) { + const widelyAvailableOnDate = new Date(pkgConfig.widelyAvailableOnDate); + const baselineYearDate = new Date(extendsConfig.baselineYear + "-12-31"); + + let stringFragment = ""; + + if (widelyAvailableOnDate < baselineYearDate) { + bbmConfig.widelyAvailableOnDate = pkgConfig.widelyAvailableOnDate; + stringFragment += `Proceeding with the lower option, widelyAvailableOnDate: ${pkgConfig.widelyAvailableOnDate}.\n`; + } else { + bbmConfig.targetYear = extendsConfig.baselineYear; + stringFragment += `Proceeding with the lower option, baselineYear: ${extendsConfig.baselineYear}.\n`; + } + + console.warn( + `[browserslist-config-baseline] You’ve set widelyAvailableOnDate: ` + + `"${pkgConfig.widelyAvailableOnDate}" in your package.json, but extended this ` + + `config as \`browserslist-config-baseline/${extendsConfig.baselineYear}\`.\n` + + stringFragment + + `Remove widelyAvailableOnDate in package.json or use \`extend browserslist-config-baseline\` ` + + `to suppress this warning.`, + ); + } + + // Check to see if extends and package have conflicting includeDownstreamBrowsers + if ( + extendsConfig.includeDownstreamBrowsers && + pkgConfig.includeDownstreamBrowsers === false + ) { + bbmConfig.includeDownstreamBrowsers = false; + console.warn( + `[browserslist-config-baseline]` + + `You've extended your browserslist config using \`/with-downstream\` ` + + `but set includeDownstreamBrowsers: false in package.json.\n` + + `Proceeding with includeDownstreamBrowsers: false.\n` + + `Remove includeDownstreamBrowsers: false in package.json or use` + + `\`extend browserslist-config-baseline\` to suppress this warning.`, + ); + } + + return { + bbmConfig: bbmConfig, + logConfigToConsole: pkgConfig.logConfigToConsole ?? false, + }; +} + +module.exports = function (extendsConfig = {}) { + const config = reconcileConfigs(extendsConfig); + + const versions = bbm.getCompatibleVersions(config.bbmConfig); + const listToReturn = transform(versions); + + if (config.logConfigToConsole) { + console.log( + "Your browserslist config from browserslist-config-baseline is:\n", + listToReturn, + ); + } -module.exports = function (config = {}) { - return transform( - bbm.getCompatibleVersions({ - targetYear: config.targetYear, - includeDownstreamBrowsers: config.includeDownstreamBrowsers, - }), - ); + return listToReturn; }; diff --git a/with-downstream/2016.js b/with-downstream/2016.js index fa8b405..d281589 100644 --- a/with-downstream/2016.js +++ b/with-downstream/2016.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2016, + baselineYear: 2016, includeDownstreamBrowsers: true, }); diff --git a/with-downstream/2017.js b/with-downstream/2017.js index a233128..081ba5b 100644 --- a/with-downstream/2017.js +++ b/with-downstream/2017.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2017, + baselineYear: 2017, includeDownstreamBrowsers: true, }); diff --git a/with-downstream/2018.js b/with-downstream/2018.js index 55848be..7bc5a2b 100644 --- a/with-downstream/2018.js +++ b/with-downstream/2018.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2018, + baselineYear: 2018, includeDownstreamBrowsers: true, }); diff --git a/with-downstream/2019.js b/with-downstream/2019.js index fb70e2a..b360d03 100644 --- a/with-downstream/2019.js +++ b/with-downstream/2019.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2019, + baselineYear: 2019, includeDownstreamBrowsers: true, }); diff --git a/with-downstream/2020.js b/with-downstream/2020.js index 32d5389..1897fd8 100644 --- a/with-downstream/2020.js +++ b/with-downstream/2020.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2020, + baselineYear: 2020, includeDownstreamBrowsers: true, }); diff --git a/with-downstream/2021.js b/with-downstream/2021.js index 14daab8..093342e 100644 --- a/with-downstream/2021.js +++ b/with-downstream/2021.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2021, + baselineYear: 2021, includeDownstreamBrowsers: true, }); diff --git a/with-downstream/2022.js b/with-downstream/2022.js index d7539f3..0fab452 100644 --- a/with-downstream/2022.js +++ b/with-downstream/2022.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2022, + baselineYear: 2022, includeDownstreamBrowsers: true, }); diff --git a/with-downstream/2023.js b/with-downstream/2023.js index e006301..8159d4f 100644 --- a/with-downstream/2023.js +++ b/with-downstream/2023.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2023, + baselineYear: 2023, includeDownstreamBrowsers: true, }); diff --git a/with-downstream/2024.js b/with-downstream/2024.js index b6057fa..deb1f40 100644 --- a/with-downstream/2024.js +++ b/with-downstream/2024.js @@ -1,5 +1,5 @@ const getBaselineVersions = require("../scripts/get-baseline-versions"); module.exports = getBaselineVersions({ - targetYear: 2024, + baselineYear: 2024, includeDownstreamBrowsers: true, });