dapp-core icon indicating copy to clipboard operation
dapp-core copied to clipboard

Building error when using dapp-core in a nextjs app

Open joaquin-alfaro opened this issue 2 years ago • 9 comments

Thanks for the library of components, it is great and really helpful when making elrond dapps.

I have to make a SSR dapp and I am planning to use nextjs, but the building of the app fails when using any component of dapp-core

Expected behavior

The building of a nextjs app using components from dapp-core finish successfully and generates the folder .next with the required files to start the app.

Actual behavior

The building of the nextjs app fails with the following error:

> Build error occurred
/nextjs-with-elrond-dapp-core/node_modules/@elrondnetwork/dapp-core/UI/index.js:1
"use strict";import{a as n}from"../__chunks__/chunk-Z2GXZLB7.js";import{a as l}from"../__chunks__/chunk-2R3H532S.js";
             ^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Module._load (node:internal/modules/cjs/loader:827:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at 272 (/nextjs-with-elrond-dapp-core/.next/server/pages/elrond-page.js:22:28)
    at __webpack_require__ (/nextjs-with-elrond-dapp-core/.next/server/webpack-runtime.js:25:42) {
  type: 'SyntaxError'
}

Steps to reproduce the behavior

  1. Create nextjs app
npx create-next-app@latest --typescript
npm run build
  1. Add dapp-core dependencies
npm install @types/[email protected] @types/[email protected] --save-dev
npm install @elrondnetwork/dapp-core @elrondnetwork/erdjs @elrondnetwork/erdjs-network-providers
  1. Use a dapp-core component in a page
import type { NextPage } from 'next'
import * as DappUI from '@elrondnetwork/dapp-core/UI'
  
const Elrond: NextPage = () => {
    const { WebWalletLoginButton } = DappUI
    return (
        <div>
            <WebWalletLoginButton
              callbackRoute='/'
              loginButtonText={'Web wallet'}
            />
        </div>
    )
}

export default Elrond
  1. Build app
npm run build

I have created this repository nextjs-with-elrond-dapp-core so you can reproduce the issue easily

Thanks!

joaquin-alfaro avatar Aug 04 '22 09:08 joaquin-alfaro

The thing is that dapp-core now supports 2 build systems: ESM and CJS, for testing purposes, as JEST does not have support for ESM.

The problem you're having is that the application tries to read from the browser field in package.json, which loads the ESM module. However, you need to use the _commonjs folder, which has the CJS build. You need to set up the next config to read from the "main" field in package.json, which is the nodejs path

StanislavSava avatar Aug 05 '22 07:08 StanislavSava

I changed the configuration in next.config to use the "main" field

// next.config.js

  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack, nextRuntime }) => {
    config.resolve.mainFields = ['main', 'browser', 'module']
    config.resolve.fallback = {
      fs: false,
      net: require.resolve('net'),
      tls: require.resolve('tls'),
      'better-sqlite3': require.resolve('better-sqlite3'),
      bufferutil: require.resolve('bufferutil'),
      'utf-8-validate': require.resolve('utf-8-validate'),
    };

    return config;
  }

It was necessary to add dependencies with these packages: fs, net, tls, better-sqlite3, bufferutil and utf8-validate

But building is still failing // output of yarn build

./node_modules/better-sqlite3/lib/database.js
Critical dependency: the request of a dependency is an expression

Import trace for requested module:
./node_modules/better-sqlite3/lib/index.js
./node_modules/@walletconnect/keyvaluestorage/dist/cjs/node-js/index.js
./node_modules/@walletconnect/keyvaluestorage/dist/cjs/index.js
./node_modules/@walletconnect/sign-client/node_modules/@walletconnect/core/dist/index.cjs.js
./node_modules/@walletconnect/sign-client/dist/index.cjs.js
./node_modules/@elrondnetwork/erdjs-wallet-connect-provider/out/walletConnectProviderV2.js
./node_modules/@elrondnetwork/erdjs-wallet-connect-provider/out/index.js
./node_modules/@elrondnetwork/dapp-core/__chunks__/chunk-MFJNVGU4.js
./node_modules/@elrondnetwork/dapp-core/UI/index.js
./pages/elrond-page.tsx


> Build error occurred
/nextjs-with-elrond-dapp-core/node_modules/@elrondnetwork/dapp-core/UI/index.js:1
"use strict";import{a as n}from"../__chunks__/chunk-Z2GXZLB7.js";import{a as l}from"../__chunks__/chunk-2R3H532S.js";import"../__chunks__/chunk-73MMPUBZ.js";import{a as k}from"../__ch

