Skip to content

Conversation

@chirsz-ever
Copy link
Contributor

Node.js and Deno do not support self.

@github-actions
Copy link

github-actions bot commented Mar 31, 2025

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 336.36
78.34
336.36
78.34
+0 B
+0 B
WebGPU 533.31
148.2
533.34
148.21
+30 B
+12 B
WebGPU Nodes 532.78
148.1
532.81
148.11
+30 B
+12 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 465.37
112.21
465.37
112.21
+0 B
+0 B
WebGPU 604.9
164.17
604.93
164.18
+30 B
+12 B
WebGPU Nodes 559.88
153.6
559.91
153.61
+30 B
+12 B

@chirsz-ever chirsz-ever force-pushed the chirsz/fix-self-250401 branch from 52be400 to a8b860a Compare March 31, 2025 17:27
Comment on lines 37 to 38
this._context = typeof self !== 'undefined' ? self : // browser or Web Worker
typeof globalThis !== 'undefined' ? globalThis : // ES 2020
typeof global !== 'undefined' ? global : // Node.js
null;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use globalThis which is the standard for JS? Then build tools can polyfill this based on build target.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not find globalThis used anywhere else in this repository, so I assume it’s some kind of convention.

@mrdoob do you think using globalThis is OK?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason is that we've decided to stick to ES2018 for compatibility reasons. globalThis is ES2020.

However, if the usage of globalThis does not affect build tools like WebPack 4, I'm okay with using it.

Copy link
Collaborator

@Mugen87 Mugen87 Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just doing this similar to WebGLRenderer:

this._context = typeof self !== 'undefined' ? self : null;

The code is a bit different but the outcome is the same (context evaluates to null):

if ( typeof self !== 'undefined' ) animation.setContext( self );

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just doing this similar to WebGLRenderer:

this._context = typeof self !== 'undefined' ? self : null;

Because I want to polyfill requestAnimationFrame by add it as a global function. If we set _context to null when no self exists, the program would throw here:

this._requestId = this._context.requestAnimationFrame( update );

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even with this polyfill is the renderer actually usable in a node or deno environment? Do you mind explaining your use case a bit?

Copy link
Contributor Author

@chirsz-ever chirsz-ever Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even with this polyfill is the renderer actually usable in a node or deno environment? Do you mind explaining your use case a bit?

Yes. I try to run three.js on Deno with WebGPU1. the polyfill of requestAnimationFrame is

https://github.com/chirsz-ever/deno-webgpu-window-demos/blob/cc5666c17732a68a4dd4f0d8836cf4d771c27118/threejs/polyfill.ts#L151-L155

It is hard to resolve the problem with simplely assigning null to this._context, because Animation is not exported from three.webgpu.js (so we cannot modify its prototype ahead of time), and this._animation.start(); is almost right behind this._animation = new Animation(...) in Renderer.prototype.init(). This even cannot be resolved by set a self member on globalThis, because Deno would remove it when calling npm packages.

If this problem is fixed, most demos would work fine.

Footnotes

  1. https://github.com/chirsz-ever/deno-webgpu-window-demos/blob/master/threejs

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about moving the code into a new function in src/utils.js and call it getSelf(). In this way, we don't clutter Animation.js. Besides, we might need the same logic elsewhere.

I would not simply use globalThis to avoid issues in older environments or tools.

@chirsz-ever chirsz-ever force-pushed the chirsz/fix-self-250401 branch from a8b860a to ad72e21 Compare April 1, 2025 18:47
@chirsz-ever
Copy link
Contributor Author

@Mugen87 getSelf has other meanings in the existing code, so I use getGlobalThis instead.

@chirsz-ever chirsz-ever force-pushed the chirsz/fix-self-250401 branch from ad72e21 to 45dc5f7 Compare April 1, 2025 18:52
@chirsz-ever chirsz-ever force-pushed the chirsz/fix-self-250401 branch from 45dc5f7 to fc79110 Compare April 2, 2025 18:56
@chirsz-ever
Copy link
Contributor Author

@Mugen87

I found another way to make my polyfill work (basically using code in src instead of build), so I switched to the simplest modification we both agreed on.

One more thing I want to request is, whether we should add Animation to the global exports? Just like add this line to src/Three.*.js:

 export { WebXRController } from './renderers/webxr/WebXRController.js';
+export { Animation } from './renderers/common/Animation.js';
 export { FogExp2 } from './scenes/FogExp2.js';

This would make it easier for me to polyfill and allow me to use the code in build.

If you don't agree to export Animation, you can just merge this PR, and I have no more opinions. Or if you allow to export Animation, I would like to add the code.

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 2, 2025

Animation.js is considered to be an internal class. If we export it, it becomes part of the public API which is not wanted. Sorry, but I think it's better to keep the PR as it is.

@Mugen87 Mugen87 added this to the r176 milestone Apr 2, 2025
@Mugen87 Mugen87 merged commit 5f4b079 into mrdoob:dev Apr 2, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants