Angular 18 SSR环境下如何客户端动态加载igv.js模块?
Angular 18 SSR 下正确动态加载 igv.js 的方法
igv.js 依赖浏览器环境(window、document 等对象),在 Angular SSR 模式下直接静态导入会导致服务器端渲染报错,必须仅在客户端环境中动态加载。你遇到的 TypeError: igv.createBrowser is not a function 通常是因为动态导入时未正确获取 igv 的导出对象,以下是两种可行的解决方案:
方案一:使用 npm 包动态导入(推荐)
通过 Angular 的平台判断工具,仅在客户端动态导入 igv.js,并注意获取其默认导出对象:
1. 安装依赖
npm install igv
2. 组件代码实现
在组件中使用 isPlatformBrowser 确保仅在客户端执行加载逻辑,且在视图初始化完成后(ngAfterViewInit)操作 DOM:
import { Component, AfterViewInit, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Component({ selector: 'app-igv-browser', templateUrl: './igv-browser.component.html', styleUrls: ['./igv-browser.component.css'] }) export class IgvBrowserComponent implements AfterViewInit { constructor(@Inject(PLATFORM_ID) private platformId: Object) {} async ngAfterViewInit() { // 仅在浏览器环境执行 if (isPlatformBrowser(this.platformId)) { // 动态导入igv.js,获取默认导出 const igv = (await import('igv')).default; // 获取DOM容器(确保视图已渲染完成,容器存在) const container = document.getElementById('igv-container'); if (container) { // 初始化igv浏览器 const browser = await igv.createBrowser(container, { genome: 'hg19', locus: 'chr1:1-100000' // 其他配置项根据需求添加 }); // 可在此处对browser进行后续操作 } } } }
3. 模板代码
<div id="igv-container" style="height: 600px; width: 100%;"></div>
方案二:动态加载脚本标签
如果不想通过 npm 管理依赖,可直接在客户端动态创建 script 标签加载 igv.js 的 CDN 或本地文件:
import { Component, AfterViewInit, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Component({ selector: 'app-igv-browser', templateUrl: './igv-browser.component.html', styleUrls: ['./igv-browser.component.css'] }) export class IgvBrowserComponent implements AfterViewInit { constructor(@Inject(PLATFORM_ID) private platformId: Object) {} async ngAfterViewInit() { if (isPlatformBrowser(this.platformId)) { // 先加载igv脚本 await this.loadIgvScript(); const container = document.getElementById('igv-container'); // 脚本加载完成后,window.igv全局对象可用 if (container && window.igv) { const browser = await window.igv.createBrowser(container, { genome: 'hg19', locus: 'chr1:1-100000' }); } } } // 封装脚本加载逻辑 private loadIgvScript(): Promise<void> { return new Promise((resolve, reject) => { const script = document.createElement('script'); // 替换为你需要的版本或本地文件路径 script.src = 'https://cdn.jsdelivr.net/npm/igv@2.17.3/dist/igv.min.js'; script.onload = () => resolve(); script.onerror = (err) => reject(err); document.body.appendChild(script); }); } }
错误原因说明
之前出现 createBrowser is not a function,是因为 igv.js 的 npm 包采用默认导出,直接使用 import * as igv 得到的是包含 default 属性的模块对象,而非 igv 本身,因此需要通过 .default 获取实际的 igv 实例。
内容的提问来源于stack exchange,提问作者Kim
相关产品推荐
相关产品推荐

