当前位置: 首页 > news >正文

@ant-design/icons-vue 打包成多格式库

@ant-design/icons-vue 打包成多格式库

以下是完整的配置方案,将 @ant-design/icons-vue 打包成 UMD、ESM、CJS、AMD、IIFE 格式的
开发版和生产版。

📁 项目结构

project/
├── vite.config.advanced.js    # Vite 高级配置(位于根目录)
├── build.js                   # 自定义构建脚本(位于根目录或 scripts/ 目录)
├── src/
│   └── index.js         # 主入口文件
├── dist/               # 输出目录
│   ├── dev/           # 开发版(无压缩)
│   └── prod/          # 生产版(压缩,含 .min)
├── vite.config.js     # Vite 配置
└── package.json

📄 入口文件 (src/index.js)

// src/index.js - 主入口文件
// 重新导出 @ant-design/icons-vue 的所有内容// 具名导出所有图标
export * from '@ant-design/icons-vue'// 默认导出所有图标
import * as icons from '@ant-design/icons-vue'export default icons// 为 CommonJS 环境提供兼容导出
if (typeof module !== 'undefined' && module.exports) {module.exports = iconsmodule.exports.default = icons
}// 版本信息
export const version = '__VERSION__'

⚙️ Vite 配置 (vite.config.js)

