关于ES6新增的script标签type为module和importmap的使用和坑点
关于ES6新增的script标签type为module和importmap的使用和坑点
今天在做web3D的时候,为了简单的验证一些案例,我直接在html上书写,但是three.js的导入都是模块化的,为了解决这个问题,ES++6已经给出解决方法,那就是在script标签中,使用type为module的声明,就可以实现导入,下面展示下简单的使用:
<script type="module" src="./02.js"></script> //这里声明为module后,我连接到另外一个文件
02.js的内容如下:
import * as THREE from './build/three.module.js'
//创建一个三维场景
const scene=new THREE.Scene()
const geometry = new THREE.BoxGeometry( 50, 50, 50 );
到这里,对于module的使用是没有问题的。
那么没问题就是有问题,后续我还需要导入另外一个模块,这个时候就非常魔怔了,我的导入是这样子的:
import * as THREE from './build/three.module.js'
import { OrbitControls } from './three.js-r148/examples/jsm/controls/OrbitControls.js';
我觉得这样子是没问题的,因为我已经声明导入了,但是关键就是浏览器一直报错,长这样子:
01.html:1 Uncaught TypeError: Failed to resolve module specifier “three”. Relative references must start with either “/”, “./”, or “…/”.
01.html:1 Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".
啥意思呢,就是说我的导入,如果是相对的就必需使用到./,…/,/ 开头,这就很纳闷了,我明明就使用到./了,为什么还是报错,,难道是导入的东西有问题?查看下导入的模块代码:
import {
EventDispatcher,
MOUSE,
Quaternion,
Spherical,
TOUCH,
Vector2,
Vector3
} from 'three';
确实他自己有导入,但是这个three和我上面那个three又不是同一个,难道说这样子还会冲突,但是报的错误又不是这个,搞不懂!那就找别的办法!
那我现在改写为importmap方式,我直接模仿脚手架导入方式,ES6的script添加的type功能还是很强大的,但是可能是个人原因,使用起来老磕磕碰碰,这里展示下我怎末使用的,首先,我们需要声明出来,然后设置模块的位置:
<script type="importmap">
{
"imports": {
"three": "./three.js-r148/build/three.module.js",
"three/addons/": "./three.js-r148/examples/jsm"
}
}
</script>
上面的代码意思大概就是,我告诉浏览器,我需要使用import语法,然后我import的名字里面,对应的有文件所在的位置,比如导入three,那么文件的位置就在"./three.js-r148/build/three.module.js",然后,还需要配合type=module使用:
<script type="module" src="./02.js"></script>
展示02.js代码:
import * as THREE from './build/three.module.js';
import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
console.log(OrbitControls);
这样子对于importmap的使用大致就是这样子,理论上是没问题的了,接下来我们打开下html看看,emmmm,还有问题:报错为
Uncaught TypeError: Failed to resolve module specifier “three/addons/controls/OrbitControls.js”. Import Map: “three/addons/controls/OrbitControls.js” matches with “three/addons/” but is blocked by a null value
Uncaught TypeError: Failed to resolve module specifier "three/addons/controls/OrbitControls.js". Import Map: "three/addons/controls/OrbitControls.js" matches with "three/addons/" but is blocked by a null value
这个问题我看到的时候倒是不怕了,因为显示的是 “three/addons/” 这个名字没有被索引到,显示为null值,自然加载不了引用到的那个对象,那么为啥会这样,网络上没解决办法,那就自己来。仔细看报错,是说这个尾缀使用到这个/结尾但是却获得空值,那我仔细想一想,也对,如果使用到 “three/addons/” 这个空间,而我在导入是这样子的:“./three.js-r148/examples/jsm”,真正的js文件在引用确是:“three/addons/controls/Orbitcontrols”,那我们合并一下,是不是就变成了:
/three.js-r148/examples/jsmcontrols /Orbitcontrols
那问题就很明显了,合并后文档jsm和control是有/的,但是被我分开了。这个时候也就理解为什么importmap说如果我的"three/addons/"是以“/”结尾的,那么我的路径也是需要以“/”结尾的,所以我做出以下修改:
<script type="importmap">
{
"imports": {
"three": "./three.js-r148/build/three.module.js",
"three/addons/": "./three.js-r148/examples/jsm/"
}
}
</script>
好!结果正常!
但是至于为什么纯module,导入一个正常,导入两个就错误,我也还是没搞懂,但是解决方法就是我上面的那种,这个网络上找不到,所以我写一个,看看能不能帮助到道友~