Angular中引入外部JS文件调用$FPROM函数报错的解决方法
这个问题本质是TypeScript不知道全局存在$FPROM这个变量,再加上Angular的模块封装机制,直接import本地JS文件不会自动把变量挂载到全局作用域。下面给你几个可行的解决方案,按推荐程度排序:
方案1:全局配置脚本+类型声明(推荐)
如果多个组件都要用到FirstPromoter的功能,这种方法最省心:
在angular.json中配置全局脚本
打开项目根目录的angular.json,找到projects -> 你的项目名 -> architect -> build -> options -> scripts数组,把外部JS的CDN地址或者本地文件路径加进去:"scripts": [ "https://cdn.firstpromoter.com/fprom.js" // 或者本地路径:"src/app/components/your-component/fprom.js" ]配置后重启Angular开发服务器,脚本会在应用启动时全局加载。
添加TypeScript类型声明
因为TS不知道$FPROM的类型,需要手动声明它。在项目根目录或者组件所在文件夹下创建一个typings.d.ts文件(如果已经有就直接追加内容),写入:declare var $FPROM: { trackSignup: (params: { email: string, uid: string }, callback?: () => void) => void; // 可以根据需要添加其他你会用到的$FPROM方法 };这样TS就会识别
$FPROM是全局可用的变量了。
方案2:组件内动态加载脚本+类型声明(适合单个组件使用)
如果只有当前组件需要用到这个功能,不想全局加载脚本,可以在组件里动态加载:
在组件类中动态加载脚本
把这段代码加到你的组件类的ngOnInit生命周期钩子中:ngOnInit(): void { const script = document.createElement('script'); script.src = 'https://cdn.firstpromoter.com/fprom.js'; script.onload = () => { // 脚本加载完成后再调用方法,避免未初始化报错 $FPROM.trackSignup({ email: this.userEmail, uid: this.userId }, () => { // 这里写回调逻辑 }); }; document.body.appendChild(script); }同样添加类型声明
还是需要创建或修改typings.d.ts文件,写入方案1里的声明代码,否则TS依然会提示找不到$FPROM。
方案3:修改本地JS文件导出(不推荐)
如果你坚持用本地fprom.js文件,也可以修改JS文件,把$FPROM导出:
在fprom.js末尾加上:
export default $FPROM;
然后在组件中导入:
import $FPROM from './fprom.js';
不过这种方法可能会破坏原JS文件的全局逻辑,而且如果原文件有依赖全局环境的代码,可能会出现未知问题,所以不推荐使用。
内容的提问来源于stack exchange,提问作者cup_of

