如何在Nuxt SSR项目中配置plotly.js并解决self is not defined报错
问题根因
self is not defined报错的核心原因是plotly.js依赖浏览器全局对象self,而Nuxt SSR阶段运行在Node.js环境,不存在该全局对象,只要服务端加载到plotly.js相关代码就会触发报错,和webpack版本没有直接关联。
解决方案
按以下步骤逐一调整即可解决:
- 第一步:调整插件命名规则
将你编写的plotly插件文件重命名为plotly.client.js(存放在nuxt项目的plugins/目录下),Nuxt会自动识别.client.js后缀的插件,仅在客户端环境加载执行,避免服务端加载到plotly代码。
插件代码不需要修改,保持如下即可:// here we use custom partial bundle import plotly from 'plotly.js/lib/core'; import barpolar from 'plotly.js/lib/barpolar'; export default function (_, inject) { plotly.register([barpolar]); inject('plotly', plotly); } - 第二步:修正webpack配置
你当前的webpack配置没有区分客户端/服务端,需要将ify-loader相关逻辑仅在客户端构建时生效,调整nuxt.config.js的build配置如下:
额外添加build: { extend(config, { isClient }) { // 仅客户端构建时添加plotly相关loader if (isClient) { config.module.rules.push({ test: /\.js$/, include: /node_modules\/plotly\.js/, use: [ 'ify-loader', 'transform-loader?plotly.js/tasks/compress_attributes.js', ], }); } }, }include: /node_modules\/plotly\.js/规则可以缩小loader的处理范围,提升构建速度。 - 第三步:调整调用逻辑
- 不要在服务端执行的生命周期(如asyncData、fetch、setup函数的服务端执行阶段)调用
$plotly相关方法 - 渲染plotly图表的容器组件外层包裹
<client-only>标签,避免服务端渲染和客户端hydration不匹配:
调用plotly渲染方法建议放在<template> <client-only> <div ref="plotContainer"></div> </client-only> </template>onMounted生命周期中执行,确保此时已经是客户端环境。 - 不要在服务端执行的生命周期(如asyncData、fetch、setup函数的服务端执行阶段)调用
验证方案
完成以上调整后重启项目,即可正常加载plotly.js,不会再触发self is not defined报错。
内容的提问来源于stack exchange,提问作者Perp
相关产品推荐
相关产品推荐

