Подключение D3: CDN, npm, ES-модули

D3.js может быть подключена напрямую через CDN без установки сборщиков и пакетов. Такой способ используется в случаях, когда требуется быстрый старт или работа в окружениях без npm.

Базовое подключение выполняется через тег <script>:

<script src="https://d3js.org/d3.v7.min.js"></script>

После загрузки библиотеки в глобальной области видимости появляется объект d3, содержащий весь API.

<script>
  const svg = d3.select("body")
    .append("svg")
    .attr("width", 400)
    .attr("height", 200);

  svg.append("circle")
    .attr("cx", 200)
    .attr("cy", 100)
    .attr("r", 50);
</script>

Использование CDN удобно, но накладывает ряд особенностей:

  • библиотека загружается целиком, без возможности tree-shaking;
  • версия фиксируется URL-адресом;
  • код выполняется только после полной загрузки скрипта;
  • отсутствует модульная изоляция.

Популярные CDN-источники:

https://d3js.org/d3.v7.min.js
https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js
https://unpkg.com/d3@7/dist/d3.min.js

Подключение через CDN часто применяется для прототипов и учебных примеров, где важна минимальная настройка окружения.


Установка через npm

В проектах с Node.js и сборщиками предпочтительным способом становится установка через npm:

npm install d3

После установки пакет становится доступен в node_modules, а импорт выполняется через ES-модули или CommonJS (в зависимости от конфигурации сборщика).

Базовый импорт всей библиотеки:

import * as d3 from "d3";

Такой подход сохраняет доступ ко всему API, но не даёт преимуществ модульности на уровне сборки.

Использование полного импорта удобно в случаях:

  • небольших проектов;
  • прототипирования;
  • отсутствия требований к размеру бандла.

Однако в более сложных приложениях предпочтительнее точечные импорты.


Модульная структура и ES-модули

Современная архитектура D3.js построена вокруг ES-модулей. Библиотека разделена на отдельные пакеты, такие как:

  • d3-selection
  • d3-scale
  • d3-axis
  • d3-shape
  • d3-array

Каждый модуль можно импортировать отдельно:

import { sel ect } from "d3-selection";
import { scaleLinear } fr om "d3-scale";

Такой подход обеспечивает:

  • минимальный размер итогового бандла;
  • явные зависимости;
  • улучшенную читаемость кода;
  • совместимость с tree-shaking.

Пример использования модульного подхода:

import { sel ect } from "d3-selection";
import { scaleLinear } fr om "d3-scale";

const svg = sel ect("body")
  .append("svg")
  .attr("width", 400)
  .attr("height", 200);

const scale = scaleLinear()
  .domain([0, 100])
  .range([0, 300]);

svg.append("rect")
  .attr("x", 10)
  .attr("y", 50)
  .attr("width", scale(80))
  .attr("height", 20);

Использование ES-модулей в браузере

В современных браузерах ES-модули могут использоваться напрямую без сборщика:

<script type="module">
  import { sel ect } fr om "https://cdn.jsdelivr.net/npm/d3-selection@3/+esm";

  sel ect("body")
    .append("div")
    .text("D3 module import");
</script>

Такой вариант сочетает преимущества CDN и модульной структуры:

  • загрузка только необходимых частей;
  • отсутствие этапа сборки;
  • поддержка стандартного import.

При этом важно учитывать особенности:

  • кэширование зависит от конкретного URL версии;
  • производительность может быть ниже по сравнению с бандлингом;
  • требуется поддержка ES-модулей в браузере.

Сборка проекта с использованием npm и модулей D3

В связке с Vite, Webpack или Rollup импорт модулей D3.js интегрируется в процесс сборки.

Пример структуры:

src/
  main.js
  chart.js

chart.js:

import { sel ect } fr om "d3-selection";
import { scaleLinear } fr om "d3-scale";

export function createChart(container) {
  const svg = sel ect(container)
    .append("svg")
    .attr("width", 500)
    .attr("height", 300);

  const x = scaleLinear()
    .domain([0, 100])
    .range([0, 400]);

  svg.append("circle")
    .attr("cx", x(50))
    .attr("cy", 150)
    .attr("r", 30);
}

main.js:

import { createChart } fr om "./chart.js";

createChart("#app");

Сборщик анализирует зависимости и включает только используемые части библиотек, исключая неиспользуемый код.


Сравнение подходов подключения

CDN-подключение:

  • быстрое внедрение;
  • отсутствие настройки сборки;
  • глобальный объект d3;
  • отсутствие оптимизации размера.

npm + полный импорт:

  • единая точка доступа;
  • работа в модульной среде;
  • отсутствие tree-shaking.

npm + ES-модули:

  • точечные импорты;
  • минимальный размер бандла;
  • строгая структура зависимостей;
  • интеграция с современными сборщиками.

ESM в браузере:

  • отсутствие сборки;
  • гибкость подключения модулей;
  • зависимость от сети и версий CDN.

Версионность и совместимость

При подключении D3.js через CDN или npm важно учитывать различия между версиями. Начиная с D3 v5 произошёл переход к Promise-based API для загрузки данных, а с v6 усилилась модульная структура и переход на ES-модули.

Пример загрузки данных в новых версиях:

import { csv } fr om "d3-fetch";

csv("/data.csv").then(data => {
  console.log(data);
});

Изменения в версиях напрямую влияют на:

  • синтаксис импорта;
  • структуру модулей;
  • совместимость кода между проектами.

Практика организации импортов

В модульных проектах часто формируется единый слой реэкспорта:

// d3.js
export { sel ect } from "d3-selection";
export { scaleLinear } fr om "d3-scale";
export { axisBottom } from "d3-axis";

Далее используется централизованный импорт:

import { select, scaleLinear } from "./d3.js";

Такой подход упрощает поддержку кода и контроль используемых частей библиотеки, особенно при работе с крупными визуализациями и множеством компонентов.