-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Problem Statement
I've briefly chatted to @AbhiPrasad about this but we wanted to open the discussion up and get some feedback and ideas from others...
The current integration options are as follows:
/**
* If this is set to false, default integrations will not be added, otherwise this will internally be set to the
* recommended default integrations.
* TODO: We should consider changing this to `boolean | Integration[]`
*/
defaultIntegrations?: false | Integration[];
/**
* List of integrations that should be installed after SDK was initialized.
* Accepts either a list of integrations or a function that receives
* default integrations and returns a new, updated list.
*/
integrations?: Integration[] | ((integrations: Integration[]) => Integration[]);
There are a few issues I see with this:
defaultIntegrations: false
is not tree shakeable.- It looks like
defaultIntegrations
allowing an array is an internal implementation detail that has leaked into the public api- it's not clear why users would ever supply an array here
- It appears that the
integrations
function option solely exists to allow users to remove default integrations easily- Is there a better/cleaner way to offer this functionality?
Ultimately, we're stuck between a rock and hard place trying to provide a fully featured standard configuration, simple customisability and the ability to fully customise for those who want to reduce bundle size to the bare minimum.
Solution Brainstorm
We could remove defaultIntegrations
and supply a way to init the SDKs without any defaults and preferably one that allows tree shaking.
The obvious way to do this would be to have two different init
functions, one which includes the defaults and one which doesn't. For now I'm going to call these init
and initRaw
but I'm open to better suggestions!
It's also worth noting that initRaw
could also include no default Transport to allow for greatest "tree shakeability".
import { init, initRaw, defaultIntegrations } from '@sentry/xxx';
// init the sdk with defaults
init({
dsn: '__DSN__',
});
// this does the same as above!
initRaw({
dsn: '__DSN__',
integrations: defaultIntegrations,
})
Adding a custom integration:
import { init, initRaw, defaultIntegrations } from '@sentry/xxx';
import { MyWonderfulIntegration } from './integrations';
init({
dsn: '__DSN__',
integrations: [new MyWonderfulIntegration()]
});
initRaw({
dsn: '__DSN__',
integrations: [...defaultIntegrations, new MyWonderfulIntegration()],
})
Removing an integration:
import { init, initRaw, defaultIntegrations } from '@sentry/xxx';
init({
dsn: '__DSN__',
// this wont tree shake 🤷♂️
integrations: (itgs) => itgs.filter(i => i.name !== "Breadcrumbs")
});
initRaw({
dsn: '__DSN__',
// this wont tree shake either 🤷♂️
integrations: defaultIntegrations.filter(i => i.name !== "Breadcrumbs"),
})
initRaw({
dsn: '__DSN__',
integrations: [ /* manually include all the integrations you need for greatest tree shakability! */ ]
})
The integrations
function option + filtering by name string to remove an integration feels a bit nasty but currently it appears to be the simplest solution to exclude an integration 🤔