Two copies of Three.js were packaged by mistake when I used typescript

When I import like this:

import * as THREE from '../../packages/three.js/src/three';
import {RGBELoader} from '../../packages/three.js/examples/jsm/loaders/RGBELoader';

Will compile and package two copies of three.js, I used rollup.As this topic says:

I checked the code of RGBELoader and found that it was referenced like this:

import {
	DataTextureLoader,
	DataUtils,
	FloatType,
	HalfFloatType,
	LinearEncoding,
	LinearFilter,
	NearestFilter,
	RGBEEncoding,
	RGBEFormat,
	RGBFormat,
	UnsignedByteType
} from '../../../build/three.module.js';

I realize this is the problem and modify it:

import {
	DataTextureLoader,
	DataUtils,
	FloatType,
	HalfFloatType,
	LinearEncoding,
	LinearFilter,
	NearestFilter,
	RGBEEncoding,
	RGBEFormat,
	RGBFormat,
	UnsignedByteType
} from '../../../src/Three';

Worked!

idea:

  • Add three.module.d.ts

  • Modify jsm

this is known. import { ... } from '../../../build/three.module.js' is non-standard and breaks resolution. it’s kind of bad three does this, it’s made so that examples appear as if they are working ootb. it creates a separate namespace so you will always end up with two instances of three in commonjs environments since package.json leads the bundler towards one namespace (build/three.min.js) and jsm isn’t resolved so it goes into another namespace (build/three.module.js). :man_shrugging:

the only correct solution is import { … } from 'three' but it was decided that three won’t do it. at least if cjs is deleted it will start working again (examples/js goes away soon).

1 Like

When importing according to the installation docs, examples do work out of the box:

import { Scene, ... } from 'three';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';

Problems will arise when you import from anything under the src/* directory, because the production builds are under build/, and all examples reference that. Using a relative path for three.module.js instead is also fine, but perhaps less obvious.

3 Likes

Thank you very much for your reply. Can I understand that I can only manually modify the path of using three in jsm, if I am using typescript.

You are right, but if I want to use it in typescript , it is not imported from build , only in src .

It was my fault, I didn’t explain in the title that I was using typescript.

I think I already know how to solve it. The problem is not three. I should read more about typescript, such as typeRoots. I don’t use npm, but I have to quote the content of src because of the type. When using npm, everything is normal. Three's packages.js is set to "types": "src/Three.d.ts", and it works normally in typescript. But I haven’t found how to put three locally and work normally in typescript. If I find the correct solution, I will explain it in this topic.

Well, a very simple solution is to put three's original packages.json file in the directory, so that we can use type and unify a copy of three from the module three.module.js.
If you also use three locally as a dependency instead of through npm,you can do like this:

├─package.json
├─build
├─src
├─examples
|      ├─jsm

as long as threejs is stored in a specific place. html demos would not work if jsm would be its own package or behave like a real npm module. jsm classes on the other hand, which are more valuable, work merely by accident at the moment.

did the threejs maintainers consider skypack? this could solve all these issues. jsm could be a real package. html demos would work ootb without hacks or fragility:

import { Scene, ... } from 'https://cdn.skypack.dev/three'
import { RGBELoader } from 'https://cdn.skypack.dev/three/examples/jsm/loaders/RGBELoader.js'

demo: https://codesandbox.io/s/nostalgic-hooks-msvxz?file=/index.html

imo skypack is a good option for vanilla users. they’d normally not be able to use 3rd party controls and packages without bundling. with skypack they could.

jsm classes on the other hand, which are more valuable, work merely by accident at the moment.

Please give a little more benefit of the doubt here. :slight_smile:

Did the threejs maintainers consider skypack?

I’m not sure I understand which problem this solves? Unpkg and other CDNs do work correctly with three.js (including examples/jsm/) now, but common mistakes come from users mixing imports from different CDNs, or the mixing ES modules with CJS, or using source files instead of built artifacts. It seems like skypack is no better and no worse? I do think that a well-documented, recommended option for vanilla users would be valuable.

1 Like

It auto-bundles so that every package can be consumed as a browser esm without tooling. Unpkg just serves npm packages as cjs/esm with required/imported dependencies which the browser cannot resolve.