React Storybook not running after installation of react-leaflet version 3

Viewed 731

After installation of react-leaflet version 3.2.1 storybook crashes on initial run

ERROR in ./node_modules/@react-leaflet/core/esm/path.js 10:41
Module parse failed: Unexpected token (10:41)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|   useEffect(function updatePathOptions() {
|     if (props.pathOptions !== optionsRef.current) {
>       const options = props.pathOptions ?? {};
|       element.instance.setStyle(options);
|       optionsRef.current = options;
 @ ./node_modules/@react-leaflet/core/esm/index.js 15:0-56 15:0-56 15:0-56
 @ ./node_modules/react-leaflet/esm/hooks.js
 @ ./node_modules/react-leaflet/esm/index.js
 @ ./src/navigation/config/index.tsx
 @ ./src/navigation/config/Routes.tsx
 @ ./src/redux/reducers/gl_navigation_reducer/reducer.ts
 @ ./src/redux/reducers/index.tsx
 @ ./src/redux/store.tsx
 @ ./src/providers/StoryBookProvider/index.tsx
 @ ./.storybook/preview.js
 @ ./.storybook/preview.js-generated-config-entry.js

ERROR in ./node_modules/react-leaflet/esm/Pane.js 25:37
Module parse failed: Unexpected token (25:37)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|   }
|
>   const parentPaneName = props.pane ?? context.pane;
|   const parentPane = parentPaneName ? context.map.getPane(parentPaneName) : undefined;
|   const element = context.map.createPane(name, parentPane);
 @ ./node_modules/react-leaflet/esm/index.js 13:0-30 13:0-30
 @ ./src/scenes/SingleClient/components/Map.tsx
 @ ./src/navigation/config/Routes.tsx
 @ ./src/redux/reducers/gl_navigation_reducer/reducer.ts
 @ ./src/redux/reducers/index.tsx
 @ ./src/redux/store.tsx
 @ ./src/providers/StoryBookProvider/index.tsx
 @ ./.storybook/preview.js
 @ ./.storybook/preview.js-generated-config-entry.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.j
ERROR in ./node_modules/@react-leaflet/core/esm/pane.js 2:27
Module parse failed: Unexpected token (2:27)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| export function withPane(props, context) {
>   const pane = props.pane ?? context.pane;
|   return pane ? { ...props,
|     pane

My storybook version:

  • "@storybook/addon-actions": "^6.3.12",
  • "@storybook/addon-essentials":"^6.3.12",
  • "@storybook/addon-links": "^6.3.12",
  • "@storybook/node-logger": "^6.3.12",
  • "@storybook/preset-create-react-app": "^3.2.0",
  • "@storybook/react": "^6.3.12",

Maybe I have to override the webpack configuration?

3 Answers

This issue, and others duplicating it, has been bouncing around for quite some time. The maintainer of react-leaflet wants to put the burden on consumers of the library to transpile react-leaflet to a version of ECMAScript suitable to their audience.

The target for react-leaflet does not transpile the nullish coalescing operator, so your build will have to explicitly transpile that from within node_modules.

Assuming you have @babel/plugin-proposal-nullish-coalescing-operator somewhere in your toolchain, you can try adding a module rule to your Storybook build similar to this:

{
  test: /\.jsx?$/,
  exclude: filename => {
    return /node_modules/.test(filename) && !/react-leaflet/.test(filename)
  },
  use: ['babel-loader']
}

Actually for me worked including it instead of excluding: I assume you are using webpackFinal config? If yes you need find which rule does the babel-loader for your js files. For me it is in config.module.rules[5].oneOf[3]. Just add this:

config.module.rules[5].oneOf[3].include.push(
  path.resolve(__dirname, '../node_modules/@react-leaflet/core'),
  path.resolve(__dirname, '../node_modules/react-leaflet')
);

But it can be in different place depending of your conf.

The give solutions didn't work for me, however a combination did.

This is for:

"leaflet": "^1.8.0",
"react-leaflet": "^4.0.1",
"@storybook/react": "^6.5.9",

within ./storybook open main.js and edit the webpackFinal section

module.exports = {
  webpackFinal: (config) => {
    const leafletRule = {
      test: /\.js$/,
      include: [ /node_modules\/@react-leaflet/, /node_modules\/react-leaflet/],
      use: [
        {
          loader: 'babel-loader',
          options:{"presets":[["@babel/preset-env",{"modules":"commonjs"}]]}
        }
      ]
    }

    config.module.rules.push(leafletRule);

    return config;
  },
};

When you check the rules, that storybook already uses, you can see, that they do the same for acorn-jsx - the rule I'm using is just a copy for react-leaflet.

Hope this helps someone out there

Related