背景

G 4.0 之前,整个 入口是统一的,通过 svg、canvas renderer 来区分,这种情况下做多引擎切换和按需是打包简单的。

G 4.0 之后,画布变成多个 entry,如何做到按需加载 SVG、Canvas 包由开发者来控制,以便 G2 层做到按需引入。

方案

概略来说,因为 G 层没有 renderer 管理的部分,所以有 G2 增加一个 G 版本管理的小模块,提供注册功能给开发者,内部仅消费。全量 G2 注册 svg、canvas 两个。

  • engine 管理

在 G2 层增加 registerEngine,getEngine API 去注册和获取引擎,然后由开发者去注册 svg、canvas 版本的 G,注册的类是各个引擎的 Canvas。

  1. const ENGINES = {};
  2. export function getEngine(name: string) {
  3. return ENGINES[name];
  4. }
  5. export function registerEngine(name: string, engine: G) {
  6. ENGINES[name] = engine;
  7. }
  • 注册 engine

index.ts全量注册两个 G 版本。core.ts不注册任何 G。

  1. import * as Canvas from '@antv/g-canvas';
  2. import * as SVG from '@antv/g-svg';
  3. import { registerEngine } from '@antv/g2/lib/core';
  4. registerEngine('canvas', Canvas);
  5. registerEngine('svg', SVG);
  • Chart.ts消费 engine
  1. import { getEngine } from './engine';
  2. class Chart {
  3. // ...
  4. createCanvas() {
  5. const renderer = this.renderer;
  6. const G = getEngine(renderer);
  7. this.canvas = new G.Canvas({
  8. width: this.width,
  9. height: this.height,
  10. // ...
  11. });
  12. }
  13. // ...
  14. }
  • G 层要求
  1. g-canvas 和 g-svg 的 export 保持一模一样
  2. g-base 中 export G 的类型定义

弊 & 优

  • 弊端

因为 G 多 entry 导致上层需要

  1. 做一个 engine 管理的东西,有点冗余
  2. 需要 G2 层额外提供 engine 管理的两个方法
  3. 代码写法上的问题
  • 优点

开发者可以完全自定义加载,按需打包上也会做的比较好一些。