Skip to content

Components:External Dependencies

Jeroen Reijs edited this page Feb 23, 2023 · 8 revisions

Using external dependencies in your custom components

Current default component set

Currently we use the following dependencies in our default component set:

  • "@date-io/date-fns": "^1.3.13",
  • "@material-ui/core": "^4.9.11",
  • "@material-ui/icons": "^4.11.2",
  • "@material-ui/lab": "^4.0.0-alpha.50",
  • "@material-ui/pickers": "^3.2.10",
  • "@material-ui/styles": "^4.9.10",
  • "date-fns": "^2.11.0",

And we render our runtime with:

  • "react": "^16.9.0",
  • "react-dom": "^16.9.0",

This means your components will always be rendered with this React version.

Other than that you can add other NPM packages to your component to render custom components of choice.

Adding dependencies to your component

The only thing you need to do is define which package you need in your component and destruct the React components from the property "dependencies" which is passed to the component.

We will pass the dependencies to the component before it is rendering.

In the meantime we will generate a javascript bundle with your extra dependencies next to the bundle for the default component set.

How?

Make sure you use the updated CLI version, 25.58.4 or newer. To use the treeshaking feature, use CLI version 25.62.1 or newer. This means only the javascript which is used will be included inside the bundle and will create smaller bundles to improve performance. Add the field dependencies to the component structure. This field consists of a list of dependencies, so you can add multiple. A dependency consists of three fields: label, package, imports.

The label is something that you can use in your component. By this label we will pass the module corresponding to the chosen package.

The package should be properly formatted. It should have the format:

registry:package-name@version

For now, we only allow npm as registry.

Imports is to define which components are used from the package. When specified as ["*"], it means the whole module is imported. When specified as separate components i.e. ["Component-A", "Component-B"], it means only those mentioned components will be available in the generated bundle. And that bundle will then be an optimised version. Good for performance win.

An example

dependencies: [
	{
		label: 'Recharts',
		package: 'npm:recharts@2.1.14',
		imports: ['*'],
	},
],

This means the bundle will serve version 2.1.4 of the NPM package recharts and will consist of all components exported in the recharts package.

An example with named imports (for treeshaking)

dependencies: [
	{
		label: 'Recharts',
		package: 'npm:recharts@2.1.14',
		imports: [
                  'BarChart',
                  'Bar',
                  'LineChart',
                  'Line',
                  'XAxis',
                  'YAxis',
                  'CartesianGrid',
                  'Tooltip',
                  'Legend',
                  'ResponsiveContainer',
                ],
	},
],

This means the bundle will serve version 2.1.4 of the NPM package recharts package. But it will only include the components mentioned in the imports field. This way you get the most out of the package and performance.

In the component itself you can use the packages like this:

	const { [yourlabel] } = dependencies;

Where we will take care of the dependencies. An example which will use the package mentioned above.

	const { Recharts } = dependencies;
        ....
        const { BarChart, Bar } = Recharts;

You can also decide to directly destructure the used components from the passed dependencies property like this:

const {
	Recharts: {
		BarChart,
		Bar,
		LineChart,
		Line,
		XAxis,
		YAxis,
		CartesianGrid,
		Tooltip,
		Legend,
		ResponsiveContainer,
	},
} = dependencies;

Handling a default export There are packages which don't have named exports, just a default or packages which export both default and named exports. We have seen examples of handling named exports above. When you want to use the default export from a package, you'll have to add default to your destructering. We export named as they are in the package, and we export the default export under the key default. For example the package google-map-react makes use of the default export.

So, in the dependency key we mention this package and version:

dependencies: [
    {
      label: 'GoogleMap',
      package: 'npm:google-map-react@2.2.0',
      imports: ['*'],
    },
  ],

Then in the component JSX, you can use this default export like this:

const { GoogleMap } = dependencies;
const { default: GoogleMapReact } = GoogleMap;

Or in 1 line:

const { GoogleMap: { default: GoogleMapReact } } = dependencies;

And the default is now available in the const GoogleMapReact. This is different from what you might have been used to.

Clone this wiki locally