Angular 2升级至9(先升4)时LegendSingleton未定义错误求助
嘿,我帮你捋捋这个升级时遇到的问题——本质上是旧的纯JS模块和Angular逐步收紧的模块系统之间的兼容问题,咱们一步步来解决:
第一个问题:LegendSingleton is not defined
这个错误大概率是脚本加载顺序错了。你在.angular-cli.json的scripts数组里同时加了legend.component.js和main.component.js,但main依赖LegendSingleton,如果先加载main,那它运行时LegendSingleton还没被定义,自然报错。
修复步骤:
调整.angular-cli.json里scripts的顺序,把依赖方放在前面:
"scripts": [ "src/app/legend.component.js", // 先加载这个 "src/app/main.component.js" // 再加载依赖它的main ]
保存后重启Angular CLI服务,确保脚本按正确顺序注入到全局环境。
第二个问题:require引入后getInstance不是函数
这是因为你的legend.component.js原本是把单例挂在全局window上的,但用require导入时,它没有正确导出这个对象,导致你拿到的不是预期的LegendSingleton。
修复步骤:
修改legend.component.js,让它同时支持全局变量和CommonJS导出:
// 原来的单例定义不变 var LegendSingleton = { createInstance: function() { // 你的原有逻辑 }, getInstance: function() { // 你的原有逻辑 } }; // 新增:同时兼容全局和require导入 if (typeof module !== 'undefined' && module.exports) { module.exports = LegendSingleton; // 给require用 } else { window.LegendSingleton = LegendSingleton; // 保持全局可用 }
然后在main.component.js里,用require导入时就能拿到正确的对象了:
// 正确导入LegendSingleton const LegendSingleton = require('./legend.component.js'); // 继续你的原有逻辑创建myExtObject var myExtObject = { legendInstance: LegendSingleton.getInstance() }; // 同样把myExtObject也导出,方便Angular组件用 if (typeof module !== 'undefined' && module.exports) { module.exports.myExtObject = myExtObject; } else { window.myExtObject = myExtObject; }
在TypeScript组件里的正确用法
到了layoutindicateur.component.ts,因为是TypeScript,推荐两种方式:
方式1:声明全局变量(更贴合原有逻辑)
在组件顶部声明全局变量的类型,避免TypeScript报错:
// 声明全局变量类型 declare var myExtObject: any; export class LayoutindicateurComponent { ngOnInit() { // 直接使用myExtObject console.log(myExtObject.legendInstance); } }
方式2:用require导入(更符合模块规范)
直接从main.component.js导入:
const { myExtObject } = require('../path/to/main.component.js'); export class LayoutindicateurComponent { ngOnInit() { console.log(myExtObject.legendInstance); } }
额外建议
因为你最终要升级到Angular9,建议后续逐步把这些纯JS文件转为TypeScript组件,比如把legend.component.js改成legend.service.ts,用Angular的服务来实现单例(Angular的服务默认就是单例模式),这样后续升级会更顺畅,也能利用TypeScript的类型检查优势。
内容的提问来源于stack exchange,提问作者Ayoub Beltarchi

