React中使用node-sass引用public文件夹静态图片编译报错怎么办
React 项目 node-sass 引用 public 目录静态图编译报错解决方案
报错原因
Create React App 默认的 webpack 配置会自动解析 sass/css 中 url() 引入的资源,默认会以当前 sass 文件所在的 src 目录为根路径查找模块。你写的 /images/icon.png 被 webpack 识别为待解析的模块路径,又因为 src 目录下不存在对应文件,就会抛出模块找不到的错误。
可行解决方案
方案1:使用
PUBLIC_URL标识引用(官方推荐,零配置)
CRA 内置了%PUBLIC_URL%全局变量,编译时会自动替换为 public 目录对应的站点绝对路径,只要在路径前加上这个标识和~前缀,就能跳过 src 目录的模块查找逻辑,直接指向 public 下的资源,写法如下:background-image: url(~'%PUBLIC_URL%/images/icon.png');这个写法本地开发、生产构建都能正常生效,不需要修改任何构建配置。
方案2:配置构建规则跳过指定路径解析(适合大量引用 public 资源的场景)
如果项目里有大量 public 静态资源要在 sass 里引用,不想每次都加前缀,可以修改 webpack 配置,让 css-loader 不对指定前缀的路径做模块解析:- 未 eject 的 CRA 项目,可以借助 craco 或 react-app-rewired 覆盖配置,以 craco 为例,在项目根目录的
craco.config.js中添加如下配置:module.exports = { webpack: { configure: (config) => { const rules = config.module.rules.find(rule => Array.isArray(rule.oneOf))?.oneOf || []; rules.forEach(rule => { (rule.use || []).forEach(useItem => { if (useItem.loader?.includes('css-loader')) { useItem.options = { ...useItem.options, url: { filter: (urlPath) => { // 所有/public下/images开头的路径跳过解析 if (urlPath.startsWith('/images/')) return false; return true; } } } } }) }) return config } } } - 已经 eject 的项目,直接找到
config/webpack.config.js里的 css-loader 配置项,添加上面的 url 过滤规则即可。
配置完成后,原本写的background-image: url("/images/icon.png");就能正常编译,不会再报模块找不到的错误。
- 未 eject 的 CRA 项目,可以借助 craco 或 react-app-rewired 覆盖配置,以 craco 为例,在项目根目录的
注意:不要用相对路径跨目录引用public下的资源(比如写
../../public/images/icon.png),这种写法在开发环境可能偶然生效,但生产构建时webpack不会把对应资源拷贝到产物目录,上线后会出现资源404问题。
内容的提问来源于stack exchange,提问作者Abraham
相关产品推荐
相关产品推荐

