如何实现@rct/icons包中图标的单独子路径导出与导入?
实现@rct/icons的单个图标独立导入方案
要让@rct/icons支持@rct/icons/LikeFilled这类子路径导入方式,需要从构建配置和包入口映射两方面调整,以下是具体步骤:
1. 调整Rollup打包配置
修改rollup.config.js,让每个图标组件单独打包为独立模块,同时保留全量导出的入口:
import fs from 'fs'; import path from 'path'; import resolve from '@rollup/plugin-node-resolve'; import babel from '@rollup/plugin-babel'; import { terser } from 'rollup-plugin-terser'; // 自动读取src目录下的所有图标组件(排除index.js) const iconEntries = fs.readdirSync('./src') .filter(file => file.endsWith('.js') && file !== 'index.js') .map(file => path.basename(file, '.js')); export default [ // 保留全量导出的打包配置(兼容原有导入方式) { input: 'src/index.js', output: [ { file: 'dist/index.js', format: 'esm', sourcemap: true }, { file: 'dist/index.cjs', format: 'cjs', sourcemap: true } ], plugins: [ resolve(), babel({ babelHelpers: 'bundled', presets: ['@babel/preset-react'] }), terser() ] }, // 单独打包每个图标组件 ...iconEntries.map(iconName => ({ input: `src/${iconName}.js`, output: [ { file: `dist/${iconName}.js`, format: 'esm', sourcemap: true }, { file: `dist/${iconName}.cjs`, format: 'cjs', sourcemap: true } ], plugins: [ resolve(), babel({ babelHelpers: 'bundled', presets: ['@babel/preset-react'] }), terser() ] })) ];
2. 修改package.json的入口映射
添加exports字段,定义包的子路径规则,让工具链能正确解析@rct/icons/*这类导入:
{ "name": "@rct/icons", "version": "1.0.0", "type": "module", "main": "./dist/index.cjs", "module": "./dist/index.js", "exports": { ".": { "import": "./dist/index.js", "require": "./dist/index.cjs" }, "./*": { "import": "./dist/*.js", "require": "./dist/*.cjs" } }, "scripts": { "prebuild": "rimraf src && rimraf dist", "build": "npm run svgr && rollup -c", "svgr": "svgr --icon --title-prop --replace-attr-values '#1D1D1D=currentColor' -d src -- assets" }, "devDependencies": { "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-node-resolve": "^15.0.1", "@babel/preset-react": "^7.22.5", "rollup": "^3.26.3", "rollup-plugin-terser": "^7.0.2", "rimraf": "^5.0.1", "@svgr/cli": "^8.0.1" } }
3. 支持解构式单个导入(可选)
如果需要让消费者用import { LikeFilled } from '@rct/icons/LikeFilled';这种解构语法,需要修改SVGR生成的组件导出规则:
- 创建自定义模板文件
svgr-template.js:
export default (code, config) => { const componentName = config.componentName; return ` import * as React from 'react'; ${code} export default ${componentName}; export { ${componentName} }; `; };
- 修改package.json中的svgr命令,引入模板:
"svgr": "svgr --icon --title-prop --replace-attr-values '#1D1D1D=currentColor' --template ./svgr-template.js -d src -- assets"
4. 验证效果
执行npm run build后,dist目录会生成每个图标对应的独立文件,消费者即可两种方式导入:
- 全量导入(原有方式):
import { LikeFilled, HeartFilled } from '@rct/icons';
- 单个图标导入:
// 默认导入(推荐) import LikeFilled from '@rct/icons/LikeFilled'; // 解构导入(需完成步骤3) import { LikeFilled } from '@rct/icons/LikeFilled';
内容的提问来源于stack exchange,提问作者Onera
相关产品推荐
相关产品推荐

