Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New minimal import API, improve exported option types. #13890

Merged
merged 41 commits into from Jan 3, 2021

Conversation

pissang
Copy link
Contributor

@pissang pissang commented Dec 28, 2020

Brief Information

This pull request is about refactoring of exports so developers can have better API to get minimal imports.
Also, in this PR ts is upgraded to 4.1 to make sure exported types won't have problems in the higher ts version.

Related ZRender PR: ecomfe/zrender#685

Fixed issues

#13764
#13755
#13763
#13850
#13701
#13804

Details

Before: What was the problem?

We kept providing CommonJS modules in the earlier version because we want to make sure echarts can be compatible with environments as more as possible, like old Webpack and NodeJS.
So after rewriting our code with TypeScript. We still export two kinds of modules, CommonJS and ESM. CommonJS modules are in the lib folder, which is the same as the previous version and mainly used in NodeJS. ESM modules are in the esm folder, which will be used in the bundlers which target browser. This brings a serious issue, we were suggesting developers using the lib folder when import modules. Like import * as echarts from 'echarts/lib/echarts'. But now in most scenarios ESM module is much better because bundler can tree-shake it and get a smaller bundle. This contradiction leads us to not know how to deal with the compatibility when still providing a best practice.
Even worse, because codes of different extensions may both reference lib and esm. The bundle will have two namespaces. This leads to a much larger bundle size and bugs like registered components can not be found.

After: How is it fixed in this PR?

First of all, we remove CommonJS modules and export ESM format modules in the lib folder. Since very few bundlers don't support ESM module now. And for NodeJS we can provide the UMD format dist/echarts.js

Sencondly, we provide a higher level of exports for each components and each to avoid exposing our underlying folder structure and provide a use method to register the components

import {LineChart} from 'echarts/charts';
import {GridComponent} from 'echarts/components';
import {CanvasRenderer} from 'echarts/renderers';
import {use} from 'echarts/core';
// Must import at least one renderer, SVGRenderer or CanvasRenderer.
use([LineChart, GridComponent, CanvasRenderer]);

For TypeScript, we also provide a better type when using the new minimal imports.

import {LineChart, LineSeriesOption} from 'echarts/charts';
import {GridComponent, GridComponentOption} from 'echarts/components';
import {use, ComposeOption} from 'echarts/core';

use([LineChart, GridComponent]);

// A minimal types for option is useful for checking if any components are missing.
type ECOption = ComposeOption<LineSeriesOption | GridComponentOption>;
const option: ECOption = {};

Usage

Are there any API changes?

  • The API has been changed.

Related test cases or examples to use the new APIs

Import the whole package.

Importing of whole package is not changed.

import * as echarts from 'echarts';
const option: echarts.EChartsOption = {};

On top of that, we expose more types for cases like #13755

import * as echarts from 'echarts';
const lineOption: echarts.LineSeriesOption = {};

Minimal import.

import * as echarts from 'echarts/core';
import { GridComponent, GridComponentOption } from 'echarts/components';
import { LineChart, LineSeriesOption } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';

// Must import at least one renderer.
// If you only want to render with SVG, just replace the CanvasRenderer with SVGRenderer.
// So the CanvasRenderer won't be included in the final bundle.
echarts.use([GridComponent, LineChart, CanvasRenderer]);

// A minimal types for option is useful for checking if any components are missing.
type EChartsOption = echarts.ComposeOption<GridComponentOption | LineSeriesOption>;
var option: EChartsOption = {...};

// If you want the full option. 
import {EChartsOption} from 'echarts;
var option: EChartsOption = {...};

Then let the bundler do the tree-shaking and remove all unused components.

PS: We are working on generating tests of this minimal import in the https://github.com/apache/incubator-echarts-examples/tree/next. We will provide a new feature in the example page about generating a minimal import code based on the example option.

The legacy minimal import is still supported but not suggested.

// See https://github.com/apache/incubator-echarts/issues/13701
import * as echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/line';
import 'echarts/lib/component/grid';

This is still supported. You should use it only when tree-shaking can't work in the bundlers.

Internal changes

All very core modules have been moved into core dir. The original src/echarts.ts has been changed to only export necessary modules for compatible reasons.

So the old code

import * echarts from 'echarts/lib/echarts'

Can still work well to avoid issues like #13701

But for the new minimal import code. We can tree shake it as much as possible. For example, we can remove the CanvasRenderer if we only wan't to render with SVG now.

Other Changes

The dependencies in theme and i18n has been changed from echarts to echarts/lib/echarts to avoid bundling the whole package. ecomfe/vue-echarts#345 (comment)

import {use, init} from 'echarts/core';
import {ChartBar} from 'echarts/charts';
import {ComponentGrid} from 'echarts/components';
use([ChartBar, ComponentGrid]);
optimize inner option determination
@echarts-bot
Copy link

echarts-bot bot commented Dec 28, 2020

Thanks for your contribution!
The community will review it ASAP. In the meanwhile, please checkout the coding standard and Wiki about How to make a pull request.

The pull request is marked to be PR: author is committer because you are a committer of this project.

Document changes are required in this PR. Please also make a PR to apache/incubator-echarts-doc for document changes. When the doc PR is merged, the maintainers will remove the PR: awaiting doc label.

@echarts-bot echarts-bot bot removed the PR: awaiting doc Document changes is required for this PR. label Dec 28, 2020
@pissang pissang changed the title chore: improve minimal imports, option exports. Improve minimal imports, option exports. Dec 28, 2020
@pissang pissang changed the title Improve minimal imports, option exports. New minimal import API, improve exported option types. Dec 28, 2020
@plainheart
Copy link
Member

Wow! Looks great!

@pissang pissang added this to the 5.0.1 milestone Dec 28, 2020
100pah
100pah previously approved these changes Dec 30, 2020
@pissang pissang merged commit 0fc80c7 into master Jan 3, 2021
@echarts-bot
Copy link

echarts-bot bot commented Jan 3, 2021

Congratulations! Your PR has been merged. Thanks for your contribution! 👍

@pissang pissang deleted the treeshakable-exports branch January 3, 2021 15:20
@ThomasBower
Copy link

Amazing work, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants