模块化引入与对象扩展的冲突

最近在维护vue的项目,在一个单页面应用中糅合了arcgis、highcharts、three.js的应用,这些技术要在单页应用中使用,就要使其适合模块化的引入方式,否则在编译打包后可能会产生与开发环境不一致的情况。

问题

为了优化页面加载速度,我在vue-router中使用了异步组件的方式挂载组件,但这样做之后,变异打包后的应用中针对threejs的自定义控制模块OrbitControls失效了。

分析

我引入threejs的方式是这样的

import * as THREE from 'three'

而将OrbitControls注入THREE是这样做的

import {initOrbitControls} from './orbit.js'
initOrbitControls(THREE)

随后我直接在组件中即可调用构造函数THREE.OrbitControl来初始化一个可由鼠标和键盘控制的scene。
以上方法在没有使用异步组建时仅仅是有警告说OrbitControl没有被webpack在three中发现,但是仍然可以正常运行,在使用异步组件并编译打包后,警告变成了错误报告,描述为某个被用作构造函数的方法未定义,也就是OrbitControls方法对THREE的注入失效了。
我将THREE对象释放到window中后,再次访问时,发现其内部是存在着OrbitControl方法的,但是,在组件内部调用的THREE并不是这个THREE,而是某个模块,由此得出,webpack在打包时,不会对当前模块下THREE对象的注入作出解释,因此模块内部仍然访问的是从node_modules中引入的THREE对象。

解决

因此,如果需要对THREE进行扩展,我们仍应该遵守模块的定义方式,将扩展后的THREE作为依赖在当前组件上下文中引入。
于是如下方式可以使得THREE对象被成功扩展,即将扩展后的THREE对象作为模块编写为一个文件,再从组件中引入该模块即可。

import * as THREE from 'three'
import {initOrbitControl} from './orbit.js'
initOrbitControl(THREE)
export default THREE
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。