import type { Tree } from '@nrwl/devkit'; import { logger, visitNotIgnoredFiles } from '@nrwl/devkit'; import { basename } from 'path'; const validBrowserslistConfigFilenames = new Set([ 'browserslist', '.browserslistrc', ]); export const DEFAULT_BROWSERS = [ 'last 1 Chrome version', 'last 1 Firefox version', 'last 2 Edge major versions', 'last 2 Safari major versions', 'last 2 iOS major versions', 'Firefox ESR', ]; export default async function removeBrowserlistConfig(tree: Tree) { let browserslist: any; try { browserslist = await import('browserslist'); } catch { logger.warn( 'Skipping migration because the "browserslist" package could not be loaded.' ); return; } // Set the defaults to match the defaults in build-angular. browserslist.defaults = DEFAULT_BROWSERS; const defaultSupportedBrowsers = new Set(browserslist(DEFAULT_BROWSERS)); const es5Browsers = new Set(browserslist(['supports es6-module'])); visitNotIgnoredFiles(tree, '/', (path) => { const fileName = basename(path); if ( !validBrowserslistConfigFilenames.has(fileName) || path.startsWith('node_modules') ) { return; } const { defaults: browsersListConfig, ...otherConfigs } = browserslist.parseConfig(tree.read(path, 'utf-8')); if (Object.keys(otherConfigs).length) { // The config contains additional sections. return; } const browserslistInProject = browserslist( // Exclude from the list ES5 browsers which are not supported. browsersListConfig.map((s) => `${s} and supports es6-module`), { ignoreUnknownVersions: true, } ); if (defaultSupportedBrowsers.size !== browserslistInProject.length) { return; } const shouldDelete = browserslistInProject.every((browser) => defaultSupportedBrowsers.has(browser) ); if (shouldDelete) { // All browsers are the same as the default config. // Delete file as it's redundant. tree.delete(path); } }); }