Next.js中使用JS文件生成内联脚本及第三方脚本相关问题处理
hydration报错与脚本不执行修复
该异常是服务端渲染输出的<script>结构与客户端hydration预期不匹配导致,优先使用Next.js官方Script组件解决,配置strategy="beforeInteractive"可保证脚本在第三方脚本加载前执行,完全符合全局变量预定义的要求:
import Script from 'next/script' export default function Page({ pageProps }) { return ( <> {/* 内联全局配置,必须加唯一id避免hydration异常 */} <Script id="global-config" strategy="beforeInteractive" dangerouslySetInnerHTML={{ __html: `window.config = ${JSON.stringify(pageProps.config)}; window.varforthem = '自定义值'` }} /> <Script src="/scripts/myfile.js" strategy="beforeInteractive" /> <Script src={pageProps.config.third_party_script_url} strategy="beforeInteractive" /> </> ) }
如果坚持使用原生<script>标签,给标签添加suppressHydrationWarning={true}属性关闭hydration校验即可解决报错。
脚本静态资源优化方案
如果不希望将脚本放在public目录,可通过webpack配置将自定义脚本打包到_next/static目录,享受内置的哈希命名、压缩优化和默认缓存策略:
// next.config.js const path = require('path') module.exports = { webpack: (config, { isServer }) => { if (!isServer) { config.module.rules.push({ test: /\.js$/, include: path.resolve(__dirname, 'src/scripts'), type: 'asset/resource', generator: { filename: 'static/scripts/[name].[contenthash].js' } }) } return config } }
页面中直接导入脚本路径使用即可:
import myScriptPath from '@/scripts/myfile.js' <Script src={myScriptPath} strategy="beforeInteractive" />
public目录脚本自定义缓存头
如果继续使用public目录存放脚本,可在next.config.js中配置响应头规则修改max-age:
// next.config.js module.exports = { async headers() { return [ { source: '/scripts/:path*', headers: [ { key: 'Cache-Control', value: 'public, max-age=31536000, immutable' } ] } ] } }
上述配置会给public/scripts下所有资源设置1年缓存周期,支持CDN正常缓存。
内联脚本可读性与eslint兼容优化
如果内联脚本逻辑复杂,可将逻辑抽离为单独的JS文件,构建时通过raw-loader导入文件内容注入到dangerouslySetInnerHTML中,即可正常享受eslint校验、代码高亮等能力。
内容的提问来源于stack exchange,提问作者Dave Stein
相关产品推荐
相关产品推荐

