gdsestimating/three-dxf

Unable to load ThreeDxf from the window object in React

niranjanshukla opened this issue · 3 comments

I am trying to load the three-dxf script into my React app using below.

useEffect(() => {
    const script = document.createElement("script");
    script.type = 'text/javascript';
    script.src = '/dist/three-dxf.js';
    script.async = true;
    script.onload = () => scriptLoaded();

    document.getElementsByTagName('head')[0].appendChild(script);
  });

The above does not give any error, however, inside the scriptLoaded function, when I try to load the ThreeDxf object from the window object, it gives undefined, i.e.

window.ThreeDxf.Viewer(...) gives an error TypeError: Cannot read property 'Viewer' of undefined

Any idea why the window object does not contain ThreeDxf?

Sorry, I'm not familiar enough with react to have an immediate answer. I've been meaning to try to create a react sample so I can learn and have it available for people. If anyone wants to make a PR with a simple react sample, I'd happily merge it in.

# the latest version of three: 0.133.1
yarn add three

yarn add dxf-parser
yarn add three-dxf

Hmm....


/node_modules/three-dxf/src/index.js

+ import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'

// line: 570
- geometry = new THREE.TextGeometry(entity.text, { font: font, height: 0, size: entity.textHeight || 12 });

+ geometry = new TextGeometry(entity.text, { font: font, height: 0, size: entity.textHeight || 12 });

And...

import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'

//@ts-ignore
import DxfParser from 'dxf-parser'

//@ts-ignore
- import { Viewer } from 'three-dxf'
+ import { Viewer } from 'three-dxf/src/index'

Demo:

import React, { useEffect } from 'react';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
import axios from 'axios';

//@ts-ignore
import DxfParser from 'dxf-parser'

//@ts-ignore
import { Viewer } from 'three-dxf/src/index'

import './App.css';

function App() {

  useEffect(() => {

    const promise = axios.get('./dxf/demo.dxf')
    promise.then(response => {
      console.log('get file text')
      const fileText = response.data as string
      const parser = new DxfParser()
      try {
        const dxf = parser.parseSync(fileText)
        console.log(dxf)

        const cadViewDiv = document.getElementById('cad-view')
        const fontLoader = new FontLoader()
        fontLoader.load('./fonts/helvetiker_regular.typeface.json', (font) => {
          const cadCanvas = new Viewer(dxf, cadViewDiv, 800, 600, font)
          console.log(cadCanvas)
        })

      } catch (error) {
        console.log(error)
      }
    })
    promise.catch(error => {
      console.log(error)
    })

  }, [])

  return (
    <div id='cad-view'></div>
  );
}

export default App;

Please Note:

In the above example code, I use vite + react + typescript.

I tried to use 'create-react-app', but I encountered this error:

./node_modules/@dxfom/mtext/index.mjs 8:14
Module parse failed: Unexpected token (8:14)
File was processed with these loaders:
 * ./node_modules/react-scripts/node_modules/babel-loader/lib/index.js  
You may need an additional loader to handle the result of these loaders.

We know that the create-react-app uses weback4.

I think weback4 does not support it, but I haven't found a solution.

Therefore, there are only two solutions: use webpack5 or vite

I've the same problem ,I hope the author could solve it.