效果展示
react项目中使用
使用antd图标
在线收藏iconfont图标
使用刚收藏的图标
使用本地刚生成的图标
修改icon样式
vue项目中使用
使用文档
安装
在vscode应用市场中搜索iconfont-helper,作者是dbfu321,然后安装。或者到这个地址在线安装,marketplace.visualstudio.com/items?itemN…
登录iconfont
进入这个地址,然后注册或登录账号。
收藏图标
找到自己想用的图标,然后收藏。
使用F12打开开发者控制台,在network中随便找一个接口,右键复制cookie。然后在vscode设置中搜索iconfont.cookie
,把刚复制的cookie放进去。
安装依赖
因为项目中使用了antd icons组件,所以需要先安装依赖才能使用。react项目安装@ant-design/icons
依赖,vue项目安装@ant-design/icons-vue
依赖。
设置alias
因为自动导入的时候,需要使用绝对路径,所以建议大家设置alias,把@
指向src
目录。插件也支持自定义目录,在设置中搜索iconfont.importPath,然后改成自己想要的。
修改存放icon的目录
默认是放在src/assets/icons
目录下,这个可以自己去改。在vscode设置中搜索iconfont.dirPath
,然后改成自己想要的。
使用
在你需要使用icon的地方,右键(插入iconfont图标)或使用快捷键(cmd+shift+i)打开图标预览页面,然后选中一个,就行了。
说明
以前我在项目里,使用的是Symbol
方案(不清楚这个方案的,可以看下iconfont的帮助文档),这个方案iconfont也支持,用起来也简单,但是这种方案有个致命缺点,没办法做按需加载,所有的图标都放在一个文件里,还必须在项目渲染前加载,随着项目越来越大,图标越来越多,图标文件已经1M多了,用户网速慢的情况下,首屏加载时间特别长,严重影响用户体验。所以这段时间在想办法优化,然后决定用现在这个方案,把svg做成一个个组件,然后根据路由按需加载,写这个插件是为了提高使用图标的效率。
项目真实截图,文件很大,加载时间也比较长。
插件实现思路
- 调用iconfont接口,查询收藏的图标和项目图标。
- 根据接口返回的svg信息,使用vscode的webview动态渲染svg。
- 选中一个图标后把svg信息传给vscode,根据类型执行不同的操作。
- 如果是本地图标,直接在当前文件头部导入并在当前位置插入图标组件。
- 如果是iconfont项目图标或收藏的图标,首先检查本地是否已经存在,不存在则根据svg组件模版创建到本地。如果svg存在,用户可以选择是否使用本地的,或改个名字保存到本地并使用。
- 如果是antd图标则在当前文件位置插入图标组件,然后从antd icons库中引入当前图标组件。
项目难点
通过上面的效果展示,大家应该看到了一个功能,在vscode webview中展示本地图标,这个功能难点是怎么把react组件转换成html。
本地icon组件截图
我的方案是:
- 使用正则表达式把svg内容给取出来
- 使用babel把jsx转换成 React.createElement
- 动态执行组件代码,获取组件
- 使用react-dom/server服务端渲染方法把组件转换成html
// 读取本地组件内容
const fileContent = data.toString('utf8');
// 根据正则表达式获取svg内容
let [svgContent] = fileContent.replace(/\n/g, '').match(/<svg (.+?)>(.+?)<\/svg>/g) || [];
// 把jsx转换成react.createElmennt
const result = babel.transform(`${svgContent}`, { presets: [react] });
// 动态执行组件代码,获取组件
const func = new Function('React', `return ${result?.code || ''}`);
const component = func(React);
// 使用服务端渲染,把组件渲染成html
svgContent = renderToString(component);
总结
开发中,我们应该多思考怎么借助工具或脚本来提高自己的开发效率,让自己有更多的时间学习(摸鱼)。本人平时比较喜欢写一些插件或脚本来帮助自己工作,后面我会陆陆续续把自己平时写的小插件或脚本整理成文章发布出来,如果这个插件对你有用,就给个赞吧,谢谢。
插件仓库地址:github.com/dbfu/iconfo…