Jacksonkr
Jacksonkr

Reputation: 32247

Next.js seemingly erroneous message "SyntaxError: Cannot use import statement outside a module"

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

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);

Upvotes: 2

Views: 3000

Answers (1)

Jacksonkr
Jacksonkr

Reputation: 32247

I ended up using next/dynamic

import dynamic from 'next/dynamic';

...

const DynamicPackage = dynamic(() => import('package'), { ssr: false });

Upvotes: 1

Related Questions