Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempted import error: 'RTCSessionDescription' is not exported #553

Open
thachp opened this issue Jun 2, 2024 · 7 comments
Open

Attempted import error: 'RTCSessionDescription' is not exported #553

thachp opened this issue Jun 2, 2024 · 7 comments
Labels
kind/discussion Topical discussion; usually not changes to codebase kind/support This is a question or a request for support need/analysis Needs further analysis before proceeding

Comments

@thachp
Copy link

thachp commented Jun 2, 2024

I have no luck writing a ReactJS Hook for Helia. I keep getting the following errors... Any thoughts?

Repro(s)

  1. Start a new NextJS project
  2. Add Helia
  3. copy & paste hooks below.
  4. Use it in any react component

// version
"helia": "4.2.3",
"next": "14.2.3",

Error

 ⨯ ../../node_modules/.pnpm/@[email protected][email protected]/node_modules/@libp2p/webrtc/dist/src/private-to-private/initiate-connection.js
Attempted import error: 'RTCSessionDescription' is not exported from '../webrtc/index.js' (imported as 'RTCSessionDescription').

Sample Codes

import { json } from "@helia/json";
import { Helia, createHelia } from "helia";
import { useCallback, useEffect, useState } from "react";

export type HeliaJsonResult = {
  helia: Helia | null;
  nodeId: string | null;
  nodeIsOnline: boolean;
  addJson: (jsonData: any) => Promise<string>;
  getJson: (cid: string) => Promise<any>;
  error: Error | null;
  loading: boolean;
};

export const useHeliaJson = (): HeliaJsonResult => {
  const [helia, setHelia] = useState<Helia | null>(null);
  const [nodeId, setNodeId] = useState<string | null>(null);
  const [nodeIsOnline, setNodeIsOnline] = useState<boolean>(false);
  const [error, setError] = useState<Error | null>(null);
  const [loading, setLoading] = useState<boolean>(true);

  useEffect(() => {
    const init = async () => {
      try {
        const heliaInstance = await createHelia();
        setHelia(heliaInstance);

        console.log("Helia instance: ", heliaInstance);

        const nodeId = heliaInstance.libp2p.peerId.toString();
        const nodeIsOnline = heliaInstance.libp2p.status === "started";
        setNodeId(nodeId);
        setNodeIsOnline(nodeIsOnline);

        setLoading(false);
      } catch (err) {
        setError(err as Error);
        setLoading(false);
      }
    };

    init();
  }, []);

  const addJson = useCallback(
    async (jsonData: any): Promise<string> => {
      if (!helia) {
        throw new Error("Helia instance is not initialized");
      }
      try {
        const cid = await json(helia).add(jsonData);
        return cid.toString();
      } catch (err) {
        setError(err as Error);
        throw err;
      }
    },
    [helia]
  );

  const getJson = useCallback(
    async (cid: string): Promise<any> => {
      if (!helia) {
        throw new Error("Helia instance is not initialized");
      }
      try {
        const data = await json(helia).get<any>(cid as any);
        return data;
      } catch (err) {
        setError(err as Error);
        throw err;
      }
    },
    [helia]
  );

  return {
    helia,
    nodeId,
    nodeIsOnline,
    addJson,
    getJson,
    error,
    loading,
  };
};

export default useHeliaJson;

``

@adapole
Copy link

adapole commented Jun 6, 2024

I get the same error when using app-router, while I'm using 'use client'; and a ClientContext. But the error doesn't occur for page-router.

@lixb-v
Copy link

lixb-v commented Jun 10, 2024

I had the same error

@adapole
Copy link

adapole commented Jun 10, 2024

I checked what the cause was, and found the following.

Tldr; it's due to @libp2p/webrtc having ./dist/src/webrtc/index.js optimised to ./dist/src/webrtc/index.browser.js for browser environments. And on app-router it tries to use index.js on the browser environment instead of index.browser.js.

@libp2p "browser" field in a package.json file

Difference between index.js and index.browser.js.

index.js

export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from 'node-datachannel/polyfill';
//# sourceMappingURL=index.js.map

The index.browser.js file is a smaller version of index.js that only includes the functionality needed for the browser (by using Native WebRTC API of the browser from the globalThis object), reducing the overall bundle size.

index.browser.js

export const RTCPeerConnection = globalThis.RTCPeerConnection;
export const RTCSessionDescription = globalThis.RTCSessionDescription;
export const RTCIceCandidate = globalThis.RTCIceCandidate;
//# sourceMappingURL=index.browser.js.map

Lastly, Nextjs 14.2 polyfills states that "to reduce bundle size, Next.js will only load these polyfills for browsers that require them", so if index.js is used the node-datachannel/polyfill will not be imported, which is the cause of the bug here.

Possible fixes

  1. When using app-router, Force Nextjs to load node-datachannel/polyfill in next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
	reactStrictMode: true,
	webpack: (config) => {
		config.externals.push('node-datachannel/polyfill');
		return config;
	},
};

export default nextConfig;
  1. Create a way to enforce the use of index.browser.js on @libp2p/webrtc

@thachp
Copy link
Author

thachp commented Jun 19, 2024

@adapole thx for looking into this. you are a life saver!

@SgtPooki
Copy link
Member

It seems a related discussion has had no feedback from the next.js team. vercel/next.js#61921

I put out an update for our nextjs-example: ipfs-examples/helia-examples#351

@SgtPooki SgtPooki added kind/discussion Topical discussion; usually not changes to codebase kind/support This is a question or a request for support need/analysis Needs further analysis before proceeding labels Oct 24, 2024
@SgtPooki
Copy link
Member

FYI: when I remove the config.externals.push('node-datachannel/polyfill') from ipfs-examples/helia-examples#351, I am not getting the error.

Do you all have some special config you're using? This may be solved with helia@5 and [email protected]

@adapole
Copy link

adapole commented Oct 29, 2024

This may be solved with helia@5 and [email protected]

[email protected] has fixed the error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/discussion Topical discussion; usually not changes to codebase kind/support This is a question or a request for support need/analysis Needs further analysis before proceeding
Projects
None yet
Development

No branches or pull requests

4 participants