美文网首页
模块化引入与对象扩展的冲突

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

作者: 黄昏故梦陈 | 来源:发表于2018-09-04 11:26 被阅读0次

    最近在维护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
    

    相关文章

      网友评论

          本文标题:模块化引入与对象扩展的冲突

          本文链接:https://www.haomeiwen.com/subject/stkgwftx.html