Angular 17 SSR项目引入flag-icons库遇文件路径冲突问题求助
问题描述
运行ng serve时出现以下构建错误:
✘ [ERROR] Two output files share the same path but have different contents: media/sh-ta.svg
✘ [ERROR] Two output files share the same path but have different contents: media/un.svg
✘ [ERROR] Two output files share the same path but have different contents: media/xk.svg
原因是flag-icons库在node_modules/flag-icons/flags下包含1x1和4x3两个文件夹,其中的SVG文件同名,Angular构建时会将它们都输出到media/目录,导致路径冲突。
最小复现步骤
$ ng version Angular CLI: 17.3.8 Node: 20.11.1 Package Manager: npm 10.2.4 $ ng new test --ssr --no-standalone $ cd test $ npm install flag-icons
修改angular.json,在build和serve配置的styles数组中添加flag-icons的CSS:
"styles": [ "src/styles.css", "flag-icons/css/flag-icons.min.css" ]
在app.component.html中添加图标:
<span class="fi fi-gr"></span>
执行ng serve即可触发错误。
解决方案(无需修改flag-icons库)
方案1:配置Angular资产映射,拆分输出路径
在angular.json的assets数组中,分别为1x1和4x3的SVG文件配置不同的输出目录,避免路径重叠:
"assets": [ "src/favicon.ico", "src/assets", { "glob": "**/*.svg", "input": "./node_modules/flag-icons/flags/1x1", "output": "media/1x1/" }, { "glob": "**/*.svg", "input": "./node_modules/flag-icons/flags/4x3", "output": "media/4x3/" } ]
之后需要覆盖flag-icons默认的CSS背景路径,在src/styles.css中添加:
/* 全局使用4x3尺寸的图标 */ .fi { background-image: url('../media/4x3/{{country-code}}.svg') !important; } /* 如果需要使用1x1尺寸,添加单独的类 */ .fi.fi-1x1 { background-image: url('../media/1x1/{{country-code}}.svg') !important; }
注意将{{country-code}}替换为实际使用的国家代码,或者针对单个图标单独配置,例如:
.fi-gr { background-image: url('../media/4x3/gr.svg') !important; }
方案2:使用CDN版本替代本地安装
直接移除本地的flag-icons依赖,在src/index.html中引入CDN提供的CSS文件:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css">
CDN版本的资源已经处理了文件路径问题,无需担心本地构建冲突,同时还能减少项目依赖体积。
方案3:自定义Webpack配置修改资源输出规则
- 安装自定义Webpack构建工具:
npm install @angular-builders/custom-webpack --save-dev
- 修改
angular.json,将build、serve、server的builder替换为自定义Webpack版本:
"architect": { "build": { "builder": "@angular-builders/custom-webpack:browser", "options": { "customWebpackConfig": { "path": "./webpack.config.js" }, // 保留原有其他配置 } }, "serve": { "builder": "@angular-builders/custom-webpack:dev-server", // 保留原有其他配置 }, "server": { "builder": "@angular-builders/custom-webpack:server", "options": { "customWebpackConfig": { "path": "./webpack.config.js" }, // 保留原有其他配置 } } }
- 在项目根目录创建
webpack.config.js,配置SVG资源的输出路径规则:
const path = require('path'); module.exports = { module: { rules: [ { test: /\.svg$/, type: 'asset/resource', generator: { filename: (pathData) => { const relativePath = path.relative('./node_modules/flag-icons/flags', pathData.filename); return `media/${relativePath}`; } } } ] } };
该配置会保留原有的1x1/和4x3/目录结构,将SVG输出到media/1x1/和media/4x3/下,自动避免路径冲突。同时无需手动修改CSS,Webpack会自动处理CSS中的url()引用,替换为正确的输出路径。
内容的提问来源于stack exchange,提问作者Murmulodi