import {defineConfig} from 'vite'
import {resolve} from 'path'
import {readFileSync} from 'fs'// 读取 package.json
const packageJson = JSON.parse(readFileSync('./package.json', 'utf-8'))export default defineConfig(({command, mode}) => {const isDev = mode === 'development'const isBuild = command === 'build'const outDir = `dist/${isDev ? 'dev' : 'prod'}`return {build: {outDir,sourcemap: isDev ? true : false,minify: isDev ? false : 'terser',lib: {entry: resolve(__dirname, 'src/index.js'),name: 'AntDesignIconsVue',fileName: (format) => {const formatMap = {es: 'esm',cjs: 'cjs',umd: 'umd',amd: 'amd',iife: 'iife'}// 生产版添加 .min 后缀const minSuffix = isDev ? '' : '.min'return `ant-design-icons-vue.${formatMap[format] || format}${minSuffix}.js`},formats: ['es', 'cjs', 'umd', 'amd', 'iife']},rollupOptions: {// 外部化 Vue 和 @ant-design/icons-vue,不打包进库external: ['vue'],output: {globals: {'vue': 'Vue','@ant-design/icons-vue': 'AntDesignIconsVue'},exports: 'named',interop: 'auto',// AMD 配置amd: {id: packageJson.name || 'ant-design-icons-vue'},// UMD 配置banner: `/*! ${packageJson.name} v${packageJson.version} - ${isDev ? 'Development' : 'Production'} */`,// 开发模式不压缩compact: !isDev,// 生产版使用更严格的压缩...(isDev ? {} : {compact: true,generatedCode: 'es2015'})}},// 清理输出目录emptyOutDir: isBuild,// 详细的构建信息reportCompressedSize: true,// 目标环境target: 'es2015'},define: {'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'),'__VERSION__': JSON.stringify(packageJson.version)},// 优化依赖optimizeDeps: {exclude: ['vue', '@ant-design/icons-vue']},// 解析配置resolve: {alias: {'@': resolve(__dirname, 'src')}},// 生产版使用更严格的压缩选项...(isDev ? {} : {esbuild: {drop: ['console', 'debugger']}})}
})

🔧 增强构建脚本 (build.js)

// build.js - 增强构建脚本,处理 .min 文件
import {build} from 'vite'
import {readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync} from 'fs'
import {resolve} from 'path'const pkg = JSON.parse(readFileSync('./package.json', 'utf-8'))async function buildAll() {console.log('🚀 开始构建多格式图标库...\n')// 构建开发版console.log('📦 构建开发版(无压缩)...')await build({mode: 'development',configFile: 'vite.config.js'})// 构建生产版console.log('🏗️  构建生产版(压缩,含 .min)...')await build({mode: 'production',configFile: 'vite.config.js'})// 为生产版创建非 .min 版本(指向 .min 的软链接)createNonMinVersions()// 生成辅助文件generateHelperFiles()// 验证构建结果validateBuild()console.log('\n✅ 所有构建完成!')console.log('📁 开发版: dist/dev/ (无压缩)')console.log('📁 生产版: dist/prod/ (压缩,含 .min)')
}function createNonMinVersions() {console.log('🔗 创建非 .min 版本链接...')const formats = ['esm', 'cjs', 'umd', 'amd', 'iife']const prodDir = 'dist/prod'formats.forEach(format => {const minFile = `${prodDir}/ant-design-icons-vue.${format}.min.js`const nonMinFile = `${prodDir}/ant-design-icons-vue.${format}.js`try {// 创建非压缩版本的副本(实际内容相同,只是文件名不同)if (existsSync(minFile)) {copyFileSync(minFile, nonMinFile)console.log(`${format}: 创建非 .min 版本`)}} catch (error) {console.log(`${format}: 创建非 .min 版本失败`, error.message)}})
}function generateHelperFiles() {// 生成 package.json 文件用于子目录引用const subPackageJson = {name: `${pkg.name}-dist`,version: pkg.version,description: pkg.description,main: '../index.js'}writeFileSync('dist/package.json', JSON.stringify(subPackageJson, null, 2))// 生成简单的类型声明文件const typeContent = `declare module '${pkg.name}' {export * from '@ant-design/icons-vue'import * as icons from '@ant-design-icons-vue'export default iconsexport const version: string
}declare module '${pkg.name}/dev' {export * from '@ant-design/icons-vue'
}declare module '${pkg.name}/prod' {export * from '@ant-design/icons-vue'
}`// 确保目录存在const typesDir = 'dist/types'if (!existsSync(typesDir)) {mkdirSync(typesDir, {recursive: true})}writeFileSync('dist/types/index.d.ts', typeContent)writeFileSync('dist/dev/types.d.ts', typeContent)writeFileSync('dist/prod/types.d.ts', typeContent)// 生成版本信息文件writeFileSync('dist/version.json', JSON.stringify({version: pkg.version,buildTime: new Date().toISOString(),formats: ['esm', 'cjs', 'umd', 'amd', 'iife']}, null, 2))
}function validateBuild() {console.log('🔍 验证构建结果...')const formats = ['esm', 'cjs', 'umd', 'amd', 'iife']const environments = {dev: '开发版',prod: '生产版'}let allValid = truefor (const [env, desc] of Object.entries(environments)) {console.log(`\n📂 检查 ${desc} (${env}):`)for (const format of formats) {const minSuffix = env === 'prod' ? '.min' : ''const filePath = `dist/${env}/ant-design-icons-vue.${format}${minSuffix}.js`try {const content = readFileSync(filePath, 'utf-8')const size = (Buffer.byteLength(content, 'utf-8') / 1024).toFixed(2)// 基本验证const isValid = content.includes('@ant-design/icons-vue') &&!content.includes('vue') && // 确保不包含 Vuecontent.length > 100 // 确保文件不为空// 检查压缩情况const isMinified = env === 'prod' &&(content.includes('function(') ||content.split('\n').length < 10)if (isValid) {console.log(`${format.toUpperCase()}: ${size} KB${isMinified ? ' (压缩)' : ''}`)} else {console.log(`${format.toUpperCase()}: 文件可能有问题`)allValid = false}} catch (error) {console.log(`${format.toUpperCase()}: 文件不存在`)allValid = false}}}return allValid
}buildAll().catch(error => {console.error('❌ 构建失败:', error)process.exit(1)
})

📦 Package.json 配置

{"name": "ant-design-icons-vue-bundle","version": "1.0.0","type": "module","description": "Bundled version of @ant-design/icons-vue in multiple formats with minified production builds","main": "./dist/prod/ant-design-icons-vue.cjs.js","module": "./dist/prod/ant-design-icons-vue.esm.js","browser": "./dist/prod/ant-design-icons-vue.umd.min.js","unpkg": "./dist/prod/ant-design-icons-vue.umd.min.js","jsdelivr": "./dist/prod/ant-design-icons-vue.umd.min.js","types": "./dist/types/index.d.ts","scripts": {"dev": "vite build --mode development","build": "vite build --mode production","build:dev": "vite build --mode development --config vite.config.advanced.js","build:prod": "vite build --mode production --config vite.config.advanced.js","build:all": "npm run build:dev && npm run build:prod","build:advanced": "node build.js","prepack": "npm run build:all","test": "node test.js","serve:dev": "vite preview --outDir dist/dev","serve:prod": "vite preview --outDir dist/prod"},"files": ["dist","README.md"],"exports": {".": {"types": "./dist/types/index.d.ts","import": {"production": "./dist/prod/ant-design-icons-vue.esm.min.js","development": "./dist/dev/ant-design-icons-vue.esm.js","default": "./dist/prod/ant-design-icons-vue.esm.min.js"},"require": {"production": "./dist/prod/ant-design-icons-vue.cjs.min.js","development": "./dist/dev/ant-design-icons-vue.cjs.js","default": "./dist/prod/ant-design-icons-vue.cjs.min.js"},"browser": {"production": "./dist/prod/ant-design-icons-vue.umd.min.js","development": "./dist/dev/ant-design-icons-vue.umd.js","default": "./dist/prod/ant-design-icons-vue.umd.min.js"}},"./dev": {"types": "./dist/dev/types.d.ts","import": "./dist/dev/ant-design-icons-vue.esm.js","require": "./dist/dev/ant-design-icons-vue.cjs.js","browser": "./dist/dev/ant-design-icons-vue.umd.js"},"./prod": {"types": "./dist/prod/types.d.ts","import": "./dist/prod/ant-design-icons-vue.esm.min.js","require": "./dist/prod/ant-design-icons-vue.cjs.min.js","browser": "./dist/prod/ant-design-icons-vue.umd.min.js"},"./package.json": "./package.json"},"dependencies": {"@ant-design/icons-vue": "^7.0.1","vue": "^3.5.21"},"peerDependencies": {"@ant-design/icons-vue": "^7.0.1","vue": "^3.5.21"},"devDependencies": {"@ant-design/icons-vue": "^7.0.1","vue": "^3.5.21","@vitejs/plugin-vue": "^4.4.0","vite": "^4.4.0","vue-tsc": "^1.8.0","@babel/preset-env": "^7.22.9","@rollup/plugin-babel": "^6.0.3","@rollup/plugin-commonjs": "^25.0.4","@rollup/plugin-node-resolve": "^15.1.0","@rollup/plugin-terser": "^0.4.3","@rollup/plugin-typescript": "^11.1.3","rollup": "^3.28.0","typescript": "^5.1.6"},"keywords": ["icons","ant-design","vue","components","umd","esm","cjs","amd","iife","minified"],"author": "MuZone","license": "MIT"
}

🧪 测试文件 (test.js)

// test.js - 验证不同格式的可用性
const {readFileSync, existsSync} = require('fs')
const path = require('path')console.log('🧪 测试构建结果...\n')// 测试文件是否存在且基本结构正确
function testFileExistence() {const formats = ['esm', 'cjs', 'umd', 'amd', 'iife']const envs = [{name: '开发版', dir: 'dev', minified: false},{name: '生产版', dir: 'prod', minified: true}]console.log('📁 文件存在性测试:')for (const env of envs) {console.log(`\n环境: ${env.name} (${env.dir})`)for (const format of formats) {const minSuffix = env.minified ? '.min' : ''const fileName = `ant-design-icons-vue.${format}${minSuffix}.js`const filePath = path.join('dist', env.dir, fileName)try {const stats = require('fs').statSync(filePath)const sizeKB = (stats.size / 1024).toFixed(2)const icon = existsSync(filePath) ? '✅' : '❌'console.log(`   ${icon} ${format.toUpperCase()}: ${sizeKB} KB${env.minified ? ' (压缩)' : ''}`)// 额外检查生产版的非 .min 版本if (env.minified) {const nonMinPath = path.join('dist', env.dir, `ant-design-icons-vue.${format}.js`)if (existsSync(nonMinPath)) {const nonMinStats = require('fs').statSync(nonMinPath)console.log(`      ↳ 非压缩版本: ${(nonMinStats.size / 1024).toFixed(2)} KB`)}}} catch (error) {console.log(`${format.toUpperCase()}: 文件不存在`)}}}
}// 测试内容是否正确外部化 Vue
function testExternalization() {console.log('\n🔍 外部化依赖测试:')const testFiles = ['dist/dev/ant-design-icons-vue.esm.js','dist/prod/ant-design-icons-vue.esm.min.js','dist/prod/ant-design-icons-vue.umd.min.js']for (const file of testFiles) {try {const content = readFileSync(file, 'utf-8')const hasVue = content.includes('require("vue")') || content.includes('from "vue"')const hasIcons = content.includes('@ant-design/icons-vue')if (!hasVue && hasIcons) {console.log(`${file}: Vue 已正确外部化`)} else {console.log(`${file}: Vue 外部化可能有问题`)}} catch (error) {console.log(`${file}: 读取失败`)}}
}// 测试压缩效果
function testMinification() {console.log('\n📦 压缩效果测试:')const pairs = [['dist/dev/ant-design-icons-vue.esm.js', 'dist/prod/ant-design-icons-vue.esm.min.js'],['dist/dev/ant-design-icons-vue.umd.js', 'dist/prod/ant-design-icons-vue.umd.min.js']]for (const [devFile, prodFile] of pairs) {if (existsSync(devFile) && existsSync(prodFile)) {const devSize = require('fs').statSync(devFile).sizeconst prodSize = require('fs').statSync(prodFile).sizeconst ratio = ((devSize - prodSize) / devSize * 100).toFixed(1)console.log(`   📊 ${path.basename(devFile)}${path.basename(prodFile)}`)console.log(`      ${(devSize / 1024).toFixed(2)} KB → ${(prodSize / 1024).toFixed(2)} KB (减少 ${ratio}%)`)}}
}// 运行测试
testFileExistence()
testExternalization()
testMinification()console.log('\n🎉 测试完成!')

📊 输出格式详情

格式环境文件路径全局变量文件大小(约)特点
ESM开发版dist/dev/esm.js-10-15KB无压缩,支持 Tree Shaking
ESM生产版dist/prod/esm.min.js-3-5KB压缩优化
CJS开发版dist/dev/cjs.js-10-15KB无压缩,CommonJS
CJS生产版dist/prod/cjs.min.js-3-5KB压缩优化
UMD开发版dist/dev/umd.jsAntDesignIconsVue15-20KB无压缩,浏览器全局变量
UMD生产版dist/prod/umd.min.jsAntDesignIconsVue5-8KB压缩优化
AMD开发版dist/dev/amd.js-15-20KB无压缩,RequireJS
AMD生产版dist/prod/amd.min.js-5-8KB压缩优化
IIFE开发版dist/dev/iife.jsAntDesignIconsVue15-20KB无压缩,立即执行
IIFE生产版dist/prod/iife.min.jsAntDesignIconsVue5-8KB压缩优化

🚀 高级压缩配置

如果需要更精细的压缩控制,可以使用以下配置:

// vite.config.advanced.js
// vite.config.advanced.js
import {defineConfig} from 'vite'
import {resolve} from 'path'export default defineConfig(({mode}) => {const isDev = mode === 'development'return {build: {outDir: `dist/${isDev ? 'dev' : 'prod'}`,sourcemap: isDev ? true : 'hidden',minify: isDev ? false : 'terser',lib: {entry: resolve(__dirname, 'src/index.js'),name: 'AntDesignIconsVue',fileName: (format) => {const formatMap = {es: 'esm', cjs: 'cjs', umd: 'umd', amd: 'amd', iife: 'iife'}const minSuffix = isDev ? '' : '.min'return `ant-design-icons-vue.${formatMap[format] || format}${minSuffix}.js`},formats: ['es', 'cjs', 'umd', 'amd', 'iife']},rollupOptions: {external: ['vue'],  //, '@ant-design/icons-vue'output: {globals: {'vue': 'Vue','@ant-design/icons-vue': 'AntDesignIconsVue'},// 生产版使用高级压缩...(isDev ? {} : {compact: true,generatedCode: {arrowFunctions: true,constBindings: true},// Terser 压缩选项minifyInternalExports: true,sanitizeFileName: true})}},// 生产版构建优化...(isDev ? {} : {chunkSizeWarningLimit: 1000,assetsInlineLimit: 4096})},define: {'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'),'__VERSION__': JSON.stringify(process.env.npm_package_version || '1.0.0')},// 生产版特定的优化...(isDev ? {} : {esbuild: {legalComments: 'none',minifyIdentifiers: true,minifySyntax: true,minifyWhitespace: true}})}
})

💡 使用示例

ESM (现代浏览器/打包工具)

// 开发版 - 无压缩
import { SearchOutlined } from 'ant-design-icons-vue-bundle/dev'// 生产版 - 压缩
import { SearchOutlined } from 'ant-design-icons-vue-bundle/prod'
// 或自动根据环境选择
import { SearchOutlined } from 'ant-design-icons-vue-bundle'

CJS (Node.js)

// 开发版
const { SearchOutlined } = require('ant-design-icons-vue-bundle/dev')// 生产版  
const { SearchOutlined } = require('ant-design-icons-vue-bundle/prod')

UMD (浏览器全局变量)

<!-- 开发版 - 无压缩 -->
<script src="path/to/ant-design-icons-vue.umd.js"></script><!-- 生产版 - 压缩 -->
<script src="path/to/ant-design-icons-vue.umd.min.js"></script><script>
// 使用方式相同
const { SearchOutlined } = AntDesignIconsVue
</script>

CDN 使用

<!-- 使用 jsDelivr CDN -->
<script src="https://cdn.jsdelivr.net/npm/ant-design-icons-vue-bundle/dist/prod/ant-design-icons-vue.umd.min.js"></script><!-- 使用 unpkg CDN -->
<script src="https://unpkg.com/ant-design-icons-vue-bundle/dist/prod/ant-design-icons-vue.umd.min.js"></script>

AMD (RequireJS)

// 开发版
require.config({paths: {'icons': 'path/to/ant-design-icons-vue.amd'}
})// 生产版  
require.config({paths: {'icons': 'path/to/ant-design-icons-vue.amd.min'}
})require(['icons'], function(icons) {const { SearchOutlined } = icons
})

🎯 构建和发布

  1. 创建项目:
mkdir antd-icons-vue
cd antd-icons-vue
npm init -y
  1. 安装依赖:
npm install
  1. 构建高级的所有格式:
npm run build:advanced
  1. 构建所有格式:
npm run build:all
  1. 仅构建开发版:
npm run build:dev
  1. 仅构建生产版:
npm run build:prod
  1. 测试构建结果:
npm test
  1. 预览开发版:
npm run serve:dev
  1. 预览生产版:
npm run serve:prod

总结这个配置方案:

  1. 使用 src/index.js 作为入口 - 符合项目结构最佳实践
  2. 生产版含 .min 后缀 - 清晰区分压缩版和非压缩版
  3. 不包含 Vue 依赖 - 通过 external 配置正确外部化
  4. 多格式支持 - 完整的 5 种模块格式
  5. 开发/生产分离 - 分别构建优化版和调试版
  6. 完整的压缩优化 - 生产版文件大小显著减少
  7. CDN 友好 - 为 CDN 使用优化了配置
http://www.dtcms.com/a/403060.html

相关文章:

  • 什么是营销型网站?杭州建设教育网站
  • C++开发环境(VSCode + CMake + gdb)
  • JAVA CodeX精选实用代码示例
  • 肥东网站建设南京医院网站建设
  • Qt 多线程解析
  • ZooKeeper与Kafka分布式:从基础原理到集群部署
  • 免费网站服务器安全软件下载wordpress权限设置方法
  • three.js射线拾取点击位置与屏幕坐标映射
  • AutoMQ × Ververica:打造云原生实时数据流最佳实践!
  • Laravel5.8 使用 snappyPDF 生成PDF文件
  • 自己做网站的图片手机芒果tv2016旧版
  • L4 vs L7 负载均衡:彻底理解、对比与实战指南
  • wordpress站群软件自己的网站怎么赚钱
  • 零知IDE——基于STM32F407VET6和MCP2515实现CAN通信与数据采集
  • 若依框架-Spring Boot
  • 全新 CloudPilot AI:嵌入 Kubernetes 的 SRE Agent,降本与韧性双提升!
  • 自建网站推广的最新发展wordpress同步到报价号
  • 4、导线、端子及印制电路板元器件的插装、焊接及拆焊
  • 【Java八股文】13-中间件面试篇
  • (四)优雅重构:洞悉“搬移特性”的艺术与实践
  • 网站建设专用图形库商务网站建设方案
  • 快速入门HarmonyOS应用开发(三)
  • Easysearch 国产替代 Elasticsearch:8 大核心问题解读
  • 【机器学习】搭建对抗神经网络模型来实现 MNIST 手写数字生成
  • 做推广的网站那个好中国机房建设公司排名
  • odoo18应用、队列服务器分离(SSHFS)
  • 老年健康管理小工具抖音快手微信小程序看广告流量主开源
  • c#vb.net动态创建二维数组
  • php做网站完整视频动漫制作和动漫设计哪个好
  • 云原生微服务中间件选型