You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Angular创建可嵌入各类网站的JS Widget?

用Angular实现可嵌入第三方网站的JS Widget(无需iframe)

完全可以用Angular实现这类Widget,而且不需要依赖iframe就能实现全局调用(比如MyWidget.show())。下面是具体的实现步骤,帮你生成可直接引入的单JS文件:

1. 准备Angular项目与组件

  • 创建一个新的Angular项目(建议用Angular 14+,支持独立组件更方便)
  • 编写你的目标Widget组件,比如一个简单的聊天弹窗组件ChatWidgetComponent
  • 确保组件的样式做了隔离处理,比如使用ViewEncapsulation.ShadowDom,或者给所有样式类加专属前缀,避免和宿主网站样式冲突

2. 调整Angular构建配置

修改项目根目录下的angular.json,调整build配置,让Angular打包出单文件UMD格式的产物:

"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      "outputPath": "dist/widget",
      "index": "src/index.html",
      "main": "src/main.widget.ts", // 专门的Widget入口文件
      "polyfills": ["zone.js"],
      "tsConfig": "tsconfig.widget.json",
      "assets": [],
      "styles": ["src/styles.widget.css"],
      "scripts": [],
      "singleBundle": true, // 打包成单个文件
      "format": ["umd"], // 输出UMD格式,支持全局引入
      "outputHashing": "none" // 关闭哈希,方便文件名固定
    }
  }
}

同时创建对应的tsconfig.widget.json,配置编译目标为ES5或ES6,确保兼容性:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "target": "ES5",
    "module": "UMD",
    "declaration": false,
    "outDir": "./dist/widget"
  },
  "include": ["src/main.widget.ts", "src/app/chat-widget/**/*"]
}

3. 编写Widget入口逻辑(暴露全局方法)

创建src/main.widget.ts作为Widget的入口,在这里定义全局可调用的方法,比如MyWidget.show():

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { ChatWidgetComponent } from './app/chat-widget/chat-widget.component';
import { createCustomElement } from '@angular/elements';

platformBrowserDynamic().bootstrapModule(ChatWidgetComponent)
  .then((moduleRef) => {
    // 挂载全局对象到window
    (window as any).MyWidget = {
      show: () => {
        // 动态创建组件容器
        const container = document.createElement('div');
        container.classList.add('chat-widget-container');
        document.body.appendChild(container);
        // 渲染组件到容器
        moduleRef.instance.render(container);
        
        // 也可以用Angular Elements的方式,直接注册自定义标签
        // const ChatWidgetElement = createCustomElement(ChatWidgetComponent, { injector: moduleRef.injector });
        // customElements.define('chat-widget', ChatWidgetElement);
        // document.body.appendChild(document.createElement('chat-widget'));
      },
      hide: () => {
        // 实现隐藏逻辑
        const widget = document.querySelector('chat-widget') || document.querySelector('.chat-widget-container');
        widget?.remove();
      }
    };
  })
  .catch(err => console.error(err));

4. 构建并测试

  • 执行构建命令:ng build --configuration production
  • 构建完成后,dist/widget目录下会生成一个main.js(或你配置的文件名),这就是可嵌入的单JS文件
  • 在第三方网站中引入该脚本,然后调用MyWidget.show()即可渲染组件:
<script src="path/to/your/widget/main.js"></script>
<button onclick="MyWidget.show()">打开聊天组件</button>

关键注意事项

  • 样式隔离:推荐使用ViewEncapsulation.ShadowDom让组件样式完全隔离,不会影响宿主网站
  • 兼容性:如果需要兼容旧浏览器,记得添加必要的polyfill(比如@webcomponents/webcomponentsjs)
  • 性能优化:可以开启Tree Shaking,移除Angular的冗余代码,减小打包体积

内容的提问来源于stack exchange,提问作者Gregory Boutte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:39:19