Skip to content

Commit

Permalink
[charts] Use vendor to have CJS working out of the box (#13608)
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandre Fauquette <[email protected]>
Co-authored-by: Lukas Tyla <[email protected]>
  • Loading branch information
alexfauquette and LukasTy authored Jul 29, 2024
1 parent af9b360 commit 743779f
Show file tree
Hide file tree
Showing 344 changed files with 21,199 additions and 160 deletions.
15 changes: 12 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ jobs:
steps:
- checkout
- install_js
- run:
name: Tests charts
command: pnpm test:charts:unit # Run special test for charts due to ESM compatibility issue
- run:
name: Tests fake browser
command: pnpm test:coverage
Expand Down Expand Up @@ -212,6 +209,18 @@ jobs:
command: |
pnpm docs:link-check
git add -A && git diff --exit-code --staged
- run:
name: '`pnpm @mui/x-charts-vendor build` was run?'
command: |
# #default-branch-switch
if [[ $(git diff --name-status master | grep pnpm-lock) == "" ]];
then
echo "No changes to dependencies detected. Skipping..."
else
pnpm --filter @mui/x-charts-vendor build
git add -A && git diff --exit-code --staged
fi
test_browser:
<<: *default-job
docker:
Expand Down
2 changes: 2 additions & 0 deletions .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"packages/x-date-pickers",
"packages/x-date-pickers-pro",
"packages/x-charts",
"packages/x-charts-vendor",
"packages/x-tree-view",
"packages/x-internals"
],
Expand All @@ -23,6 +24,7 @@
"@mui/x-date-pickers": "packages/x-date-pickers/build",
"@mui/x-date-pickers-pro": "packages/x-date-pickers-pro/build",
"@mui/x-charts": "packages/x-charts/build",
"@mui/x-charts-vendor": "packages/x-charts-vendor",
"@mui/x-charts-pro": "packages/x-charts-pro/build",
"@mui/x-tree-view": "packages/x-tree-view/build",
"@mui/x-tree-view-pro": "packages/x-tree-view-pro/build",
Expand Down
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ netlify/functions
/docs/pages/playground/
/lerna.json
/packages/x-codemod/src/**/*.spec.js
/packages/x-charts-vendor
build
/coverage
CHANGELOG.md
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/vale-action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: Vale action

on: [pull_request]
on:
pull_request:
paths:
- 'docs/data/**.md'

permissions: {}

