Deck.gl представляет собой высокопроизводительную библиотеку визуализации геоданных и аналитических данных на основе WebGL. Современные версии библиотеки распространяются через npm-пакеты и ориентированы на использование вместе с системами сборки JavaScript-приложений. Корректная настройка сборщика напрямую влияет на размер итогового бандла, скорость загрузки приложения, производительность разработки и возможность использовать современные возможности языка.
В большинстве проектов Deck.gl используется совместно с:
Несмотря на появление современных инструментов сборки, webpack остаётся одним из наиболее распространённых решений в корпоративных и долгоживущих проектах.
Минимальный набор пакетов для использования Deck.gl с webpack выглядит следующим образом:
npm install deck.gl
npm install react react-dom
npm install webpack webpack-cli webpack-dev-server
npm install babel-loader @babel/core @babel/preset-env @babel/preset-react
Для TypeScript дополнительно устанавливаются:
npm install typescript ts-loader
или:
npm install typescript babel-loader @babel/preset-typescript
Структура проекта может выглядеть следующим образом:
project/
├── src/
│ ├── index.js
│ ├── App.jsx
│ └── layers/
├── public/
│ └── index.html
├── package.json
├── webpack.config.js
└── babel.config.json
Простейший файл конфигурации:
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
},
resolve: {
extensions: ['.js', '.jsx']
},
devServer: {
static: './public',
hot: true
}
};
Данная конфигурация обеспечивает:
Файл babel.config.json:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
После настройки Babel можно импортировать Deck.gl непосредственно в коде приложения:
import {DeckGL} from '@deck.gl/react';
Webpack обработает все зависимости и сформирует единый пакет для браузера.
Файл src/index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(
document.getElementById('root')
);
root.render(<App />);
Файл App.jsx:
import DeckGL from '@deck.gl/react';
export default function App() {
return (
<DeckGL
initialViewState={{
longitude: 37.6,
latitude: 55.75,
zoom: 10
}}
controller={true}
layers={[]}
/>
);
}
После сборки webpack сформирует единый бандл, содержащий React и Deck.gl.
Во время разработки применяется режим:
mode: 'development'
Для выпуска приложения используется:
mode: 'production'
Production-режим автоматически включает:
Пример запуска:
webpack --mode production
или через npm:
{
"scripts": {
"build": "webpack --mode production"
}
}
Deck.gl имеет модульную архитектуру.
Неэффективный импорт:
import * as deck from 'deck.gl';
Подобная запись способна увеличить размер итогового пакета.
Предпочтительный вариант:
import {ScatterplotLayer} from '@deck.gl/layers';
или:
import {GeoJsonLayer} from '@deck.gl/layers';
Webpack способен исключать неиспользуемые модули при построении production-сборки.
Пример:
import {ScatterplotLayer} from '@deck.gl/layers';
const layer = new ScatterplotLayer({
data
});
В итоговый бандл попадёт только необходимый код.
Deck.gl может использоваться лишь на отдельных страницах приложения.
В таких случаях полезно применять динамические импорты.
Без разделения:
import {GeoJsonLayer} from '@deck.gl/layers';
С разделением:
const GeoJsonLayer = await import(
'@deck.gl/layers'
);
или:
const module = await import('@deck.gl/layers');
const layer = new module.GeoJsonLayer({
data
});
Webpack создаст отдельный chunk-файл.
Преимущества:
Для больших картографических интерфейсов часто применяется ленивое подключение компонентов.
import React, {lazy} from 'react';
const MapPage = lazy(() =>
import('./MapPage')
);
Внутри MapPage могут располагаться тяжёлые слои
Deck.gl.
import {TileLayer} from '@deck.gl/geo-layers';
import {MVTLayer} from '@deck.gl/geo-layers';
Загрузка произойдёт только при открытии соответствующего маршрута.
Конфигурация webpack для TypeScript:
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: [
'.tsx',
'.ts',
'.js'
]
}
};
Файл tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"jsx": "react-jsx",
"strict": true
}
}
Пример использования слоя:
import {ScatterplotLayer} from '@deck.gl/layers';
const layer = new ScatterplotLayer({
id: 'points',
data
});
TypeScript предоставляет типизацию конфигураций слоёв и параметров визуализации.
Обработка крупных наборов данных может создавать нагрузку на главный поток браузера.
Webpack поддерживает подключение Worker-модулей:
const worker = new Worker(
new URL('./worker.js', import.meta.url)
);
Конфигурация webpack 5 не требует дополнительных загрузчиков.
Пример обработки геоданных:
worker.postMessage(bigDataset);
Внутри воркера:
self.onmess age = event => {
const processed = processData(event.data);
self.postMessage(processed);
};
Deck.gl получает уже подготовленные данные без блокировки интерфейса.
Размер приложения можно анализировать при помощи специального плагина.
Установка:
npm install webpack-bundle-analyzer
Подключение:
const {
BundleAnalyzerPlugin
} = require('webpack-bundle-analyzer');
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
};
После сборки открывается визуальная диаграмма зависимостей.
Чаще всего наибольший вклад в размер пакета вносят:
В больших проектах количество импортов быстро растёт.
Без алиасов:
import MapLayer from
'../. ./. ./. ./components/map/layers/MapLayer';
С алиасами:
resolve: {
alias: {
'@layers': path.resolve(
__dirname,
'src/layers'
)
}
}
Использование:
import MapLayer from '@layers/MapLayer';
Подобный подход значительно упрощает поддержку крупного проекта.
Слои Deck.gl часто используют внешние данные.
Например:
fetch('/data/cities.json')
Webpack позволяет автоматически копировать ресурсы.
Установка:
npm install copy-webpack-plugin
Настройка:
const CopyPlugin =
require('copy-webpack-plugin');
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'public/data',
to: 'data'
}
]
})
]
};
После сборки JSON-файлы будут доступны приложению.
Для разных окружений обычно применяются различные источники данных.
Установка:
npm install dotenv-webpack
Конфигурация:
const Dotenv = require('dotenv-webpack');
module.exports = {
plugins: [
new Dotenv()
]
};
Файл .env:
API_URL=https://api.example.com
Использование:
const url =
process.env.API_URL;
Это позволяет переключать конфигурации без изменения исходного кода.
При отладке сложных визуализаций важно видеть оригинальный код.
Настройка:
module.exports = {
devtool: 'source-map'
};
Варианты:
devtool: 'eval-source-map'
или:
devtool: 'cheap-module-source-map'
Преимущества:
Для production-сборок рекомендуется использовать хэширование файлов.
output: {
filename: '[name].[contenthash].js'
}
Пример результата:
main.8f5d13a2.js
vendors.a7827c3e.js
Браузер будет повторно загружать только изменённые файлы.
Deck.gl и React редко изменяются по сравнению с бизнес-логикой приложения.
Поэтому полезно выделять зависимости в отдельный пакет.
optimization: {
splitChunks: {
chunks: 'all'
}
}
Webpack автоматически сформирует отдельные файлы:
vendors.js
main.js
Преимущества:
Для разработки картографических приложений важна быстрая обратная связь.
Конфигурация:
devServer: {
port: 3000,
hot: true,
open: true
}
Запуск:
npx webpack serve
Возможности:
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true
},
resolve: {
extensions: ['.js', '.jsx']
},
optimization: {
splitChunks: {
chunks: 'all'
}
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
}
};
Подобная конфигурация обеспечивает эффективную работу приложений на базе Deck.gl, поддерживает современные возможности JavaScript, уменьшает размер итогового бандла, ускоряет загрузку картографических интерфейсов и создаёт основу для масштабирования крупных проектов визуализации геоданных.