Can not compile in Next.js
Closed this issue · 8 comments
Versions:
- Nextjs: 13.5.6
- Reactjs: 18
- @lifi/widget: 3.0.0
Reproduce:
- Clone the source code here
- Install dependencies:
yarn
- Run the app:
yarn dev
- Check the terminal and look at the error message
⨯ TypeError [ERR_IMPORT_ASSERTION_TYPE_MISSING]: Module "file:///Users/quoxent/Documents/Coding/metamask-reproduce/node_modules/@lifi/widget/_esm/i18n/bn.json" needs an import attribute of type "json" at new NodeError (node:internal/errors:405:5) at validateAttributes (node:internal/modules/esm/assert:89:15) at defaultLoad (node:internal/modules/esm/load:103:3) at ModuleLoader.load (node:internal/modules/esm/loader:417:13) at ModuleLoader.moduleProvider (node:internal/modules/esm/loader:288:22) at new ModuleJob (node:internal/modules/esm/module_job:63:26) at #createModuleJob (node:internal/modules/esm/loader:312:17) at ModuleLoader.getJobFromResolveResult (node:internal/modules/esm/loader:265:34) at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:251:17) at async ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:21) { code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING', page: '/' }
I get the same error in my Next.js project when trying to migrate to widget 3.0.0. Additionally, if I use this in my next.config.js (as I had before) transpilePackages: ['@lifi/widget', '@lifi/wallet-management'],
I get this error instead:
./node_modules/@lifi/widget/node_modules/@mui/icons-material/node_modules/@babel/runtime/helpers/interopRequireDefault.js
Module parse failed: Cannot use 'import.meta' outside a module (39:16)
| // still a Refresh Boundary later.
| // @ts-ignore importMeta is replaced in the loader
> import.meta.webpackHot.accept();
| // This field is set when the previous version of this module was a
| // Refresh Boundary, letting us know we need to check for invalidation or
Import trace for requested module:
./node_modules/@lifi/widget/node_modules/@mui/icons-material/node_modules/@babel/runtime/helpers/interopRequireDefault.js
./node_modules/@lifi/widget/node_modules/@mui/icons-material/Block.js
./node_modules/@lifi/widget/_esm/components/NotFound.js
./node_modules/@lifi/widget/_esm/AppRoutes.js
./node_modules/@lifi/widget/_esm/AppDefault.js
./node_modules/@lifi/widget/_esm/App.js
./node_modules/@lifi/widget/_esm/index.js
./components/Widget.tsx
Using next 13.5.2, typescript 5.1.6
next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: false,
swcMinify: true,
transpilePackages: ['@lifi/widget', '@lifi/wallet-management'],
output: 'export',
};
module.exports = nextConfig;
tsconfig.json
{
"compilerOptions": {
"target": "es6",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
Hi @chybisov, could u help to take a look? Thanks
@caotrongtin99 Thanks for providing your example, that was really useful.
The pattern we present in our documentation for using the Widget in Next.js is something we have built for the App router. Working in the App router with Next.js 14 you shouldn't experience the same issues.
However, you should still be able to get Widget up and running in the Pages Router with the current version - at the moment we still need to use a different approach to importing and using the widget code.
It looks like you are using javascript rather than typescript? I think with some simple changes you could get your project up and running.
Try following these steps
- Delete the components/ClientOnly.tsx
- You can rename you components/Widgets.tsx to components/Widgets.jsx
- Change the code in your components/Widgets.jsx to the following
import { LiFiWidget } from '@lifi/widget';
export default function Widget() {
const config = {
appearance: 'light',
theme: {
container: {
boxShadow: '0px 8px 32px rgba(0, 0, 0, 0.08)',
borderRadius: '16px',
},
},
};
return <LiFiWidget config={config} integrator="nextjs-example" />;
}
- Change the code in your page/index.js to the following
import dynamic from 'next/dynamic';
const DynamicWidget = dynamic(() => import('@/components/Widget'), {
loading: () => <p>Loading...</p>,
ssr: false,
});
export default function Home() {
return (
<section>
<DynamicWidget />
</section>
);
}
- You should be able to run that code and see the Widget
- Note that currently with this implementation you won't yet be able to use the WidgetSkeleton yet.
JSON assertions
The problem you that you saw with json assertions is something we are currently looking at in more depth. We had originally included the assertions but they had caused problems for users of environments other than Next.js.
Reinstating the json assertations something we want to do but as you can understand we need to do it without breaking how the widget works in other environments as well. Hopefully coming soon.
WidgetSkeleton
This is something we originally created while working against Next14 and the App Router. There currently seems to be some import issues with using this under the Page Router. This is again something that we are aiming to improve so that the adaptive Skeleton can be used more extensively in SSR environments. Coming soon.
nextjs-page-router example
We have added a typescript page router example to present the above solution for now. You can find in our repo at example/nextjs-page-router. Hopefully we can provide a more unified way of working with Widget once we have addressed the above problems. Please bear with us.
@paintoshi are you able to provide an example? It might be that this is a separate issue to the one listed above. It might be worth creating a different issue if the above fix doesn't help you out.
@VladimirMikulic - the Widget does require some consideration around peer dependancies - its important that if you use react query in your own application that its on a similiar version to the one that Widget uses to ensure compatibility. Again its helps if you can provide an example and it might be a different issue to the one raised above.
@DNR500 Thanks for the hint about app router. I have a relative small project, so I migrated to app router instead and the new widget builds now. But I'm seeing other strange things with it, like no swaps on the Fantom network works, while it works on the old version. Will create a separate issue.
For anyone else encountering issue like mine, make sure to delete node_modules folder and reinstall everything. That resolved it for me.
We have since updated import asserts in Widget so that there should be less problems with them. The Examples have been updated accordingly