Подключение API на TypeScript
Обычное подключение
<!DOCTYPE html>
<html>
<head>
<!-- Вместо YOUR_API_KEY подставить значение настоящего ключа -->
<script src="https://api-maps.yandex.ru/v3/?apikey=YOUR_API_KEY&lang=ru_RU"></script>
<script type="module" src="index.js"></script>
</head>
<body>
<div id="app" style="width: 600px; height: 400px"></div>
</body>
</html>
import type { YMapLocationRequest } from 'ymaps3';
async function initMap(): Promise<void> {
await ymaps3.ready;
const LOCATION: YMapLocationRequest = {
center: [37.623082, 55.75254],
zoom: 9
};
const { YMap, YMapDefaultSchemeLayer } = ymaps3;
const map = new YMap(document.getElementById('app'), { location: LOCATION });
map.addChild(new YMapDefaultSchemeLayer({}));
}
initMap();
{
"compilerOptions": {
"target": "es2015",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"esModuleInterop": true,
"moduleResolution": "node",
"typeRoots": [
"./node_modules/@types",
"./node_modules/@yandex/ymaps3-types"
],
"paths": {
"ymaps3": [
"./node_modules/@yandex/ymaps3-types"
]
}
}
}
{
"devDependencies": {
"@yandex/ymaps3-types": "^0.0.27",
"http-server": "14.1.1",
"typescript": "5.2.2"
},
"scripts": {
"compile": "./node_modules/.bin/tsc",
"start": "npx http-server ."
}
}
Поставьте зависимости, скомпилируйте typescript
и запустите локальный сервер:
npm install
npm run compile
npm run start
Откройте приложение
Особенности обычного подключения
-
В
package.json
добавляем dev-зависимость от пакета@yandex/ymaps3-types
.Рекомендуется устанавливать последнюю версию:
npm i --save-dev @yandex/ymaps3-types@latest
-
В
tsconfig.json
задаёмcompilerOptions.typeRoots
со списком путей к файлам типов. Добавляем туда путь к пакету@yandex/ymaps3-types
, благодаря чему в глобальной области видимости появляется пространство именymaps3
с типами.Примечание
Пространство имен
ymaps3
содержит все типы классов, которые предоставляет JS API, но до резолваymaps3.ready
в среде выполнения они недоступны. -
В
tsconfig.json
задаёмcompilerOptions.paths
, в которой сообщаем ts-компилятору о том, что при импорте пакетаymaps3
его контент следует искать по указанному пути. Благодаря этому в проектных файлах можно импортировать типы словно они лежат не в@yandex/ymaps3-types
, а в пакетеymaps3
:import type { YMapLocationRequest } from 'ymaps3';
Все типы должны быть импортированы из корня.
Внутренняя структура не гарантирована и может меняться со временем.
-
В теге
script
, который загружает скомплированный проектный js, указываем атрибутtype="module"
, чтобы браузер активировал поддержкуESM
в js-файлах.Если в примере этого не сделать, возникнет ошибка:
SyntaxError: Unexpected token 'export {}'
Подключение через top-level-await (рекомендуется)
<!DOCTYPE html>
<html>
<head>
<!-- Вместо YOUR_API_KEY подставить значение настоящего ключа -->
<script src="https://api-maps.yandex.ru/v3/?apikey=YOUR_API_KEY&lang=ru_RU"></script>
<script type="module" src="index.js"></script>
</head>
<body>
<div id="app" style="width: 600px; height: 400px"></div>
</body>
</html>
import type { YMapLocationRequest } from 'ymaps3'
import { YMap, YMapDefaultSchemeLayer } from './lib/ymaps.js'
const LOCATION: YMapLocationRequest = {
center: [37.588144, 55.733842],
zoom: 9
};
const map = new YMap(
document.getElementById('app'),
{
location: LOCATION
}
);
map.addChild(new YMapDefaultSchemeLayer());
await ymaps3.ready;
export const {YMap, YMapDefaultSchemeLayer} = ymaps3;
{
"compilerOptions": {
"target": "es2017",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"typeRoots": [
"./node_modules/@types",
"./node_modules/@yandex/ymaps3-types"
],
"paths": {
"ymaps3": [
"./node_modules/@yandex/ymaps3-types"
]
}
}
}
{
"devDependencies": {
"@yandex/ymaps3-types": "^0.0.27",
"http-server": "14.1.1",
"typescript": "5.2.2"
},
"scripts": {
"compile": "./node_modules/.bin/tsc",
"start": "npx http-server ."
}
}
Поставьте зависимости, скомпилируйте typescript
и запустите локальный сервер:
npm install
npm run compile
npm run start
Откройте приложение
Особенности
-
В теге script, который загружает скомпилированный проектный js, указываем атрибут
type="module"
, чтобы активировать поддержку ECMAScript Modules (ESM) и top-level-await:<script type="module" src="index.js"></script>
Поддержка ESM при использовании бандлеров
Если для сборки проекта используется бандлер, например Webpack, то в файл
package.json
необходимо добавить"type": "module"
-
В
tsconfig.json
, для корректной работы top-level-await, параметрcompilerOptions.module
должен быть установлен в одно из следующих значений:es2022
,esnext
,system
илиpreserve
. Также параметрcompilerOptions.target
должен бытьes2017
или выше. -
В файле
lib/ymaps.ts
дожидаемся полной загрузки JS API, после чего экспортируем необходимые компоненты карты для их использования в других частях проекта:await ymaps3.ready; export const {YMap, YMapDefaultSchemeLayer} = ymaps3;
-
Использование top-level-await в
lib/ymaps.ts
гарантирует выполнениеymaps3.ready
до импорта компонентов карты, поэтому проектный код можно писать короче и опрятнее (больше не нужна асинхронная функция initMap):import { YMap, YMapDefaultSchemeLayer } from './lib/ymaps.js' const map = new YMap({...});
Подключение с Webpack
Способ №1
<!DOCTYPE html>
<html>
<head>
<!-- Вместо YOUR_API_KEY подставить значение настоящего ключа -->
<script src="https://api-maps.yandex.ru/v3/?apikey=YOUR_API_KEY&lang=ru_RU"></script>
<script src="build/bundle.js"></script>
</head>
<body>
<div id="app" style="width: 600px; height: 400px"></div>
</body>
</html>
import { type YMapLocationRequest } from 'ymaps3';
async function initMap() {
await ymaps3.ready;
const LOCATION: YMapLocationRequest = {
center: [37.623082, 55.75254],
zoom: 9
};
const { YMap, YMapDefaultSchemeLayer } = ymaps3;
const map = new YMap(document.getElementById('app'), {location: LOCATION});
map.addChild(new YMapDefaultSchemeLayer({}));
}
initMap();
{
"compilerOptions": {
"target": "es2015",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"esModuleInterop": true,
"moduleResolution": "node",
"typeRoots": [
"./node_modules/@types",
"./node_modules/@yandex/ymaps3-types"
],
"paths": {
"ymaps3": [
"./node_modules/@yandex/ymaps3-types"
]
}
},
}
const path = require('path');
module.exports = {
mode: 'development',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'build'),
},
devtool: 'cheap-source-map'
};
{
"scripts": {
"compile": "./node_modules/.bin/tsc",
"build": "webpack",
"start": "npx http-server ."
},
"devDependencies": {
"@yandex/ymaps3-types": "^0.0.27",
"http-server": "14.1.1",
"typescript": "5.2.2",
"webpack": "5.88.2",
"webpack-cli": "5.1.4"
}
}
Поставьте зависимости, скомпилируйте typescript
, соберите проект и запустите локальный сервер:
npm install
npm run compile
npm run build
npm run start
Откройте приложение
Этот способ ничем не отличается от предыдущего подключения. Добавляется только шаг сборки из проектных js
-файлов в единый build/bundle.js
Способ №2
<!DOCTYPE html>
<html>
<head>
<script src="build/bundle.js"></script>
</head>
<body>
<div id="app" style="width: 600px; height: 400px"></div>
</body>
</html>
import type { YMapLocationRequest } from '@yandex/ymaps3-types';
import {YMap, YMapDefaultSchemeLayer} from '@yandex/ymaps3-types';
const LOCATION: YMapLocationRequest = {
center: [37.623082, 55.75254],
zoom: 9
};
const map = new YMap(document.getElementById('app'), {location: LOCATION});
map.addChild(new YMapDefaultSchemeLayer({}));
{
"compilerOptions": {
"target": "es2015",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"esModuleInterop": true,
"moduleResolution": "node",
"typeRoots": [
"./node_modules/@types",
"./node_modules/@yandex/ymaps3-types"
]
},
}
const path = require('path');
module.exports = {
mode: 'development',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'build'),
},
externals: {
'@yandex/ymaps3-types': [
`promise new Promise((resolve) => {
if (typeof ymaps3 !== 'undefined') {
return ymaps3.ready.then(() => resolve(ymaps3));
}
const script = document.createElement('script');
script.src = "https://api-maps.yandex.ru/v3/?apikey=YOUR_API_KEY&lang=ru_RU";
script.onload = () => {
ymaps3.ready.then(() => resolve(ymaps3));
};
document.head.appendChild(script);
})`
]
},
devtool: 'cheap-source-map'
};
{
"scripts": {
"compile": "./node_modules/.bin/tsc",
"build": "webpack",
"start": "npx http-server ."
},
"devDependencies": {
"@yandex/ymaps3-types": "^0.0.27",
"http-server": "14.1.1",
"typescript": "5.2.2",
"webpack": "5.88.2",
"webpack-cli": "5.1.4"
}
}
Поставьте зависимости, скомпилируйте typescript
, соберите проект и запустите локальный сервер:
npm install
npm run compile
npm run build
npm run start
Откройте приложение
Особенности
-
Больше не нужно в шапке
HTML
-страницы подключать тег<script>
. Этим занимается сам webpack. -
В
webpack.config.js
объявляем external-переменную@yandex/ymaps3-types
, в которой указываем путь к загрузчику API и там же происходит разрешение промисаymaps3.ready
.Благодаря этому в проектном коде появляется возможность импортировать типы и классы JS API так, словно код поставляется не через глобальную переменную, а через
npm
-пакет@yandex/ymaps3-types
:// Импорт типов import type { YMapLocationRequest } from '@yandex/ymaps3-types'; // Импорт runtime-кода import {YMap, YMapDefaultSchemeLayer} from '@yandex/ymaps3-types';
-
В
tsconfig.json
больше не нужна настройкаcompilerOptions.paths.ymaps3
. -
При таком подключении в собранном проектном
js
-файле становятся доступны полностью загруженные модули JS API и гарантируется исполнениеymaps3.ready
, поэтому проектный код можно писать короче и опрятнее (больше не нужна асинхронная функцияinitMap
):import type { YMapLocationRequest } from '@yandex/ymaps3-types'; import {YMap, YMapDefaultSchemeLayer} from '@yandex/ymaps3-types'; const {YMap} = ymaps3; const map = new YMap({...});
Настройка alias
Обратите внимание, в последнем примере импорт происходит из пакета с названием @yandex/ymaps3-types
. Это название можно изменить с помощью алиаса в package.json
:
{
"devDependencies": {
// ...
"@yandex/ymaps3": "npm:@yandex/ymaps3-types@0.0.27",
// ...
}
}
После этого не забудьте обновите имя external-переменной в webpack.config.js
:
module.exports = {
//...
externals: {
'@yandex/ymaps3': [
// ...
]
}
}
После всех изменений импорт типов и классов можно сделать из пакета @yandex/ymaps3
:
import type { YMapLocationRequest } from '@yandex/ymaps3';
import {YMap, YMapDefaultSchemeLayer} from '@yandex/ymaps3';