使用Node模块的路径来引用Three.js

8

我正在学习Three.js,并建立了一个基本项目,运行一个node.js服务器并将Three.js作为节点模块导入。

实际上我的设置可以工作,但我有些困惑这是否是一个好的设置?

我在思考的问题主要是我的node_module路径太长了。在一些页面上,Three.js仅通过以下方式导入:

import * as THREE from 'three';

但在我的情况下,我必须写全路径:

import * as THREE from './node_modules/three/build/three.module.js';

这是正确的实现吗?

这是我完整的代码:

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <title>three.js webgl</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            background-color: #cce0ff;
            color: #000;
        }

        a {
            color: #080;
        }
    </style>
</head>

<body>
    <script type="module" src="index.js"></script>
</body>

</html>

index.js

**import * as THREE from './node_modules/three/build/three.module.js';**

const scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

var animate = function () {
    requestAnimationFrame(animate);

    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
};

animate();

我需要使用webpack进行打包吗?能解决找不到我的nodemodules路径的问题吗?


如果使用 import * as THREE from 'three'; 会发生什么? - user5734311
文档所述,当使用官方的npm包时,import * as THREE from 'three';是正确的方法。 - Mugen87
2
是的,在Chrome中可以工作,但在Firefox中我会得到 TypeError: Error resolving module specifier: three。我必须提供完整路径才能让它在Firefox中工作:import * as THREE from './node_modules/three/build/three.module.js'; - acroscene
你的Webpack配置文件是什么样子的? - Jacek Rojek
我没有使用webpack。也许这就是我的问题所在?我需要使用webpack来解决这个问题吗? - acroscene
3个回答

4

除非你有多个JS文件要打包成一个,否则你不需要把Webpack带入其中。一个简单的解决方案是直接指向Three.js的three.module.js版本,无论它存储在哪里。在下面的示例中,我从CDN中导入了它,但如果你愿意,它也可以来自你的node_modules文件夹。

<!DOCTYPE html>
<html lang="en">

<head>
    <title>three.js webgl</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            background-color: #cce0ff;
            color: #000;
        }

        a {
            color: #080;
        }
    </style>
</head>

<body>
    <script type="module">
        import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.module.js';

        const scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        var geometry = new THREE.BoxGeometry(1, 1, 1);
        var material = new THREE.MeshBasicMaterial({ color: 0xff9900 });
        var cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        camera.position.z = 5;

        var animate = function () {
            requestAnimationFrame(animate);

            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;

            renderer.render(scene, camera);
        };

        animate();
    </script>
</body>

</html>

请记住,使用<script type="module">在Edge和IE中不受支持。因此,如果您需要支持这些浏览器,则可能需要使用WebPack。这是一个非常广泛的话题,因此您可以按照其文档的入门部分中的指示进行操作。


4

如果你对打包工具不熟悉,我的建议是使用parcel。这里有一个启动项目可以帮助你入门。如果你不想使用完整的路径,就需要一个打包工具。


1
你可以考虑从CDN导入three.js,该库依赖于UMD(通用模块定义)捆绑包。
<script src="https://unpkg.com/three@0.110.0/build/three.js"></script>
<script src="./path/to/your/index.js"></script>

这将获取库并在全局对象中公开THREE。这是10年前Web前端的工作方式,现在仍应该在任何浏览器中正常工作。
// index.js
const scene = new THREE.Scene();
...

话虽如此,为了支持项目的即将到来的要求,您很快就需要一个打包工具。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接