Expand Down
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const defaultAlias = {
'@mui/x-date-pickers-pro': resolveAliasPath('./packages/x-date-pickers-pro/src'),
'@mui/x-charts': resolveAliasPath('./packages/x-charts/src'),
'@mui/x-charts-pro': resolveAliasPath('./packages/x-charts-pro/src'),
'@mui/x-charts-vendor': resolveAliasPath('./packages/x-charts-vendor'),
'@mui/x-tree-view': resolveAliasPath('./packages/x-tree-view/src'),
'@mui/x-tree-view-pro': resolveAliasPath('./packages/x-tree-view-pro/src'),
'@mui/x-internals': resolveAliasPath('./packages/x-internals/src'),
Expand Down
1 change: 1 addition & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
coverage:
ignore:
- 'packages/x-charts-vendor'
- '**/*.test.tsx'
status:
project:
Expand Down
11 changes: 3 additions & 8 deletions docs/data/charts/getting-started/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,11 @@ yarn add @mui/styled-engine-sc styled-components

Take a look at the [Styled engine guide](/material-ui/integrations/styled-components/) for more information about how to configure `styled-components` as the style engine.

### Usage with Next.js
### Usage with D3

If you're using MUI X Charts with Next.js, you might face the following error:
To help folks using CommonJS, the `@mui/x-charts` package uses a vendored package named `@mui/x-charts-vendor` to access D3 libraries.

```bash
[ESM][charts] Doesn't build due to require() of ES Module (ERR_REQUIRE_ESM)
```
To solve it, transpile the package by adding `transpilePackages: ['@mui/x-charts']` to your `next.config.js` file.
Visit [this GitHub issue and comment](https://github.com/mui/mui-x/issues/9826#issuecomment-1658333978) for details.
If you need some D3 functions, you can import them with `@mui/x-charts-vendor/d3-color`.

## Displaying Charts

Expand Down
2 changes: 2 additions & 0 deletions docs/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const WORKSPACE_ALIASES = {
'@mui/x-date-pickers': path.resolve(WORKSPACE_ROOT, './packages/x-date-pickers/src'),
'@mui/x-date-pickers-pro': path.resolve(WORKSPACE_ROOT, './packages/x-date-pickers-pro/src'),
'@mui/x-charts': path.resolve(WORKSPACE_ROOT, './packages/x-charts/src'),
'@mui/x-charts-pro': path.resolve(WORKSPACE_ROOT, './packages/x-charts-pro/src'),
'@mui/x-charts-vendor': path.resolve(WORKSPACE_ROOT, './packages/x-charts-vendor'),
'@mui/x-tree-view': path.resolve(WORKSPACE_ROOT, './packages/x-tree-view/src'),
'@mui/x-tree-view-pro': path.resolve(WORKSPACE_ROOT, './packages/x-tree-view-pro/src'),
'@mui/x-license': path.resolve(WORKSPACE_ROOT, './packages/x-license/src'),
Expand Down
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@mui/system": "^5.16.5",
"@mui/utils": "^5.16.5",
"@mui/x-charts": "workspace:*",
"@mui/x-charts-vendor": "workspace:*",
"@mui/x-data-grid": "workspace:*",
"@mui/x-data-grid-generator": "workspace:*",
"@mui/x-data-grid-premium": "workspace:*",
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"test:karma": "cross-env NODE_ENV=test TZ=UTC karma start test/karma.conf.js",
"test:karma:parallel": "cross-env NODE_ENV=test TZ=UTC PARALLEL=true karma start test/karma.conf.js",
"test:unit": "cross-env NODE_ENV=test TZ=UTC mocha -n expose_gc",
"test:charts:unit": "cross-env NODE_ENV=test TZ=UTC mocha -n expose_gc --config packages/x-charts/.mocharc.js",
"test:e2e": "cross-env NODE_ENV=production pnpm test:e2e:build && concurrently --success first --kill-others \"pnpm test:e2e:run\" \"pnpm test:e2e:server\"",
"test:e2e:build": "webpack --config test/e2e/webpack.config.js",
"test:e2e:dev": "concurrently \"pnpm test:e2e:build --watch\" \"pnpm test:e2e:server\"",
Expand Down
11 changes: 1 addition & 10 deletions packages/x-charts-pro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,10 @@
"@mui/utils": "^5.16.5",
"@mui/x-charts": "workspace:*",
"@mui/x-license": "workspace:*",
"@mui/x-charts-vendor": "workspace:*",
"@react-spring/rafz": "^9.7.3",
"@react-spring/web": "^9.7.3",
"clsx": "^2.1.1",
"d3-color": "^3.1.0",
"d3-delaunay": "^6.0.4",
"d3-interpolate": "^3.0.1",
"d3-scale": "^4.0.2",
"d3-shape": "^3.2.0",
"prop-types": "^15.8.1"
},
"peerDependencies": {
Expand All @@ -74,11 +70,6 @@
"devDependencies": {
"@react-spring/core": "^9.7.3",
"@react-spring/shared": "^9.7.3",
"@types/d3-color": "^3.1.3",
"@types/d3-delaunay": "^6.0.4",
"@types/d3-interpolate": "^3.0.4",
"@types/d3-scale": "^4.0.8",
"@types/d3-shape": "^3.1.6",
"@types/prop-types": "^15.7.12",
"csstype": "^3.1.3",
"rimraf": "^5.0.9"
Expand Down
2 changes: 1 addition & 1 deletion packages/x-charts-pro/src/Heatmap/Heatmap.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { interpolateRgbBasis } from 'd3-interpolate';
import { interpolateRgbBasis } from '@mui/x-charts-vendor/d3-interpolate';
import useId from '@mui/utils/useId';
import { ChartsAxis, ChartsAxisProps } from '@mui/x-charts/ChartsAxis';
import {
Expand Down
62 changes: 62 additions & 0 deletions packages/x-charts-vendor/.babelrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Transform d3 ESM libraries to vendored CommonJS libraries
*
* This produces `lib-vendor/d3-<package name>/src` files that have
* internally consistent references to other d3 packages. It is only meant
* to be used for the CommonJS import path.
*/
const path = require('path');

module.exports = {
only: [/node_modules\/(d3-.*|internmap|delaunator|robust-predicates)\/.*\.js/],
plugins: [
[
'@babel/transform-modules-commonjs',
{
strict: false,
allowTopLevelThis: true,
},
],
[
'module-resolver',
{
// Convert all imports for _other_ d3 dependencies to the relative
// path in our vendor package.
resolvePath(sourcePath, currentFile) {
const d3pattern =
/^(?<pkg>(d3-[^\/]+|internmap|delaunator|robust-predicates))(?<path>.*)/;
const match = d3pattern.exec(sourcePath);
if (match) {
// We're assuming a common shape of d3 packages:
// - Only top level imports "d3-<whatever>"
// - With no path components (like "d3-<whatever>/path/to.js")
if (match.groups.path) {
throw new Error(`Unable to process ${sourcePath} import in ${currentFile}`);
}

// Get Vendor package path.
const vendorPkg = ['delaunator', 'robust-predicates'].includes(match.groups.pkg)
? path.resolve(__dirname, `./lib-vendor/${match.groups.pkg}/index.js`)
: path.resolve(__dirname, `./lib-vendor/${match.groups.pkg}/src/index.js`);

// Derive relative path to vendor lib to have a file like move from:
// - 'node_modules/d3-interpolate/src/rgb.js'
// - 'lib-vendor/d3-interpolate/src/rgb.js'
// and have an import transform like:
// - `d3-color`
// - `../../d3-color`
const currentFileVendor = currentFile.replace(/^node_modules/, 'lib-vendor');
const relPathToPkg = path
.relative(path.dirname(currentFileVendor), vendorPkg)
.replace(/\\/g, '/');

return relPathToPkg;
}

return sourcePath;
},
},
],
'@babel/plugin-transform-runtime',
],
};
14 changes: 14 additions & 0 deletions packages/x-charts-vendor/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
!/dist
!/es
!/lib
!/lib-vendor
!/src
!/d3-*
!/internmap.js
!LICENSE.txt
!CHANGELOG.md
!README.md
!package.json
*.map
**/*.test.*
76 changes: 76 additions & 0 deletions packages/x-charts-vendor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Charts Vendor

Vendored dependencies for @mui/x-charts.

An adaptation of the victory-vendor

## Background

D3 has released most of its libraries as ESM-only. This means that consumers in Node.js applications can no longer just `require()` anything with a d3 transitive dependency, including much of @mui/x-charts.

To help provide an easy path to folks still using CommonJS in their Node.js applications that consume @mui/x-charts, we now provide this package to vendor in various d3-related packages.

## Main difference with victory-vendor

Victory is using the `d3-voronoid` which is an archived project.
Our chart library relies on the `d3-delaunay` which is also ESM only and reuse `robust-predicates` which is also ESM only

## Packages

We presently provide the following top-level libraries:

- d3-color
- d3-delaunay
- d3-interpolate
- d3-scale
- d3-shape
- d3-time
- delaunator
- robust-predicate

This is the total list of top and transitive libraries we vendor:

- d3-array
- d3-color
- d3-delaunay
- d3-format
- d3-interpolate
- d3-path
- d3-scale
- d3-shape
- d3-time
- d3-time-format
- delaunator
- internmap
- robust-predicates

## How it works

We provide two alternate paths and behaviors -- for ESM and CommonJS

### ESM

If you do a Node.js import like:

```js
import { interpolate } from '@mui/x-charts-vendor/d3-interpolate';
```

under the hood it's going to just re-export and pass you through to `node_modules/d3-interpolate`, the **real** ESM library from D3.

### CommonJS

If you do a Node.js import like:

```js
const { interpolate } = require('@mui/x-charts-vendor/d3-interpolate');
```

under the hood, it will go to an alternate path that contains the transpiled version of the underlying d3 library found at `x-charts-vendor/lib-vendor/d3-interpolate/**/*.js`.
This further has internally consistent import references to other `x-charts-vendor/lib-vendor/<pkg-name>` paths.

Note that for some tooling (like Jest) that doesn't play well with `package.json:exports` routing to this CommonJS path, we **also** output a root file in the form of `x-charts-vendor/d3-interpolate.js`.

## Licenses

This project is released under the MIT license, but the vendored in libraries include other licenses (e.g. ISC) that we enumerate in our `package.json:license` field.
5 changes: 5 additions & 0 deletions packages/x-charts-vendor/d3-color.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

// `x-charts-vendor/d3-color` (TypeScript)
//
// Export the type definitions for this package:
export * from "d3-color";
7 changes: 7 additions & 0 deletions packages/x-charts-vendor/d3-color.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

// `x-charts-vendor/d3-color` (CommonJS)
// See upstream license: https://github.com/d3/d3-color/blob/main/LICENSE
//
// This file only exists for tooling that doesn't work yet with package.json:exports
// by proxying through the CommonJS version.
module.exports = require("./lib/d3-color");
5 changes: 5 additions & 0 deletions packages/x-charts-vendor/d3-delaunay.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

// `x-charts-vendor/d3-delaunay` (TypeScript)
//
// Export the type definitions for this package:
export * from "d3-delaunay";
7 changes: 7 additions & 0 deletions packages/x-charts-vendor/d3-delaunay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

// `x-charts-vendor/d3-delaunay` (CommonJS)
// See upstream license: https://github.com/d3/d3-delaunay/blob/main/LICENSE
//
// This file only exists for tooling that doesn't work yet with package.json:exports
// by proxying through the CommonJS version.
module.exports = require("./lib/d3-delaunay");
5 changes: 5 additions & 0 deletions packages/x-charts-vendor/d3-interpolate.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

// `x-charts-vendor/d3-interpolate` (TypeScript)
//
// Export the type definitions for this package:
export * from "d3-interpolate";
7 changes: 7 additions & 0 deletions packages/x-charts-vendor/d3-interpolate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

// `x-charts-vendor/d3-interpolate` (CommonJS)
// See upstream license: https://github.com/d3/d3-interpolate/blob/main/LICENSE
//
// This file only exists for tooling that doesn't work yet with package.json:exports
// by proxying through the CommonJS version.
module.exports = require("./lib/d3-interpolate");
5 changes: 5 additions & 0 deletions packages/x-charts-vendor/d3-scale.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

// `x-charts-vendor/d3-scale` (TypeScript)
//
// Export the type definitions for this package:
export * from "d3-scale";
7 changes: 7 additions & 0 deletions packages/x-charts-vendor/d3-scale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

// `x-charts-vendor/d3-scale` (CommonJS)
// See upstream license: https://github.com/d3/d3-scale/blob/main/LICENSE
//
// This file only exists for tooling that doesn't work yet with package.json:exports
// by proxying through the CommonJS version.
module.exports = require("./lib/d3-scale");
5 changes: 5 additions & 0 deletions packages/x-charts-vendor/d3-shape.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

// `x-charts-vendor/d3-shape` (TypeScript)
//
// Export the type definitions for this package:
export * from "d3-shape";
7 changes: 7 additions & 0 deletions packages/x-charts-vendor/d3-shape.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

// `x-charts-vendor/d3-shape` (CommonJS)
// See upstream license: https://github.com/d3/d3-shape/blob/main/LICENSE
//
// This file only exists for tooling that doesn't work yet with package.json:exports
// by proxying through the CommonJS version.
module.exports = require("./lib/d3-shape");
5 changes: 5 additions & 0 deletions packages/x-charts-vendor/d3-time.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

// `x-charts-vendor/d3-time` (TypeScript)
//
// Export the type definitions for this package:
export * from "d3-time";
7 changes: 7 additions & 0 deletions packages/x-charts-vendor/d3-time.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

// `x-charts-vendor/d3-time` (CommonJS)
// See upstream license: https://github.com/d3/d3-time/blob/main/LICENSE
//
// This file only exists for tooling that doesn't work yet with package.json:exports
// by proxying through the CommonJS version.
module.exports = require("./lib/d3-time");
Loading

0 comments on commit 743779f

Please sign in to comment.