Angular 16项目无法引入TS编译的ESNext自定义元素问题
问题描述
我们通过TypeScript文件(RoleSelector.ts)实现了基于HTMLElement的自定义元素,编译后生成私有NPM包,包含RoleSelector.js和RoleSelector.d.ts,其tsconfig.json配置为"target": "ES6", "module": "ESNext"。
代码实现如下:
export class RoleSelector extends HTMLElement { // 渲染shadowElement的类实现 constructor() { super(); // 附加shadow root以封装自定义元素的样式和DOM树 this.shadow = this.attachShadow({ mode: 'open' }); // 初始渲染 this.shadow.innerHTML = <HTML-TEMPLATE-HERE>; } // 定义自定义元素 customElements.define('tenant-role-selector', TenantRoleSelector);
在Angular 16项目中引入该NPM包时,启动项目出现运行时错误:
Uncaught syntaxerror unexpected token 'export' (at.
请问需要修改消费端Angular应用配置,还是调整TS编译方式?
解决方案
核心原因
该错误源于编译后的ESNext模块语法未被Angular构建流程正确转译,浏览器无法直接识别顶级export语法。优先调整TS编译方式让包具备更好的兼容性,其次再考虑修改Angular配置。
方案一:调整TS编译方式(推荐)
修改自定义元素包的编译配置,输出Angular易处理的模块格式:
- 修改包的
tsconfig.json,将module替换为ES2020(兼顾兼容性和现代模块特性):{ "compilerOptions": { "target": "ES6", "module": "ES2020", "declaration": true, "outDir": "./dist", "strict": true } } - 在包的
package.json中补充模块入口声明,帮助Angular正确识别:{ "main": "./dist/RoleSelector.js", "module": "./dist/RoleSelector.js", "types": "./dist/RoleSelector.d.ts" } - 重新编译并发布私有包。
方案二:修改Angular应用配置
若无法调整包的编译配置,可在Angular项目中配置转译规则:
- 打开项目的
angular.json,在build配置的options中添加允许转译私有包的规则:{ "projects": { "你的项目名": { "architect": { "build": { "options": { "allowedCommonJsDependencies": ["你的私有包名称"] } } } } } } - 确保项目
tsconfig.json的模块配置与包兼容:{ "compilerOptions": { "module": "ESNext", "target": "ES2020" } } - 重启Angular开发服务。
额外注意点
- 代码存在命名错误:类名是
RoleSelector,但customElements.define中使用的是TenantRoleSelector,需修正为一致的类名。 - Angular项目中需在模块的
schemas数组中添加CUSTOM_ELEMENTS_SCHEMA,允许使用自定义元素;或在main.ts中确保自定义元素的定义代码被执行。
内容的提问来源于stack exchange,提问作者Acc_Milind
相关产品推荐
相关产品推荐

