Angular项目引入外部JS报错KTLayoutBrand.init不是函数
问题原因
- 导入规范不匹配:外部JS使用ES6的
export default语法导出对象,但组件中使用CommonJS的require语法导入,此时require返回的是包裹了导出内容的对象,实际的KTLayoutBrand实例存放在返回对象的default属性下,直接调用KTLayoutBrand.init自然会抛出方法不存在的错误。 - CommonJS导出被注释:外部JS末尾的
module.exports = KTLayoutBrand处于注释状态,没有对CommonJS规范暴露导出内容,进一步导致require无法拿到正确的实例。 - 重复加载冲突:如果你已经将JS文件添加到了
angular.json的scripts数组中,这些JS会被全局加载并挂载到window对象上,组件内再次重复导入会引发变量冲突,也可能导致调用异常。
验证方法
你可以在调用KTLayoutBrand.init前添加一行打印代码:
console.log(KTLayoutBrand)
如果打印结果是包含default属性的对象,可确认是导入规范不匹配问题;如果打印结果为undefined,则是JS未正常加载或导出异常。
解决方法
你可以任选一种适配方案操作:
方案1:调整导入语法适配ES6导出
将组件内所有require导入改为ES6的import语法,直接获取default导出的内容:
import { Component, OnInit, AfterViewInit } from '@angular/core'; // 替换所有require为import import { KTUtil } from '../../../assets/js/util.d'; import KTLayoutAsideToggle from '../../../assets/js/aside-toggle'; import KTLayoutStickyCard from '../../../assets/js/sticky-card'; import KTLayoutStretchedCard from '../../../assets/js/stretched-card'; import KTLayoutBrand from '../../../assets/js/brand'; import KTLayoutAside from '../../../assets/js/aside'; import KTLayoutAsideMenu from '../../../assets/js/aside-menu';
如果你要保留require写法,需手动取default属性:
const KTLayoutBrand = require( '../../../assets/js/brand').default;
方案2:放开CommonJS导出注释
将所有外部JS末尾的module.exports = 对应实例的注释去掉,以KTLayoutBrand的JS为例,修改为:
// Webpack兼容支持 if (typeof module !== 'undefined') { module.exports = KTLayoutBrand; }
修改后组件内原有require写法即可正常拿到实例。
方案3:直接使用全局挂载的对象(适配angular.json引入脚本的场景)
如果你已经在angular.json中配置了JS加载,可直接删除组件内所有导入这些JS的代码,通过全局变量调用,只需在组件顶部添加TS类型声明避免报错即可:
import { Component, OnInit, AfterViewInit } from '@angular/core'; // 声明全局变量 declare const KTUtil: any; declare const KTLayoutAsideToggle: any; declare const KTLayoutStickyCard: any; declare const KTLayoutStretchedCard: any; declare const KTLayoutBrand: any; declare const KTLayoutAside: any; declare const KTLayoutAsideMenu: any;
修改后原有调用逻辑不需要改动即可正常运行。
内容的提问来源于stack exchange,提问作者Pooja Shah
相关产品推荐
相关产品推荐

