unable to import `three` installed via `npm` in markdown file of `observable` project

The following js code block in the example-report.md of the default example code of an observable project returns error, when three is already installed via npm install three for this project.

May I ask if I missed something important here?

Code:

import * as three from "three";

Error:

TypeError: Failed to resolve module specifier 'three'

The following also produce error:

Code:

 import * as three from "npm:three";

Error:

TypeError: Failed to fetch dynamically imported module: http://127.0.0.1:3000/_npm/three@0.163.0/_esm.js

The following code works for me:

```js echo
import * as THREE from "npm:three";
```

```js echo
const height = 300;
const camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 10);
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh(geometry, material);
const renderer = new THREE.WebGLRenderer({antialias: true});
camera.position.z = 1;
scene.add(mesh);

const animation = (time) => {
  mesh.rotation.x = time / 2000;
  mesh.rotation.y = time / 1000;
  renderer.render(scene, camera);
};

renderer.setSize(width, height);
renderer.setAnimationLoop(animation);
display(renderer.domElement);
```

An alternative is to do npm install three (as you originally mentioned), and import from node_modules with import * as THREE from "three"; this also works for me under Framework ^1.6 (note that this is the version that was released yesterday, so maybe you just need to upgrade).

Thanks, @Fil

I figured out the source of the problem: The Great Firewall of China. (I’m in China now. No need for more explanation, right?..), or as I suspect.

Once I switch to using roaming data of a non-China mobile number to bypass the Great Firewall and connect to internet, the issue is gone.

The import * as THREE from "npm:three" solution still works even if I switch back to using local internet connection in China within the Great Firewall.

However, I still can’t get import * as THREE from "three" to work, with three@0.163.0 installed via npm, even if I use mobile roaming data for internet connection.

The message remains as TypeError: Failed to resolve module specifier 'three', which is strange because three.js is installed locally now.

I can’t fix China, sorry :-/

Are you running the latest version of Framework?

yes this is because the npm module is downloaded once, then served locally

@Fil, tell me about it… :wink:

I think I have the latest version of the Observable Framework:

npm list

hello-framework@ C:\Users\oat\Downloads\code\t_observable\hello-framework
+-- @observablehq/framework@1.5.1
+-- d3-dsv@3.0.1
+-- d3-time-format@4.1.0
+-- rimraf@5.0.5
`-- three@0.163.0

I see. But my question will be: How come import * as THREE from "three" is not working, if three has been downloaded successfully?

The latest version is 1.6; you need this release because that’s when we introduced the node imports feature.

Importing from “npm:module” uses a completely different method (please see the documentation for all details).

Woops, my bad. Yes, after update the observable package, import * as THREE from "three" works now. Thanks.

1 Like