Next.js11中next/image组件IE11下无法显示报错如何解决?
问题根因
- Next 11自带的
next/image组件原生不支持IE11,依赖IE11不存在的Intersection ObserverAPI实现懒加载逻辑 - 你遇到的SCRIPT5022: Should not already be working报错是
@webcomponents/shadydom和polyfill的加载顺序冲突导致的 next/image默认输出的loading="lazy"属性、srcset自动处理逻辑在IE11下无兼容支持,组件逻辑跑挂后会出现图片宽高被设为0无法显示的问题
解决方案
1. 补全polyfill并调整加载顺序
首先安装缺失的依赖:
npm install intersection-observer next-transpile-modules --save
在项目入口pages/_app.tsx的最顶部按顺序引入polyfill,必须保证所有polyfill在shadydom之前加载:
// 以下三个导入必须放在所有代码最顶部 import 'react-app-polyfill/ie11'; import 'react-app-polyfill/stable'; import 'intersection-observer'; // 再导入shadydom和其他业务依赖 import '@webcomponents/shadydom'; // 其他原有导入...
2. 配置next转译node_modules依赖
Next默认不会转译node_modules内的代码,需要配置next-transpile-modules把next/image转为ES5兼容语法,修改next.config.js:
const withTM = require('next-transpile-modules')(['next/image']); module.exports = withTM({ // 保留你的其他原有配置 });
3. 改造封装的Image组件做IE11降级
IE11下直接渲染原生img标签避开兼容问题,现代浏览器仍保留next/image的优化能力,修改后的组件代码:
import { getMyMedia } from "@utils/medias" import NextImage from "next/image" // 检测是否为IE11环境 const isIE11 = typeof window !== 'undefined' && /Trident\/7\.0/.test(window.navigator.userAgent); const Image = ({img,...props})=>{ const media = img const imgUrl = getMyMedia(media.url) // IE11直接降级用原生img if (isIE11) { return <img src={imgUrl} alt={media.alternativeText || ""} {...props} style={{ maxWidth: '100%', ...props.style }} /> } const loader = ({ src }) => { return getMyMedia(src) } // 固定宽高场景 if (props.width && props.height) { return ( <NextImage loader={loader} src={media.url} alt={media.alternativeText || ""} loading="eager" unoptimized={true} {...props} /> ) } // 响应式场景 return ( <NextImage loader={loader} layout="responsive" width={media.width} height={media.height} objectFit="contain" src={media.url} alt={media.alternativeText || ""} loading="eager" unoptimized={true} /> ) } export default Image
配置说明:
unoptimized={true}关掉Next自动图片裁剪、格式转换逻辑,避免输出IE11不支持的WebP等格式loading="eager"关掉懒加载,避开Intersection Observer的兼容风险
内容的提问来源于stack exchange,提问作者lin Duan
相关产品推荐
相关产品推荐

