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

Cannot import { OrbitControls } from three/examples/jsm #4

Closed
etoal83 opened this issue Aug 12, 2020 · 2 comments
Closed

Cannot import { OrbitControls } from three/examples/jsm #4

etoal83 opened this issue Aug 12, 2020 · 2 comments

Comments

@etoal83
Copy link
Owner

etoal83 commented Aug 12, 2020

👾 Background

I'm using OrbitControls in a Next.js app with react-three-fiber. The module OrbitControls is provided from Three.js 'three/jsm' so put the following import statement, but it doesn't work and raises:

SyntaxError: Cannot use import statement outside a module

Any workarounds?

import { Canvas, useFrame, useThree, extend } from 'react-three-fiber';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; // This raises error

extends({ OrbitControls });

const CameraControls = () => {
  const {
    camera,
    gl: { domElement },
  } = useThree();
  const controls = useRef();

  useFrame((state) => {
    controls.current.update();
  });

  return (
    <orbitControls ref={controls} args={[camera, domElement]} />
  );
};

const SomeMesh = () => {
  return <mesh>...</mesh>
};

const Scene = () => (
  <Canvas camera={{ position: [100, 0, 0] }}>
    <CameraControls />
    <directionalLight position={[500, 500, 500]} intensity={0.8} />
    <SomeMesh />
  </Canvas>
);

export default Scene;
@etoal83 etoal83 changed the title Cannot import { OrbitControls } from Three.js example Cannot import { OrbitControls } from three/examples/jsm Aug 12, 2020
@etoal83
Copy link
Owner Author

etoal83 commented Aug 30, 2020

🚁 Workaround1: Using require instead

For a moment, I dealt with this problem by using JS' require to directly call the OrbitControls and it worked well😆✨

let OrbitControls;

const CameraControls = () => {
  OrbitControls = require('three/examples/jsm/controls/OrbitControls')
    .OrbitControls;
  extend({ OrbitControls });

  const {
    camera,
    gl: { domElement },
  } = useThree();
  const controls = useRef();

  useFrame((state) => {
    controls.current.update();
  });

  return (
    <orbitControls ref={controls} args={[camera, domElement]} />
  );
};

I found this solution in the Three.js discourse forum - Can not load GLTFLoader in nextjs application!.
I didn't completely understand why it worked but it seems preventing Next.js from importing the untranspiled jsm when SSR (I just cited a forum comment, to be honest...😝💦)

Anyway, that's pretty helpful!

@etoal83
Copy link
Owner Author

etoal83 commented Aug 30, 2020

🚁 Workaround2: Configuring module transpilation

Though I spent peaceful days with the workaround1, this issue happened again when I added react-spring/drei to my app!😫🌧

😷 Symptoms

While Next.js dev server was running, I added react-spring/drei by yarn add drei then the following error appeared in the localhost browser window.

Attempted import error: 'addAfterEffect' is not exported from 'react-three-fiber'.

Then I upgraded all the node_modules as this error seemed fixed in the recent version of react-three-fiber according to this issue report. → pmndrs/drei#59
So I restarted the dev server once and make it run again. But instead of the error message above, the titled issue has come out soon!

💊 Solution

Referring to the PR merged into the Next.js three-js example (vercel/next.js#14864), I added a module martpie/next-transpile-modules and put the following transpilation settings in next.config.js. Finally the build went successfully😊💚

const withTM = require('next-transpile-modules')([
  'drei',
  'three',
  'postprocessing',
]);

module.exports = withTM();

Note that this way pops some warnings in the terminal like these:

[BABEL] Note: The code generator has deoptimised the styling of /path/to/the/project/etoal-labs/node_modules/three/build/three.js as it exceeds the max of 500KB.
[BABEL] Note: The code generator has deoptimised the styling of /path/to/the/project/etoal-labs/node_modules/three/build/three.module.js as it exceeds the max of 500KB.

In this moment I ignore these warnings and just keep them in mind as I don't know absolutely how serious the performance of Babel is onto my app. But I'll stay awared...🙄

@etoal83 etoal83 closed this as completed Aug 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant