Three + examples import via CDN

Hello!

I have a React application bundled with Webpack and am trying to load threejs from a CDN on runtime in order to decrease bundle sizes. So far my solution has been to add:

externals: {
   three: 'THREE'
}

on my webpack config, so I can import three on my code using the global variable THREE:

import * as THREE from 'three'

and add the minified three bundle to my html:

<script src="https://unpkg.com/three@0.131.2/build/three.min.js"></script>

This works fine until I need to use something from the examples folder (such as GLTFLoader.js, XREstimatedLight.js, etc). If I add the versions on examples/js to my html it works fine since they are referencing the THREE variable as well, but as I understand it, the examples/js folder will be deprecated soon, correct? And there are some files I use that only exist on examples/jsm, such as XREstimatedLight.js, so I wouldn’t be able to use this anyway.

So my solution so far is to copy the examples I need into my project, changing the relative imports to use the THREE variable as well, but I’m not very satisfied with it: I’d need to copy and change them again whenever I want to update THREE, for example

So my question is: is there a better/recommended way to do this?

you don’t normally use script tags or externals, that is for pre-module era apps.

what you are looking for is called bundle splitting with dynamic imports. and this is inbuilt, there’s nothing much configure.

Example.js

import * as THREE from 'three'

export default function Example {
  return ...
}

index.js

import { Suspense, lazy } from 'react'
import { render } from 'react-dom'

const Example = lazy(() => import('./Example'))

render((
  <Suspense fallback="loading example...">
    <Example />
  </Suspense>
), rootNode)

Example will not be part of the bundle, it gets lazy-loaded. the fallback can be any generic react node: null, strings, components. you can clone this project it does exactly that. it’s using a router + React.lazy, you can toggle through the examples.

since this is react maybe it’s generally a good idea to use react-three-fiber it integrates threejs, so that these two separate worlds are now one and have full awareness of one another.