Skip to content

Commit

Permalink
feat: add ESM support (#10525)
Browse files Browse the repository at this point in the history
* feat: add ESM support

* build: rename UMD bundle

* chore: edit supbackages description

* style: disable es/no-import-meta linter rule

* test: dynamic import in cjs module

* docs: edit integrations page

* docs: review fixes

* chore: remove useless regex in webpack config

* ci: test size-limit only for ESM bundle
  • Loading branch information
dangreen authored Aug 4, 2022
1 parent a4de430 commit ce375a6
Show file tree
Hide file tree
Showing 89 changed files with 227 additions and 280 deletions.
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
dist/*.js
dist/*
1 change: 1 addition & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ rules:
no-empty-function: "off"
no-use-before-define: ["error", { "functions": false }]
# disable everything, except Rest/Spread Properties in ES2018
es/no-import-meta: "off"
es/no-async-iteration: "error"
es/no-malformed-template-literals: "error"
es/no-regexp-lookbehind-assertions: "error"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ npm-debug.log*
build/
# generated typedocs
docs/api
docs/.vuepress/dist

# Development
.DS_Store
Expand Down
16 changes: 5 additions & 11 deletions .size-limit.js → .size-limit.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,40 @@ function modifyWebpackConfig(config) {
module.exports = [
{
path: 'dist/chart.js',
limit: '94.8 KB',
webpack: false,
running: false
},
{
path: 'dist/chart.esm.js',
limit: '75 KB',
webpack: false,
running: false
},
{
path: 'dist/chart.esm.js',
path: 'dist/chart.js',
limit: '34 KB',
import: '{ Chart }',
running: false,
modifyWebpackConfig
},
{
path: 'dist/chart.esm.js',
path: 'dist/chart.js',
limit: '19.5 KB',
import: '{ BarController, BubbleController, DoughnutController, LineController, PolarAreaController, PieController, RadarController, ScatterController }',
running: false,
modifyWebpackConfig
},
{
path: 'dist/chart.esm.js',
path: 'dist/chart.js',
limit: '14 KB',
import: '{ ArcElement, LineElement, PointElement, BarElement }',
running: false,
modifyWebpackConfig
},
{
path: 'dist/chart.esm.js',
path: 'dist/chart.js',
limit: '27 KB',
import: '{ Decimation, Filler, Legend, SubTitle, Title, Tooltip }',
running: false,
modifyWebpackConfig
},
{
path: 'dist/chart.esm.js',
path: 'dist/chart.js',
limit: '22 KB',
import: '{ CategoryScale, LinearScale, LogarithmicScale, RadialLinearScale, TimeScale, TimeSeriesScale }',
running: false,
Expand Down
4 changes: 4 additions & 0 deletions auto/auto.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {Chart} from '../types';

export * from '../types';
export default Chart;
7 changes: 6 additions & 1 deletion auto/auto.js
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
module.exports = require('../dist/chart');
import {Chart, registerables} from '../dist/chart.js';

Chart.register(...registerables);

export * from '../dist/chart.js';
export default Chart;
5 changes: 0 additions & 5 deletions auto/auto.mjs

This file was deleted.

4 changes: 0 additions & 4 deletions auto/auto.mts

This file was deleted.

7 changes: 4 additions & 3 deletions auto/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "chart.js-auto",
"private": true,
"description": "auto registering package",
"description": "Auto registering package. Exists to support bundlers without exports support such as webpack 4.",
"type": "module",
"main": "auto.js",
"module": "auto.mjs",
"types": "auto.mts"
"exports": "./auto.js",
"types": "auto.d.ts"
}
6 changes: 2 additions & 4 deletions docs/.vuepress/config.js → docs/.vuepress/config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ module.exports = {
[
'vuepress-plugin-typedoc',
{
entryPoints: ['../../types/index.esm.d.ts'],
entryPoints: ['../../types/index.d.ts'],
hideInPageTOC: true,
tsconfig: 'tsconfig.json',
sidebar: {
Expand Down Expand Up @@ -94,12 +94,10 @@ module.exports = {
config.merge({
resolve: {
alias: {
'chart.js': path.resolve(__dirname, '../../dist/chart.mjs'),
'chart.js': path.resolve(__dirname, '../../dist/chart.js'),
}
}
})

config.module.rule('js').test(/\.m?jsx?$/)
},
markdown: {
extendMarkdown: md => {
Expand Down
21 changes: 11 additions & 10 deletions docs/getting-started/integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,12 @@ Chart.js can be integrated with plain JavaScript or with different module loader
## Script Tag

```html
<script src="path/to/chartjs/dist/chart.js"></script>
<script src="path/to/chartjs/dist/chart.umd.js"></script>
<script>
const myChart = new Chart(ctx, {...});
</script>
```

## Common JS

```javascript
const Chart = require('chart.js');
const myChart = new Chart(ctx, {...});
```

## Bundlers (Webpack, Rollup, etc.)

Chart.js 3 is tree-shakeable, so it is necessary to import and register the controllers, elements, scales and plugins you are going to use.
Expand Down Expand Up @@ -96,6 +89,14 @@ And finally there is a separate path to do just the above for you, in one line:
import Chart from 'chart.js/auto';
```

## CommonJS

Because Chart.js is an ESM library, in CommonJS modules you should use a dynamic `import`:

```javascript
const { Chart } = await import('chart.js');
```

### Helper functions

If you want to use the helper functions, you will need to import these separately from the helpers package and use them as stand-alone functions.
Expand Down Expand Up @@ -123,10 +124,10 @@ const chart = new Chart(ctx, {

## Require JS

**Important:** RequireJS [can **not** load CommonJS module as is](https://requirejs.org/docs/commonjs.html#intro), so be sure to require one of the UMD builds instead (i.e. `dist/chart.js`, `dist/chart.min.js`, etc.).
**Important:** RequireJS can load only [AMD modules](https://requirejs.org/docs/whyamd.html), so be sure to require one of the UMD builds instead (i.e. `dist/chart.umd.js`).

```javascript
require(['path/to/chartjs/dist/chart.min.js'], function(Chart){
require(['path/to/chartjs/dist/chart.umd.js'], function(Chart){
const myChart = new Chart(ctx, {...});
});
```
Expand Down
2 changes: 1 addition & 1 deletion docs/scripts/components.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Add Chart components needed in samples here.
// Usable through `components[name]`.
export {Tooltip} from '../../dist/chart.mjs';
export {Tooltip} from '../../dist/chart.js';
2 changes: 1 addition & 1 deletion docs/scripts/helpers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Add helpers needed in samples here.
// Usable through `helpers[name]`.
export {color, getHoverColor, easingEffects} from '../../dist/helpers.mjs';
export {color, getHoverColor, easingEffects} from '../../dist/helpers.js';
2 changes: 1 addition & 1 deletion docs/scripts/register.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Chart, registerables} from '../../dist/chart.mjs';
import {Chart, registerables} from '../../dist/chart.js';
import Log2Axis from './log2';
import './derived-bubble';
import analyzer from './analyzer';
Expand Down
2 changes: 1 addition & 1 deletion docs/scripts/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import colorLib from '@kurkle/color';
import {DateTime} from 'luxon';
import 'chartjs-adapter-luxon';
import {valueOrDefault} from '../../dist/helpers.mjs';
import {valueOrDefault} from '../../dist/helpers.js';

// Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
var _seed = Date.now();
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion helpers/helpers.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('..').helpers;
export * from '../dist/helpers.js';
1 change: 0 additions & 1 deletion helpers/helpers.mjs

This file was deleted.

9 changes: 5 additions & 4 deletions helpers/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "chart.js-helpers",
"private": true,
"description": "helper package",
"description": "Helpers package. Exists to support bundlers without exports support such as webpack 4.",
"type": "module",
"main": "helpers.js",
"module": "helpers.mjs",
"types": "helpers.mts"
}
"exports": "./helpers.js",
"types": "helpers.d.ts"
}
14 changes: 9 additions & 5 deletions karma.conf.js → karma.conf.cjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const jasmineSeedReporter = require('./test/seed-reporter');
const jasmineSeedReporter = require('./test/seed-reporter.cjs');
const commonjs = require('@rollup/plugin-commonjs');
const istanbul = require('rollup-plugin-istanbul');
const json = require('@rollup/plugin-json');
const resolve = require('@rollup/plugin-node-resolve').default;
const builds = require('./rollup.config');
const builds = require('./rollup.config.cjs');
const yargs = require('yargs');

module.exports = function(karma) {
Expand All @@ -18,9 +18,13 @@ module.exports = function(karma) {
// we will prefer the unminified build which is easier to browse and works
// better with source mapping. In other cases, pick the minified build to
// make sure that the minification process (terser) doesn't break anything.
const regex = karma.autoWatch ? /chart\.js$/ : /chart\.min\.js$/;
const regex = /chart\.umd\.js$/;
const build = builds.filter(v => v.output.file && v.output.file.match(regex))[0];

if (karma.autoWatch) {
build.plugins.pop();
}

if (args.coverage) {
build.plugins = [
json(),
Expand Down Expand Up @@ -87,14 +91,14 @@ module.exports = function(karma) {
'node_modules/moment-timezone/builds/moment-timezone-with-data.min.js',
{pattern: 'test/index.js', watched: false},
{pattern: 'test/BasicChartWebWorker.js', included: false},
{pattern: 'src/index.js', watched: false},
{pattern: 'src/index.umd.js', watched: false},
'node_modules/chartjs-adapter-moment/dist/chartjs-adapter-moment.js',
{pattern: specPattern}
],

preprocessors: {
'test/index.js': ['rollup'],
'src/index.js': ['sources']
'src/index.umd.js': ['sources']
},

rollupPreprocessor: {
Expand Down
16 changes: 0 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 14 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
"description": "Simple HTML5 charts using the canvas element.",
"version": "3.9.0",
"license": "MIT",
"jsdelivr": "dist/chart.min.js",
"unpkg": "dist/chart.min.js",
"type": "module",
"jsdelivr": "dist/chart.umd.js",
"unpkg": "dist/chart.umd.js",
"main": "dist/chart.js",
"module": "dist/chart.mjs",
"types": "types/index.esm.d.ts",
"exports": {
".": "./dist/chart.js",
"./auto": "./auto/auto.js",
"./helpers": "./helpers/helpers.js"
},
"types": "types/index.d.ts",
"keywords": [
"canvas",
"charts",
Expand All @@ -33,20 +38,20 @@
"scripts": {
"autobuild": "rollup -c -w",
"build": "rollup -c",
"dev": "karma start --auto-watch --no-single-run --browsers chrome --grep",
"dev:ff": "karma start --auto-watch --no-single-run --browsers firefox --grep",
"dev": "karma start ./karma.conf.cjs --auto-watch --no-single-run --browsers chrome --grep",
"dev:ff": "karma start ./karma.conf.cjs --auto-watch --no-single-run --browsers firefox --grep",
"docs": "npm run build && vuepress build docs --no-cache",
"docs:dev": "npm run build && vuepress dev docs --no-cache",
"lint-js": "eslint \"src/**/*.js\" \"test/**/*.js\" \"docs/**/*.js\"",
"lint-md": "eslint \"**/*.md\"",
"lint-tsc": "tsc",
"lint-types": "eslint \"types/**/*.ts\" && node -r esm types/tests/autogen.js && tsc -p types/tests/",
"lint-types": "eslint \"types/**/*.ts\" && npm run build && node types/tests/autogen.js && tsc -p types/tests/",
"lint": "concurrently \"npm:lint-*\"",
"test-size": "size-limit",
"test": "npm run lint && npm run test-ci",
"test-ci": "concurrently \"npm:test-ci-*\"",
"test-ci-karma": "cross-env NODE_ENV=test karma start --auto-watch --single-run --coverage --grep",
"test-ci-integration": "mocha --full-trace test/integration/*-test.js"
"test-ci-karma": "cross-env NODE_ENV=test karma start ./karma.conf.cjs --auto-watch --single-run --coverage --grep",
"test-ci-integration": "mocha --full-trace test/integration/*-test.cjs"
},
"devDependencies": {
"@kurkle/color": "^0.2.1",
Expand Down Expand Up @@ -94,7 +99,6 @@
"moment-timezone": "^0.5.34",
"pixelmatch": "^5.2.1",
"rollup": "^2.44.0",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-istanbul": "^3.0.0",
"rollup-plugin-terser": "^7.0.2",
Expand Down
Loading

0 comments on commit ce375a6

Please sign in to comment.