2

Scenario

I'm working on a group project and one of the project maintainers understandably wants to use Next.js. We are using three.js in the project and while leveraging the GLTFLoader I've run into something unsuspected.

SyntaxError: Cannot use import statement outside a module

Which seems due to importing the GLTFLoader like so

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

I KIND OF understand why this would happen but check this out: if I comment out the import line and refresh the browser then I see a page with no errors as expected. Now the page is hot-reloading and if I uncomment the GLTFLoader import along with the GLTFLoader code then everything works as expected!

BUT

If I refresh the page manually I'm greeted with the initial SyntaxError message & description and have to comment out & uncomment code accordingly.

Question

Why is this happening? Is this a Next.js issue rather than a Webpack issue? And ultimately, how can I get around this?

Attempts

  • import { GLTFLoader } from 'three-full'; // material.customProgramCacheKey is not a function
    
  • import { GLTFLoader } from 'three'; TypeError: three__WEBPACK_IMPORTED_MODULE_3__.GLTFLoader is not a constructor
    
  • new THREE.GLTFLoader(); TypeError: three__WEBPACK_IMPORTED_MODULE_3__.GLTFLoader is not a constructor
    
  • import { GLTFLoader } from 'https://threejs.org/examples/jsm/loaders/GLTFLoader.js'; // Webpack supports "data:" and "file:" URIs by default. You may need an additional plugin to handle "https:" URIs.
    
  • package.json { "type": "module }
  • etc etc

next.config.js This seems appropriate as something may need to be added here

module.exports = {
  future: {
    webpack5: true,
  },
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    config.module.rules.push(
      // ...

      // Shaders
      {
        test: /\.(glsl|vs|fs|vert|frag)$/,
        exclude: /node_modules/,
        use: ['raw-loader'],
      }
    );
    return config;
  },
};

** EDIT **

I think I found a workaround https://onion2k.hashnode.dev/loading-a-gltf-model-in-react-three-fiber

** TEMPORARY SOLUTION **

import { useGLTF } from '@react-three/drei'

const assetURL = "/asset/scene.gltf";
const Asset = useGLTF(assetURL);

scene.add(Asset.scene)

useGLTF.preload(assetURL);
2
  • 1
    Does this help answer the question: NextJS + react-hook-mousetrap : “Cannot use import statement outside a module”? Different lib but same solution using next-transpile-modules. Commented May 25, 2021 at 13:00
  • @juliomalves Good find. That didn't work for me out of the box but I'm willing to bet that transpiling is what I'll ultimately have to do. I'll report back when I get more time to check that out. Thanks! Commented May 25, 2021 at 22:29

1 Answer 1

1

I ended up using next/dynamic

import dynamic from 'next/dynamic';

...

const DynamicPackage = dynamic(() => import('package'), { ssr: false });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.