I tried using the component in the folder "__common" but it failed because it is missing the d.ts file

import * as DappUI from '@elrondnetwork/dapp-core/__commonjs/UI'
Could not find a declaration file for module '@elrondnetwork/dapp-core/__commonjs/UI'. '/nextjs-with-elrond-dapp-core/node_modules/@elrondnetwork/dapp-core/__commonjs/UI/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/elrondnetwork__dapp-core` if it exists or add a new declaration (.d.ts) file containing `declare module '@elrondnetwork/dapp-core/__commonjs/UI';`

joaquin-alfaro avatar Aug 05 '22 12:08 joaquin-alfaro

I am running into this after migrating from 1.X to 2. Using NextJS as well and unable to import account

 1 of 1 unhandled error
Server Error
SyntaxError: Cannot use import statement outside a module

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
<unknown>
.../node_modules/ (elrondnetwork/dapp-core/hooks/index.js (1)

Here's a similar issue in another repo: https://github.com/asyncapi/asyncapi-react/issues/177

Tried this, and also tried to import dynamically with ssr: false to no avail.

tannerhallman avatar Sep 05 '22 17:09 tannerhallman

Did you manage to solve with dynamic imports @tannerhallman ?

I tried with no luck, I think that there's some issue with the bundling.

ilyich-erd avatar Oct 18 '22 23:10 ilyich-erd

Apparently neither tools like unpkg can understand that https://bundlejs.com/?q=%40elrondnetwork%2Fdapp-core. Maybe this can help https://nodejs.org/api/packages.html#determining-module-system @StanislavSava

ilyich-erd avatar Oct 18 '22 23:10 ilyich-erd

To use dapp-core just for the util functions is not possible also. getting this: Cannot find module '@elrondnetwork/dapp-core' or its corresponding type declarations even when its installed.

newtmex avatar Nov 01 '22 10:11 newtmex

I extended next.config.js with next-transpile-modules in order to make the modules understandable by Next.js.

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
};
const withTM = require("next-transpile-modules")(["@elrondnetwork/dapp-core"]);

module.exports = withTM(nextConfig);

I also had to import dynamically every component exported by dapp-core. I can see the app working now, except for an error that is thrown as soon as the page loads:

image

ilyich-erd avatar Nov 07 '22 13:11 ilyich-erd

Seems DappCore's build output is not compatible with Next.js.

I've reproduced the above error if both Vanilla JS and TypeScript Next.js projects.

In TypeScript, I tried this solution https://www.freecodecamp.org/news/cannot-use-import-statement-outside-a-module-react-typescript-error-solved/ where we get TS to use "module": "commonjs" but the error still remains.

I'm not sure how to resolve this in Next.js.

So for now, it seems DappCore cannot be used with Next.js... which is a bummer as Next.js is a default option for many devs wanting React with SSR.

Might have something to do with this (i.e. DappCore build output does not work in the node SSR part of Next.js) : https://stackoverflow.com/questions/62422174/cannot-use-import-statement-outside-a-module-with-next-js

Any suggestions from anyone on what the issue is and if it can be solved without a core change to DappCore?

newbreedofgeek avatar Nov 19 '22 05:11 newbreedofgeek

@newbreedofgeek dapp-core works fine until 2.1.0-rc7 with next.js I use this code in my configuration to transpile dapp-core and react-redux :

const withTM = require('next-transpile-modules')([
  '@elrondnetwork/dapp-core',
  'react-redux',
]);

On the latest versions, it's impossible to use the library. I have the following error : ReferenceError: document is not defined

@arhtudormorar I saw you tried to fix this issue here, unfortunately it didn't work for me. Do you have any other idea ?

Thank you

maximechbt avatar Nov 22 '22 21:11 maximechbt

I never came to a resolution no. Had to downgrade and continue using.

tannerhallman avatar Dec 08 '22 00:12 tannerhallman

Please check this dApp template https://github.com/multiversx/mx-template-nextjs-dapp

CiprianDraghici avatar Jan 20 '23 20:01 CiprianDraghici

Closed due to inactivity

CiprianDraghici avatar Feb 01 '23 10:02 CiprianDraghici

Still no news about the next js support ? ...

AugustinKimi avatar Feb 28 '23 20:02 AugustinKimi