I've been struggling with importing example modules from three.js, I have used next.js (a server-side react framework) in my project with a custom server in express. My server code looks like this -
const express = require('express'); const next = require('next'); const favicon = require('serve-favicon'); var path = require('path'); let fs = require('fs') const dev = process.env.NODE_ENV !== 'production'; const nextApp = next({ dev }); nextApp.prepare() .then(() => { let server = express(), options = {}, PORT = 3000, app = express() if (dev) { // DEVELOPMENT /// // DEVELOPMENT /// } else { // PRODUCTION /// options = { ...options } // PRODUCTION /// } server.use(favicon(path.join(__dirname, "/favicon.ico"))) server.get('/', (req, res) => { const actualPage = '/'; nextApp.render(req, res, actualPage); }); server.get('*', (req, res) => { const actualPage = '/not-found'; nextApp.render(req, res, actualPage); // return handle(req, res) }); server.listen((PORT), (err) => { if (err) throw err console.log('>> Ready on ' + PORT) }) }) .catch((ex) => { console.error(ex.stack) process.exit(1) }) I basically ran a npx create-next-app and configured a custom express server in my next.js project for dynamic routing as you can see in the code above.
Then, I used three.js to create a scene in a home component which is imported and rendered in my App.js file. My home.js component looks like this -
import React, { useState, useEffect } from 'react' import * as THREE from 'three' import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls' import "../src/assets/sass/home.scss" const X = () => { let parent, renderer, scene, camera, TrackballControls useEffect(() => { // renderer renderer = new THREE.WebGLRenderer() renderer.setSize( window.innerWidth, window.innerHeight ) document.body.appendChild( renderer.domElement ) // scene scene = new THREE.Scene() // camera camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 ) camera.position.set( 20, 20, 20 ) // controls controls = new TrackballControls( camera ) controls.minDistance = 5 controls.maxDistance = 250 controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled controls.dampingFactor = 0.05; // axes // scene.add(new THREE.AxisHelper( 20 )) // geometry let geometry = new THREE.SphereGeometry( 2, 8, 6, 0, 6.3, 0, 3.1) // material let material = new THREE.MeshBasicMaterial({ wireframe: true, wireframeLinewidth: 1 }) let sphere = new THREE.Mesh( geometry, material ) // parent parent = new THREE.Object3D() scene.add( parent ) scene.add( sphere ) function animate() { requestAnimationFrame( animate ) parent.rotation.z += 0.01 controls.update() renderer.render( scene, camera ) } animate() } ,[]) return <div></div> } export default X Now here's the problem I'm facing - I'm importing an example module from three.js called TrackballControls which is not exactly inside the core three module, but in a folder outside it as you can see from the path - 'three/examples/jsm/controls/TrackballControls.js'. You can see more here - Importing es6 modules separately . But somehow, it's not working. It's throwing an error like
I tried doing the same thing using a simple create-react-app, the import totally works!! So I know there is a problem with my server side code, and I am assuming it's a webpack related issue. But I don't really have any idea about webpack. Someone please help me, for it will be highly appreciated!
Here's my next.config.js file if it helps -
const withSASS = require('@zeit/next-sass') const { parsed: localEnv } = require('dotenv').config() const webpack = require('webpack') // const path = require('path') function HACK_removeMinimizeOptionFromCssLoaders(config) { console.warn( 'HACK: Removing `minimize` option from `css-loader` entries in Webpack config', ) config.module.rules.forEach(rule => { if (Array.isArray(rule.use)) { rule.use.forEach(u => { if (u.loader === 'css-loader' && u.options) { delete u.options.minimize } }) } }) } module.exports = withSASS( { webpack(config) { HACK_removeMinimizeOptionFromCssLoaders(config) config.plugins.push(new webpack.EnvironmentPlugin(localEnv)) return config } }) 