Analog SSR 中如何正确引入第三方 JS 库?

思佳 Dev 阅读 8

我在用 Analog 做一个 SSR 项目,想引入一个非模块化的第三方 JS 库(比如某个图表插件),但直接在组件里 import 报错说 window 未定义。

试过在 onClient 里动态加载,但页面首次渲染还是空白。有没有标准做法?比如在 app.config.ts 里配置 externals 或者用 provideClientHydration 之类的?

目前临时方案是这样写的:

import { onClient } from '@analogjs/router';

onClient(() => {
  const script = document.createElement('script');
  script.src = '/assets/my-lib.js';
  document.head.appendChild(script);
});

但感觉很 hack,而且 SEO 完全没内容。官方推荐怎么处理这类依赖?

我来解答 赞 9 收藏
二维码
手机扫码查看
1 条解答
♫红爱
♫红爱 Lv1
对于 SSR 项目引入非模块化的第三方库确实有点麻烦。你的临时方案有一定道理,但确实对SEO不友好。这里有个更标准的处理方式。

首先在 app.config.ts 里配置 externals 是个不错的选择。把需要的库加到 externals 列表中,这样构建时就不会打包进 bundle 了。注意安全,在生产环境最好用 CDN 加载这些外部资源。


export const config: AppConfig = {
externals: ['my-chart-lib']
};


然后在客户端渲染时动态加载这个库:


import { onClient } from '@analogjs/router';

onClient(() => {
if (!window['MyChartLib']) {
const script = document.createElement('script');
script.src = 'https://cdn.example.com/my-lib.js';
document.head.appendChild(script);
script.onload = () => renderCharts();
} else {
renderCharts();
}
});

function renderCharts() {
// 这里可以安全使用图表库了
}


记得给 script 标签加上 async 或 defer 属性,避免阻塞页面渲染。还有就是考虑一下加载失败的情况,最好加个重试机制或者降级方案。

另外别忘了在服务端也要做些兼容处理,避免直接访问 window 对象报错。虽然折腾,但为了安全和性能值得花点心思。
点赞
2026-03-26 01:06