emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.64k stars 3.29k forks source link

setwasmpath error for web-ifc-viewer in Gatsby.js #20119

Open tptspe opened 1 year ago

tptspe commented 1 year ago

I have one gatsby.js project to import \*.ifc file and display it in the web browser.

I installed web-ifc-viewer package and copy the 2 files web-ifc.wasm and web-ifc-mt.wasm from its node_modules folder into the component folder, and tried to render sample ifc file but it returns failure.

I also tried to copy 2 wasm files into the public folder, root folder and static folder separately, but got same error.

I created new folder WebIfcViewer inside src / components / and add 3 files

index.tsx
web-ifc-mt.wasm
web-ifc.wasma

Here is the code in the index.tsx.

import React, { createRef, useContext, useEffect, useState } from "react";
import {
  Box,
  Button,
  ResponsiveContext,
  Text,
  Spinner,
  CheckBox
} from "grommet";
import { Color } from 'three';
import { navigate } from "gatsby";
import { IfcViewerAPI } from 'web-ifc-viewer';

const WebIfcViwer = () => {
  const size = useContext(ResponsiveContext);
  const ifcContainer = createRef<HTMLDivElement>();
  const [isSnackbarOpen, setSnackbarOpen] = useState(false);
  const [viewer, setViewer] = useState<IfcViewerAPI>();
  const [isLoading, setLoading] = useState(false);
  const [ifcLoadingErrorMessage, setIfcLoadingErrorMessage] = useState<string>();

  const ifcOnLoad = async (e) => {
    const file = e && e.target && e.target.files && e.target.files[0];
    if (file && viewer) {
      setLoading(true);
      const ifcURL = URL.createObjectURL(file);
      viewer.IFC.loadIfcUrl(ifcURL);
      setLoading(false)
    }
  };

  useEffect(() => {
    const container = document.getElementById('viewer-container') as HTMLElement;
    const Ifcviewer = new IfcViewerAPI({ container });
    Ifcviewer.axes.setAxes();
    Ifcviewer.grid.setGrid();
    Ifcviewer.IFC.setWasmPath('./');
    setViewer(Ifcviewer);

    window.ondblclick = () => Ifcviewer.IFC.selector.pickIfcItem(true);
    window.onmousemove = () => Ifcviewer.IFC.selector.prePickIfcItem();
    Ifcviewer.clipper.active = true;

  }, []);

  return (
    <Box>
      <Box>
        <input
          type='file'
          id='file'
          accept='.ifc'
          onChange={ifcOnLoad}
        />
        {isLoading && <Spinner />}
        <div style={{ flex: '1 1 auto', minWidth: 0 }}>
          <div id='viewer-container' style={{ position: 'relative', height: '100%', width: '100%' }} />
        </div>
      </Box>
    </Box>
  );
};

export default WebIfcViwer;

Here is my package.json.


