未捕获到的SyntaxError:无法在模块外部使用import语句

时间:2020-04-13 15:21:25

标签: javascript three.js

https://www.youtube.com/watch?v=1TeMXIWRrqE

<!DOCTYPE html>
<html>
<head>
	<title>Three.js</title>
	<style type="text/css">
		html, body {margin: 0; padding: 0; overflow: hidden}
	</style>
</head>
<body>
  <div id="webgl"></div>
	<script src="three.js"></script>
    <script src="GLTFLoader.js"></script>
	<script>
        
    let scene,camera,renderer;
    function init(){
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xdddddd);
    
    camera = new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,5000);
    
    hlight = new THREE.AmbientLight(0x404040,100);
    scene.add(hlight);
    
    renderer = new THREE.WebGLRenderer({antialias:true});
    renderer.setSize(window.innerWidth,window.innerHeight);
    document.getElementById('webgl').appendChild(renderer.domElement);
    
    let loader = new THREE.GLTFLoader();  //THE ERROR WITH THIS, I TRIED WITHOUT THREE. ONLY GLTLOADER() BUT DID NOT WORK 
    loader.load('scene.gltf', function(gltf){
        scene.add(gltf.scene);
        renderer.render(scene,camera);
    });
}
init();
    </script>
      
</body>
</html>
https://sketchfab.com/3d-models/1972-datsun-240k-gt-non-commercial-use-only-b2303a552b444e5b8637fdf5169b41cb // https://www.youtube.com/watch?v=1TeMXIWRrqE 这是GLTFLOADER的教程,我也导入了相同的3d文件并编写了相同的代码,但是当我在本地服务器上打开文件时,在控制台中出现2个错误: 1)“ GLTFLoader.js:9未捕获的SyntaxError:无法在模块外部使用import语句” 2)“(index):29 Uncaught TypeError:THREE.GLTFLoader不是构造函数。” 尽管在youtube视频中,它会立即与他一起打开! :( 如果有人可以帮助我,我将不胜感激。非常感谢

GLTFLoader.js:9未捕获的SyntaxError GLTFLoader.js:9 Uncaught SyntaxError

(索引):29未捕获的TypeError (index):29 Uncaught TypeError

2 个答案:

答案 0 :(得分:3)

Here's a newer tutorialthis article的底部说明了更改之处。

简短版本是three.js,改为使用es6模块,而不是

<script src="three.js"></script>
<script src="GLTFLoader.js"></script>
<script>

let scene,camera,renderer;
function init(){
  ...
  THREE.GLTFLoader.load(...

您会这样做

<script type="module">
import * as THREE from './build/three.module.js';
import {GLTFLoader} from './examples/jsm/loaders/GLTFLoader.js';

let scene,camera,renderer;
function init(){
  ...
  GLTFLoader.load(...

但是要像这样使用它,需要将three.js文件复制到相同的文件夹结构中。

someFolder
 |
 ├-build
 | |
 | +-three.module.js
 |
 +-examples
   |
   +-jsm
     |
     +-controls
     | |
     | +-OrbitControls.js
     | +-TrackballControls.js
     | +-...
     |
     +-loaders
     | |
     | +-GLTFLoader.js
     | +-...
     |
     ...

如果要使用旧方法<script>标记样式,则需要确保使用the js folder而非the jsm folder的文件

注意:您必须使用此文件夹结构,因为examples / jsm文件夹中的文件,例如GLTFLoader.js通过相对但硬编码的路径引用了其他文件,例如three.module.js 。例如,在GLTFLoader.js中有一条有效的行

import {stuff} from "../../../build/three.module.js";

新样式的一些优点是

  1. 各种模块可以插入所需的其他部件。

    过去,要多使用一部分,您可能需要添加1到10个其他<script>标签。现在您只需要导入1次,该部分就可以自己提取其他1到10个部分

  2. 如果您使用网络构建器来构建页面,则可以删除您不使用的部分。

有传言说,将来有计划完全摆脱<script>方法。


只是想弄清楚为什么ES6模块更好,为什么需要保持相同的结构。

在r105之前的版本中,您可以使用EffectComposer

<script src="threejs/examples/js/postprocessing/EffectComposer.js"></script>

您奔跑会出现错误

THREE.EffectComposer relies on THREE.CopyShader

因此,您需要四处寻找它,它与EffectsComposer.js不在同一个文件夹中。最终找到它时,将其添加

<script src="threejs/examples/js/postprocessing/EffectComposer.js"></script>
<script src="threejs/examples/js/shaders/CopyShader.js"></script>

再次运行并得到另一个错误THREE.EffectComposer relies on THREE.ShaderPass,因此再次挖掘时会添加该错误

<script src="threejs/examples/js/postprocessing/EffectComposer.js"></script>
<script src="threejs/examples/js/shaders/CopyShader.js"></script>
<script src="threejs/examples/js/postprocessing/ShaderPass.js"></script>

那太糟了。

现在从r105开始,使用es6模块就可以了

import {EffectComposer} from './threejs/examples/jsm/postprocessing/EffectComposer.js';

可以说哪个更好。您将不会遇到其他错误,因为ES6模块版本EffectComposer.js可以引用其所需的文件,其依赖项,本身。在top of EffectComposer.js处是对其依赖项的引用。

import {
    Clock,
    LinearFilter,
    Mesh,
    OrthographicCamera,
    PlaneBufferGeometry,
    RGBAFormat,
    Vector2,
    WebGLRenderTarget
} from "../../../build/three.module.js";
import { CopyShader } from "../shaders/CopyShader.js";
import { ShaderPass } from "../postprocessing/ShaderPass.js";
import { MaskPass } from "../postprocessing/MaskPass.js";
import { ClearMaskPass } from "../postprocessing/MaskPass.js";

但是,正如您在上面看到的,EffectsComposer.js期望three.module.js位于一个名为build的文件夹中,该文件夹位于其自身下方3个子文件夹中。它期望CopyShader.js位于一个名为shaders的文件夹中,而该文件夹位于其自身下方。等等...

换句话说,它需要相同的文件夹结构

答案 1 :(得分:0)

我遇到了类似的问题,我就是这样解决的。

在您的 HTML 中,添加其他脚本时顺序很重要,因为它需要来自 Three.js 的某些东西。

应该是

   <script src="../build/three.min.js"></script>
   <script src="three.js-master/examples/js/controls/OrbitControls.js"></script>
   <script src="three.js-master/examples/js/loaders/GLTFLoader.js"></script>

我建议尝试从本地 javascript 文件夹导入,而不是使用 from jsm。我希望这能解决您的问题。