How to tune babel loader to properly import a module named macro.js when using CRA


In order to create a VTK class, macro.js module needs to be imported. When I import this module (import macro from '@kitware/vtk.js/macro') in my application I get an error: SyntaxError: Cannot use import statement outside a module. My application is based on react-scripts from create-react-app. If I copy an original file macro.js from @kitware/vtk.js to my local source folder I still get an error. Even if I remove all the contents of macro.js file I get an error: The macro imported from "../macro" must be wrapped in "createMacro" which you can get from "babel-plugin-macros". Please refer to the documentation to see how to do this properly: However, when I rename macro.js to macro2.js the error is gone.

Looks like CRA uses some special loader for macro.js files. Is there some way how can I disable this macro loader?

Best regards,

Hum, thanks for bringing that up to our attention. I’m wondering if you could exclude @kitware/vtk.js from that loader?

Hi, this appears to be a conflict with babel-plugin-macros. Specifically, babel-plugin-macros runs on any file that matches [./]macro(\.c?js)?$, which is why you get that error.

As for resolution, CRA is limiting when it comes to customization. The easiest approach on your side is to eject your config, and then add a babel.config.js as shown here: False positive in macrosRegex · Issue #131 · kentcdodds/babel-plugin-macros · GitHub. Unfortunately you cannot customize babel config in CRA without ejecting.

As far as I know, there is no other easy approach. Maybe you can switch to a CRA alternative like Neutrino, which will allow you to customize babel.config.js. Unfortunately babel-plugin-macros has not shown any interest in narrowing their regex matches (see this issue), and CRA has not exposed isMacrosName, so I think your only options are to eject or switch tooling.

Update: you should check out customize-cra to see if you can make modifications to the babel config to add a custom isMacrosName that looks like the following:

isMacrosName: (name) => /[./]macro(\.c?js)?$/.test(name) && name.indexOf("@kitware/vtk.js") === -1

Thank you @Forrest! I will look into it. Another way of customizing CRA without ejecting is to use craco.

1 Like

Update: there is now a new patch to vtk.js that should be able to side-step this issue: WIP Fix #1996 and add debounced function cancellation by floryst · Pull Request #1997 · Kitware/vtk-js · GitHub

Another update: the latest vtk.js now publishes an alternative name for macro.js: macros.js (note the extra “s”).

If you are using macro.js and run into this issue, please update your imports to using macros.js. If you are using macro.js just fine, carry on – macro.js is published to keep backwards-compatibility.