{
  "name": "bim-engineering",
  "description": "Production environment for aces applcation",
  "version": "0.1.2",
  "author": "tangjingyuanivan@gmail.com",
  "dependencies": {
    "@aws-amplify/cli": "^8.0.0",
    "@aws-amplify/ui-components": "^1.9.6",
    "@aws-sdk/client-cognito-identity-provider": "^3.137.0",
    "@aws-sdk/util-credentials": "^3.56.0",
    "@culturehq/add-to-calendar": "^1.1.2",
    "@fortawesome/fontawesome-svg-core": "^6.4.0",
    "@fortawesome/free-solid-svg-icons": "^6.4.0",
    "@fortawesome/react-fontawesome": "^0.2.0",
    "@livechat/widget-react": "^1.3.0",
    "@lottiefiles/react-lottie-player": "^3.4.2",
    "@mdx-js/react": "^2.3.0",
    "@popperjs/core": "^2.9.1",
    "@rollup/plugin-node-resolve": "^15.2.1",
    "@types/google.analytics": "^0.0.42",
    "@types/react-modal": "^3.13.1",
    "@uploadcare/blocks": "^0.25.4",
    "@uploadcare/react-widget": "^2.4.3",
    "amazon-cognito-identity-js": "^6.3.1",
    "aws-amplify": "^4.3.10",
    "babel-plugin-styled-components": "^2.0.2",
    "bootstrap": "^5.0.0-beta2",
    "chart.js": "^3.9.1",
    "clsx": "^1.2.1",
    "dateformat": "^4.5.1",
    "dotenv": "^8.2.0",
    "gatsby": "^4.7.0",
    "gatsby-background-image": "^1.6.0",
    "gatsby-omni-font-loader": "^2.0.2",
    "gatsby-plugin-google-tagmanager": "^4.5.0",
    "gatsby-plugin-image": "^2.14.1",
    "gatsby-plugin-load-script": "^1.1.0",
    "gatsby-plugin-manifest": "^3.14.0",
    "gatsby-plugin-offline": "^5.18.1",
    "gatsby-plugin-react-svg": "^3.1.0",
    "gatsby-plugin-remote-images": "^3.6.0-alpha.1",
    "gatsby-plugin-resolve-src": "^2.1.0",
    "gatsby-plugin-sass": "5.17.0",
    "gatsby-plugin-scroll-indicator": "^1.0.1",
    "gatsby-plugin-sharp": "^4.14.1",
    "gatsby-plugin-sitemap": "^5.12.1",
    "gatsby-plugin-styled-components": "^5.3.0",
    "gatsby-source-filesystem": "^4.18.1",
    "gatsby-theme-blog-core": "^4.0.0",
    "gatsby-theme-landing-page": "^1.0.2",
    "gatsby-transformer-remark": "^5.18.1",
    "gatsby-transformer-sharp": "^4.14.0",
    "gbimage-bridge": "^0.2.2",
    "grommet": "^2.18.0",
    "grommet-icons": "^4.6.2",
    "grommet-theme-hpe": "^4.1.0",
    "jquery": "^3.6.0",
    "lodash.differencewith": "^4.5.0",
    "moment": "^2.29.4",
    "namor": "^2.0.2",
    "node-sass": "^9.0.0",
    "npm-check-updates": "^16.13.1",
    "patch-package": "^6.4.7",
    "prop-types": "^15.7.2",
    "rc-slider": "^9.7.2",
    "react": "^17.0.1",
    "react-chartjs-2": "^4.3.1",
    "react-datepicker": "^4.2.0",
    "react-dom": "^17.0.1",
    "react-helmet": "^6.1.0",
    "react-hook-form": "^7.43.9",
    "react-indiana-drag-scroll": "^2.1.0",
    "react-lottie": "^1.2.3",
    "react-modal": "^3.12.1",
    "react-phone-input-2": "^2.15.0",
    "react-phone-number-input": "^3.2.20",
    "react-range": "^1.8.11",
    "react-responsive": "^9.0.2",
    "react-search-box": "^2.2.1",
    "react-select": "^4.3.0",
    "react-share": "^4.4.0",
    "react-slick": "^0.29.0",
    "react-table": "^7.6.3",
    "react-use-draggable-scroll": "^0.4.0",
    "react-whatsapp-chat-widget": "^1.1.6",
    "rollup": "^3.28.1",
    "sass": "^1.63.4",
    "slick-carousel": "^1.8.1",
    "styled-components": "^5.3.3",
    "three": "^0.155.0",
    "uploadcare-widget": "^3.21.2",
    "urijs": "^1.19.11",
    "web-ifc": "^0.0.42",
    "web-ifc-viewer": "^1.0.218"
  },
  "devDependencies": {
    "@types/node": "^14.14.31",
    "@types/react": "^18.0.1",
    "@types/react-dom": "^17.0.1",
    "@typescript-eslint/parser": "^5.0.1",
    "cypress": "9.3.1",
    "cypress-localstorage-commands": "^1.7.0",
    "eslint": "^8.7.0",
    "prettier": "^2.5.1",
    "typescript": "^4.4.4"
  },
  "resolutions": {
    "graphql": "^15.0.0",
    "@types/react": "18.0.1"
  },
  "keywords": [
    "gatsby",
    "sass",
    "scss"
  ],
  "license": "MIT",
  "scripts": {
    "build": "gatsby build",
    "develop": "gatsby develop",
    "lint": "Get started linting your code with Eslint and stylelint",
    "format": "yarn prettier --write .",
    "start": "yarn develop",
    "serve": "gatsby build && gatsby serve",
    "test": "yarn cypress run",
    "clean": "gatsby clean",
    "compile-sass": "node-sass src/assets/stylesheets/application.scss static/css/style.css",
    "postinstall": "yarn patch-package",
    "refresh": "curl -X POST http://localhost:8000/__refresh"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/colbyfayock/gatsby-starter-sass"
  },
  "bugs": {
    "url": "https://github.com/colbyfayock/gatsby-starter-sass/issues"
  }
}

Behavior and Results:

When I run this, it displays like this screen Rendered UI

If I pick the ifc file called 1.ifc, then it doesn't work and I can see some errors in the browser console. Here is its content.

web-ifc-api.js:5632 wasm streaming compile failed: LinkError: WebAssembly.instantiate(): Import #48 module="a" function="X" error: function import requires a callable

falling back to ArrayBuffer instantiation

web-ifc-api.js:5623 failed to asynchronously prepare wasm: LinkError: WebAssembly.instantiate(): Import #48 module="a" function="X" error: function import requires a callable

web-ifc-api.js:5544 Aborted(LinkError: WebAssembly.instantiate(): Import #48 module="a" function="X" error: function import requires a callable)

RuntimeError: Aborted(LinkError: WebAssembly.instantiate(): Import #48 module="a" function="X" error: function import requires a callable). Build with -sASSERTIONS for more info.

My working Environment:

Question: How can I resolve this wasm path in gatsby project?

sbc100 commented 1 year ago

The wasm file you are trying to load has had its import names minified as part of code size optimization. That is why the import its looking for is a.X and not something more meanful like env.myfunc.

The JS code that loads this was module is automatically generated by emscripten and embeds these minified names. Perhaps you updated the wasm file without also updating the JS loading code. The JS loaded code (web-ifc-api.js) must match exacltly the wasm file.. they are built together as unit.

tptspe commented 1 year ago

@sbc100 Thanks for your taking time with my issue.

Btw, I am not clear howto match the JS loading code with wasm file. Would you explain about it and solution for me again?

Regards.

sbc100 commented 1 year ago

When you build a wasm file with emscripten it also produces a js file. In your case it looks like that file is called web-ifc-api.js.

If you didn't build that file then the best course of action is probably to find out who did and go to talk to them about your issue.

tptspe commented 1 year ago

@sbc100 I didn't build wasm file separate for web-ifc-api.js separately. I only installed web-ifc-viewer package by following this guide https://github.com/ifcjs/web-ifc-viewer And I copied wasm files from its source directory from node_modules folder. Its folder structure in the node_modules like this. image

Let me send msg to web-ifc-viewer team, too. If you have any solution, please update me. Thanks