<p dir="auto">For a long time threejs had trouble with commonjs environments, see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="478901051" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/17220" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/17220/hovercard" href="https://github.com/mrdoob/three.js/issues/17220">#17220</a> It affects all jsm files that mutate the namespace, ReactAreaLights for instance.</p>
<p dir="auto">A dirty workaround existed:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import * as THREECJS from 'three'
import * as THREE from 'three/build/three.module'
Object.assign(THREE, THREECJS)"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-c1">THREECJS</span> <span class="pl-k">from</span> <span class="pl-s">'three'</span>
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-c1">THREE</span> <span class="pl-k">from</span> <span class="pl-s">'three/build/three.module'</span>
<span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">assign</span><span class="pl-kos">(</span><span class="pl-c1">THREE</span><span class="pl-kos">,</span> <span class="pl-c1">THREECJS</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">It works around threeejs broken module resolution by merging the two namespaces that it creates into one. (And yes, using threejs+jsm in cjs currently loads two versions of the same library with two separate namespaces). But something in threejs took that away recently:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="Cannot set property ACESFilmicToneMapping of #&lt;Object&gt; which has only a getter"><pre class="notranslate"><span class="pl-v">Cannot</span> <span class="pl-s1">set</span> <span class="pl-s1">property</span> <span class="pl-v">ACESFilmicToneMapping</span> <span class="pl-s1">of</span> #<span class="pl-c1">&lt;</span><span class="pl-v">Object</span><span class="pl-c1">&gt;</span> <span class="pl-s1">which</span> <span class="pl-s1">has</span> <span class="pl-s1">only</span> <span class="pl-s1">a</span> <span class="pl-s1">getter</span></pre></div>
<p dir="auto">sandbox: <a href="https://codesandbox.io/s/three-fiber-useloader-rohv5?file=/src/index.js:0-103" rel="nofollow">https://codesandbox.io/s/three-fiber-useloader-rohv5?file=/src/index.js:0-103</a></p>
<p dir="auto">Could threejs please remove cjs? By offering <code class="notranslate">"main": "build/three.js"</code> it appears as if it does support cjs, but jsm most definitively doesn't, since it refers to <code class="notranslate">three/build/three.module</code>.</p>
<p dir="auto">I don't understand for whom that cjs file is for tbh. You can't use <strong>any</strong> third party lib or add-on reliably, including examples/jsm - and in every case you're loading threejs twice. Why would anyone want this? It's causing so much trouble, i can't count the bug tickets i get b/c of this. It would be such a relief to see that file go, or at least the entry in package.json.</p>
<p dir="auto">Importing from <code class="notranslate">three/examples/jsm/.../&lt;module&gt;</code> causes bundlers (tested with rollup) to include the library twice (or multiple times).</p>
<p dir="auto">For example, when doing <code class="notranslate">import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'</code>, the bundler will follow the import and in the OrbitControls.js the imports come from  <a href="https://github.com/mrdoob/three.js/blob/dev/examples/jsm/controls/OrbitControls.js#L18"><code class="notranslate">../../../build/three.module.js</code></a>. However, there is no way for the (external) bundler to know that <code class="notranslate">../../../build/three.module.js</code> is the same module as <code class="notranslate">three</code>.</p>
<p dir="auto">A solution for this would be to treat the examples modules as external packages and import from <code class="notranslate">three</code> instead of <code class="notranslate">../../../build/three.module.js</code>. This might break the rollup config of three.js, but it should be possible to tell rollup that <code class="notranslate">three</code> is an alias for the main entry point of three (<code class="notranslate">src/Three.js</code>).</p>