@web/dev-server-esbuild
Version:
Plugin for using esbuild in @web/dev-server
88 lines (69 loc) • 2.9 kB
text/typescript
import { browsers } from '@mdn/browser-compat-data';
type Release = { status: string };
export type Browser = { name: string; version: string };
export const TARGET_LATEST_MODERN = createModernTarget();
// earliest browser versions to support module scripts, dynamic imports and import.meta
export const TARGET_LOWEST_ESM_SUPPORT = ['chrome64', 'edge79', 'firefox67', 'safari11.1'];
function createModernTarget() {
try {
const latestChrome = getLatestStableMajor(browsers.chrome.releases);
if (!latestChrome) throw new Error('Could not find latest Chrome major version');
const latestEdge = getLatestStableMajor(browsers.edge.releases);
if (!latestEdge) throw new Error('Could not find latest Edge major version');
const latestSafari = getLatestStableMajor(browsers.safari.releases);
if (!latestSafari) throw new Error('Could not find latest Safari major version');
const latestFirefox = getLatestStableMajor(browsers.firefox.releases);
if (!latestFirefox) throw new Error('Could not find latest Firefox major version');
return [
`chrome${latestChrome - 1}`,
`edge${latestEdge - 1}`,
`safari${latestSafari}`,
`firefox${latestFirefox}`,
];
} catch (error) {
throw new Error(
`Error while initializing default browser targets for @web/dev-server-esbuild: ${
(error as Error).message
}`,
);
}
}
function getMajorVersion(version: string | number) {
return Number(version.toString().split('.')[0]);
}
export function getLatestStableMajor(releases: Record<string, Release>): number | undefined {
const release = Object.entries(releases).find(([, release]) => release.status === 'current')?.[0];
if (release) {
return getMajorVersion(release);
}
return undefined;
}
function isWithinRange(releases: Record<string, Release>, version: string | number, range: number) {
const currentMajorVersion = getMajorVersion(version);
const latestMajorVersion = getLatestStableMajor(releases);
if (latestMajorVersion == null) {
return false;
}
return currentMajorVersion >= latestMajorVersion - range;
}
export function isLatestSafari({ name, version }: Browser) {
const nameLowerCase = name.toLowerCase();
// don't use include to avoid matching safari iOS
if (nameLowerCase === 'safari') {
return isWithinRange(browsers.safari.releases, version, 0);
}
return false;
}
export function isLatestModernBrowser({ name, version }: Browser) {
const nameLowerCase = name.toLowerCase();
if (['chrome', 'chromium'].some(name => nameLowerCase.includes(name))) {
return isWithinRange(browsers.chrome.releases, version, 1);
}
if (nameLowerCase.includes('edge')) {
return isWithinRange(browsers.edge.releases, version, 1);
}
if (nameLowerCase.includes('firefox')) {
return isWithinRange(browsers.firefox.releases, version, 0);
}
return false;
}