bowser-js / bowser

a browser detector
Other
5.48k stars 486 forks source link

Composable architecture #505

Open marcodejongh opened 2 years ago

marcodejongh commented 2 years ago

I've been analysing the 3rd party dependencies we use at Atlassian, and Bowser stood out as 1 thing that seemed large for what we use it for. The majority of our call-sites of bowser use the library to parse the browser name and browser version. We don't use any of the other parsing functionality and we also only care about the major browsers, so I set out for a big culling mission here: https://github.com/atlassian-forks/bowser/pull/1. This reduced bundle size down to 2kb gzipped: https://bundlephobia.com/package/bowser-ultralight@1.0.5.

But the fork I've created obviously isn't going to be for everyone, but I'm thinking we might be able to get the same benefits in the main bowser project by making the architecture more composable. Without having to resort to people like creating forks that remove anything they don't want.

Atm Bowser imports all it's parsing functionality in the parser.js file: https://github.com/lancedikson/bowser/blob/master/src/parser.js#L1-L4

What if instead we changed the module to be more composable, so that from a consumer side it could look like this:

import { browsers, platform } from 'bowser/parser';
import ComposableBowser from 'bowser/composable';

new ComposableBowser( { parsers: [browsers, platform] } )
    .getParser(
      typeof navigator !== 'undefined' ? navigator.userAgent || '' : '',
    )

The benefit of this approach is that now ComposableBowser is only going to download the required parts. The original Bowser entry point can be left as is for now, it would just require some refactoring to move the imports of the parsers out of the parser file itself, and make it support the composable behaviour.