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

docs additions for external add-ons usage #4233

Merged
merged 3 commits into from Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 68 additions & 0 deletions docs/source/addons/index.md
Expand Up @@ -455,6 +455,74 @@ volto-slate can declare in its `package.json`:
And of course, the dependency add-on can depend, on its turn, on other add-ons
which will be loaded as well. Circular dependencies should be avoided.

## Problems with untranspiled add-on dependencies

When using external add-ons in your project, sometimes you will run into add-ons
that are not securely transpiled or haven't been transpiled at all. In that case
you might see an error like the following:

```console
Module parse failed: Unexpected token (10:41) in @react-leaflet/core/esm/path.js
...
const options = props.pathOptions ?? {};
...
```

Babel automatically transpiles the code in your add-on, but `node_modules` are
excluded from this process, so we need to include the add-on path in the list of
modules to be transpiled. This can be accomplished by customizing the webpack
configuration in the `razzle.config.js` file in your add-on. For example,
suppose that we want to use react-leaflet, which has a known transpilation
issue:

```js
const path = require('path');
const makeLoaderFinder = require('razzle-dev-utils/makeLoaderFinder');

const babelLoaderFinder = makeLoaderFinder('babel-loader');

const jsConfig = require('./jsconfig').compilerOptions;

const pathsConfig = jsConfig.paths;
let voltoPath = './node_modules/@plone/volto';
Object.keys(pathsConfig).forEach((pkg) => {
if (pkg === '@plone/volto') {
voltoPath = `./${jsConfig.baseUrl}/${pathsConfig[pkg][0]}`;
}
});

const { modifyWebpackConfig, plugins } = require(`${voltoPath}/razzle.config`);

const customModifyWebpackConfig = ({ env, webpackConfig, webpackObject, options }) => {
const config = modifyWebpackConfig({
env,
webpackConfig,
webpackObject,
options,
});
const babelLoader = config.module.rules.find(babelLoaderFinder);
const { include } = babelLoader;
const corePath = path.join(
path.dirname(require.resolve('@react-leaflet/core')),
'..',
);
const esmPath = path.join(
path.dirname(require.resolve('react-leaflet')),
'..',
);

include.push(corePath);
include.push(esmPath);
return config;
};

module.exports = { modifyWebpackConfig: customModifyWebpackConfig, plugins };
```

First we need some setup to get the webpack configuration from Volto's configuration.
Once we have that, we need to resolve the path to the desired add-ons and push it
into the Babel loader include list. After this, the add-ons will load correctly.

## Testing add-ons

We should let jest know about our aliases and make them available to it to
Expand Down
10 changes: 8 additions & 2 deletions docs/source/recipes/lazyload.md
Expand Up @@ -91,9 +91,15 @@ You can call the hook like:
```jsx
import { useLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';

useLazyLibs(['toastify', 'reactDnd'])
const loaded = useLazyLibs(['toastify', 'reactDnd'])
// or:
useLazyLibs(['toastify', 'reactDnd'], {shouldRerender: false})
const loaded = useLazyLibs(['toastify', 'reactDnd'], {shouldRerender: false})

const reactDnd = loaded?.reactDnd;

if (reactDnd) {
// The library is now loaded and can be used.
}
```

Passing the `shouldRerender` as false as options will cause the component to
Expand Down
1 change: 1 addition & 0 deletions news/4233.documentation
@@ -0,0 +1 @@
Add some instructions for dealing with untranspiled add-ons and a lazy loading example for functional components. [cguardia]