Scopes
This package is designed to give developers full control over its lifecycle, including the initialization process. Therefore, there are no pre-initialized global scopes available for use; developers must configure the scopes themselves.
By scope, we refer to a collection of related functionality grouped into a single entity. Examples of scopes include backButton
and mainButton
. This design makes the SDK more intuitive and efficient to use.
It's important to note that scopes are provided in the following forms:
💠Components. They are exported as both a variable and a set of functions simultaneously. For instance, developers can work with the exported backButton
variable or its alternative function set: showBackButton
, mountBackButton
, etc.
⚙️Utilities. They are exported as a set of functions. These scopes are abstract and not grouped into a single variable. Examples include openLink
, shareURL
, etc.
Effectively, exported variables are simply compositions of the same exported functions. So, backButton.isMounted
and isBackButtonMounted
are essentially the same entity.
Here's an example:
import {
backButton,
hideBackButton,
isBackButtonVisible,
} from '@telegram-apps/sdk';
isBackButtonVisible(); // false
backButton.show();
// backButton.isVisible and isBackButtonVisible are the same
// entity (signal). We can say the same about backButton.show
// and showBackButton.
//
// backButton.isVisible() -> true
// isBackButtonVisible() -> true
hideBackButton();
// backButton.isVisible() -> false
// isBackButtonVisible() -> false
The key difference here lies in the final bundle size. Internally, the backButton
export is handled through the following code:
export * as backButton from 'somewhere';
When not using the package source code while building the application, the bundler is more likely to make backButton
a non-treeshakeable object. As a result, all dependencies from somewhere
will be bundled, slightly increasing the final bundle size (though not by much).
Optimizing Bundle
TIP
The SDK works efficiently out of the box, so there is generally no need to follow the optimizations described in this section. However, these guidelines can be helpful if you want to maximize the package's efficiency in specific scenarios.
Let’s look at how we can use the package more efficiently:
- Using functions exclusively allows the bundler to tree-shake unused scope code.
import { showBackButton, backButton } from '@telegram-apps/sdk';
showBackButton();
// Only showBackButton's source code will be bundled.
backButton.show();
// All backButton dependencies will be bundled, even
// if not used in the code: backButton.show(),
// backButton.hide(), backButton.isVisible(), etc.
- Configure the bundler to use the source code instead of the built version.
import { backButton } from '@telegram-apps/sdk';
backButton.show();
// Only backButton.show's source code will be bundled
// because the bundler is smart enough to understand
// that backButton.show is just the showBackButton
// function, so only its source code is bundled.
Here's an example of a Vite config using the resolve
option:
import { defineConfig } from 'vite';
import { resolve } from 'node:path';
export default defineConfig({
resolve: {
alias: {
'@telegram-apps/sdk': resolve('node_modules/@telegram-apps/sdk/src'),
},
},
});