起因
看到项目中很多svg,使用方法都是使用img标签引入。于是就想将svg合并,像字体图标那样方便使用。
解决方案
在网上了解到可以将众多svg文件合并成一个,用symbol+id的方式区分不同的svg图案,然后使用use 标签引用。
<svg>
<use xlink:href="#id"></use>
</svg>
在 https://icomoon.io/app/#/select shang合成了几个图标,测试了下,果然可以,还可以在svg标签通过fill样式改变svg的颜色。
去看了下兼容性:https://developer.mozilla.org…
基础功能的兼容性没问题,但是通过URI引用的功能不兼容IE。也就是说,要想兼容ie,就必须要把合成的svg文件的内容编码在项目文件中(可复用)。
改进:使用方式手动合成svg的方式肯定是不行的,可以使用nodejs脚本或是webpack去自动合成svg,然后导入项目的index.html文件中。svg和use标签可以封装成一个组件,便于使用。
实现
合并svg
执行方式
合并和导入svg放在项目的编译过程中去,由于项目使用的angular框架,而angular的编译配置是封装好的。在angular6 版本废弃了ng ejec命令,不再支持自定义webpack,而angular.json中的未提供自定义webpack或是执行外挂nodejs脚本的配置。
就在快要放弃自定义webpack配置,转而使用单独的nodejs脚本去合并svg的时候,在google上搜索到了ngx-build-plus这个ng-cli的插件。安装上这个包后,ng build或是ng serve的时候,使用 –extra-webpack-config参数可以指定一个webpack配置文件,可以去https://github.com/manfredste… 看下具体使用方法和说明。
合并方式
去github上找了几种svg sprite的loader和plugin,要么是不满足要求,要么是不适合angular。我想要的是把指定目录下的svg图标合并成一个文件,然后再将内容导入到编译出的index.html中。类似svg-sprite-loader这种是检测import到js中的svg进行合并,在angular中行不通。svg-sprite-html-webpack插件倒是符合要求,但是它需要依赖html-webpack-plugin插件,这样会影响angular-cli自身的配置,如果使用了这个插件,类似–baseHref这样改变最终index.html的内容的编译参数就无法使用了。
最后决定自己实现一个插件,用来合并导出svg。
编写插件
在github上找到svg-sprite库,用来合并svg。在webpack emit的时候通过重写compilation.assets[‘index.html’]的source和size方法将合并的内容导入index.html中。实现代码:https://github.com/llycc/svg-…
注意事项
安装ngx-build-plus时要使用ng add ngx-build-plus命令,这样做ng会帮你修改angular.json中编译选项,否则需要手动修改angular.json中build和serve的builder,具体可参考本项目angular.json文件。可以去https://github.com/manfredste… 了解更多信息