Nuxt.js如何避免SSR时导入仅兼容浏览器的脚本?
解决Nuxt.js中SSR排除浏览器专属NPM包的问题
问题核心:你用的import是静态编译语句,不管代码里的process.client条件判断,编译阶段就会加载那个依赖包,SSR环境没有浏览器的document/window对象,直接触发报错。下面是几种可行的解决方式:
1. 动态导入(最直接的组件内解决方案)
把静态import改成动态import,放在process.client的判断逻辑里,这样只有客户端环境才会加载并执行这个包:
export default async function showThing() { if (process.client) { // 动态导入,仅客户端执行 const { default: thing } = await import('@vendor/thing'); thing(); } }
动态import是运行时执行的,完全避开SSR阶段的加载逻辑。
2. 客户端专属插件(适合全局复用的场景)
如果这个包需要在多个组件里用,推荐把它做成Nuxt的客户端专属插件:
- 在项目的
plugins文件夹下新建thing.client.js(文件名带.client后缀是关键,Nuxt会自动识别为仅客户端加载):
import thing from '@vendor/thing'; // 可以把包挂载到window全局,方便组件调用 window.thing = thing; // 或者如果是Vue2,也可以挂载到Vue原型:Vue.prototype.$thing = thing
- 在
nuxt.config.js里注册这个插件:
export default { plugins: [ '~/plugins/thing.client.js' ] }
之后在组件里使用时,只要确保在客户端逻辑里调用就行(比如mounted钩子,或者加process.client判断):
export default { mounted() { window.thing(); } }
3. Nuxt3专属方案(用Vue3生命周期钩子)
如果是Nuxt3项目,直接用onMounted钩子(仅客户端执行)配合动态导入:
import { onMounted } from 'vue'; export default { setup() { onMounted(async () => { const { default: thing } = await import('@vendor/thing'); thing(); }); } }
onMounted本身就是客户端才会触发的生命周期,不需要额外加process.client判断。
内容的提问来源于stack exchange,提问作者d-_-b
相关产品推荐
相关产品推荐

