'"Cannot use import statement outside a module" error when importing react-hook-mousetrap in Next.js
Trying out Next.js but I'm struggling with the following. Just tried to install react-hook-mousetrap and imported it like I normally would:
import useMousetrap from "react-hook-mousetrap";
This gives me the following error:
SyntaxError: Cannot use import statement outside a module
1 > module.exports = require("react-hook-mousetrap");
I am not sure what this means? I then thought it might be a problem with Nextjs's SSR, since my library enables hotkeys and will use some browser APIs. If you already know that I am on the wrong track here you can stop reading now.
What I did next however was this, I tried dynamic imports:
1. Dynamic import with next/dynamic
First thing I came across was next/dynamic, but this seems to be for JSX / React Components only (correct me if I'm wrong). Here I will be importing and using a React hook.
2. Dynamic import with await (...).default
So I tried dynamically importing it as a module, but I'm not sure how to do this exactly.
I need to use my hook at the top level of my component, can't make that Component async and now don't know what to do?
const MyComponent = () => {
// (1) TRIED THIS:
const useMousetrap = await import("react-hook-mousetrap").default;
//can't use the hook here since my Component is not async; Can't make the Component async, since this breaks stuff
// (2) TRIED THIS:
(async () => {
const useMousetrap = (await import("react-hook-mousetrap")).default;
// in this async function i can't use the hook, because it needs to be called at the top level.
})()
//....
}
Any advice here would be appreciated!
Solution 1:[1]
The error occurs because react-hook-mousetrap is exported as an ESM library. You can have Next.js transpile it using next-transpile-modules in your next.config.js.
const withTM = require('next-transpile-modules')(['react-hook-mousetrap']);
module.exports = withTM({ /* Your Next.js config */});
Solution 2:[2]
I don't know if my answer is actual, but i'm facing whith this problem today, and what that i done:
//test component for modal
const Button: React.FC<{close?: () => void}> = ({ close }) => (
<React.Fragment>
<button type="button" onClick={ close }>Close</button>
</React.Fragment>
);
// async call import react custom hook in next js whithout a dynamic
//import
let newHook;
(async () => {
const { hookFromNodeModules } =
await import('path/to/hook');
newHook = hookFromNodeModules;
})();
export default function Home() {
// check if hook is available
const openModal = newHook && newHook();
const { t } = useTranslation('common');
// useCallback for update call function when hook is available
const handleOpen = React.useCallback(() => {
openModal?.openModal(Button, {});
}, [openModal]);
return ( ...your code )
}
hope this help!)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Dmitriy Salnikov |
