lifinance / widget

LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.
https://li.fi/widget
Apache License 2.0
107 stars 72 forks source link

Can not compile in Next.js #264

Open caotrongtin99 opened 3 weeks ago

caotrongtin99 commented 3 weeks ago

Versions:

Reproduce:

  1. Clone the source code here
  2. Install dependencies: yarn
  3. Run the app: yarn dev
  4. 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: '/' }
paintoshi commented 3 weeks ago

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"]
}
caotrongtin99 commented 3 weeks ago

Hi @chybisov, could u help to take a look? Thanks

VladimirMikulic commented 3 weeks ago

This is what I get:

Screenshot_20240702_173858

DNR500 commented 3 weeks ago

@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

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" />;
}
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>
  );
}

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.

DNR500 commented 3 weeks ago

@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.

paintoshi commented 2 weeks ago

@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.

VladimirMikulic commented 3 days ago

For anyone else encountering issue like mine, make sure to delete node_modules folder and reinstall everything. That resolved it for me.