build.sh 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/bin/bash
  2. ###############################################################################
  3. # fmode-feishu-api 构建脚本
  4. #
  5. # 功能:
  6. # 1. 使用esbuild打包所有ESM模块
  7. # 2. 使用terser进行代码混淆和压缩
  8. # 3. 生成可发布到npm或CDN的dist文件
  9. # 4. 支持Deno和Node.js环境
  10. #
  11. # 使用方法:
  12. # chmod +x build.sh
  13. # ./build.sh
  14. #
  15. # 输出:
  16. # ./dist/{version}/fmode-feishu-api.js - 打包后的文件
  17. # ./dist/{version}/fmode-feishu-api.min.js - 混淆压缩后的文件
  18. ###############################################################################
  19. # 设置错误时退出
  20. set -e
  21. # 颜色输出
  22. GREEN='\033[0;32m'
  23. YELLOW='\033[1;33m'
  24. RED='\033[0;31m'
  25. NC='\033[0m' # No Color
  26. echo -e "${GREEN}==================================================${NC}"
  27. echo -e "${GREEN} fmode-feishu-api 构建脚本${NC}"
  28. echo -e "${GREEN}==================================================${NC}"
  29. # 检查是否在正确的目录
  30. if [ ! -f "package.json" ]; then
  31. echo -e "${RED}错误: package.json 不存在${NC}"
  32. echo -e "${YELLOW}请确保在 fmode-feishu-api 目录下运行此脚本${NC}"
  33. exit 1
  34. fi
  35. # 读取版本号
  36. VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "1.0.0")
  37. if [ -z "$VERSION" ]; then
  38. echo -e "${RED}错误: 无法从 package.json 读取版本号${NC}"
  39. exit 1
  40. fi
  41. echo -e "${GREEN}版本号: ${VERSION}${NC}"
  42. # 创建dist/{version}目录
  43. DIST_DIR="dist/${VERSION}"
  44. echo -e "${YELLOW}[1/5] 创建 ${DIST_DIR} 目录...${NC}"
  45. rm -rf "${DIST_DIR}"
  46. mkdir -p "${DIST_DIR}"
  47. # 检查是否安装了依赖
  48. if [ ! -d "node_modules" ]; then
  49. echo -e "${YELLOW}[2/5] 安装依赖...${NC}"
  50. npm install
  51. else
  52. echo -e "${GREEN}[2/5] 依赖已安装,跳过...${NC}"
  53. fi
  54. # 使用esbuild打包 esm
  55. echo -e "${YELLOW}[3/5] 使用esbuild打包 ESM 格式...${NC}"
  56. npx esbuild src/index.ts \
  57. --bundle \
  58. --format=esm \
  59. --platform=node \
  60. --target=node16 \
  61. --outfile="${DIST_DIR}/fmode-feishu-api.js" \
  62. --sourcemap \
  63. --external:express
  64. if [ $? -eq 0 ]; then
  65. echo -e "${GREEN}✓ ESM 打包成功${NC}"
  66. else
  67. echo -e "${RED}✗ ESM 打包失败${NC}"
  68. exit 1
  69. fi
  70. # 使用esbuild打包 cjs
  71. echo -e "${YELLOW}[3/5] 使用esbuild打包 CJS 格式...${NC}"
  72. npx esbuild src/index.ts \
  73. --bundle \
  74. --format=cjs \
  75. --platform=node \
  76. --target=node16 \
  77. --outfile="${DIST_DIR}/fmode-feishu-api.cjs" \
  78. --sourcemap \
  79. --external:express
  80. if [ $? -eq 0 ]; then
  81. echo -e "${GREEN}✓ CJS 打包成功${NC}"
  82. else
  83. echo -e "${RED}✗ CJS 打包失败${NC}"
  84. exit 1
  85. fi
  86. # 使用terser压缩和混淆 ESM
  87. echo -e "${YELLOW}[4/5] 使用terser压缩混淆 ESM...${NC}"
  88. npx terser "${DIST_DIR}/fmode-feishu-api.js" \
  89. --compress \
  90. --mangle \
  91. --output "${DIST_DIR}/fmode-feishu-api.min.js" \
  92. --source-map "content='${DIST_DIR}/fmode-feishu-api.js.map',url='fmode-feishu-api.min.js.map'"
  93. if [ $? -eq 0 ]; then
  94. echo -e "${GREEN}✓ ESM 压缩混淆成功${NC}"
  95. else
  96. echo -e "${RED}✗ ESM 压缩混淆失败${NC}"
  97. exit 1
  98. fi
  99. # 使用terser压缩和混淆 CJS
  100. echo -e "${YELLOW}[4/5] 使用terser压缩混淆 CJS...${NC}"
  101. npx terser "${DIST_DIR}/fmode-feishu-api.cjs" \
  102. --compress \
  103. --mangle \
  104. --output "${DIST_DIR}/fmode-feishu-api.min.cjs" \
  105. --source-map "content='${DIST_DIR}/fmode-feishu-api.cjs.map',url='fmode-feishu-api.min.cjs.map'"
  106. if [ $? -eq 0 ]; then
  107. echo -e "${GREEN}✓ CJS 压缩混淆成功${NC}"
  108. else
  109. echo -e "${RED}✗ CJS 压缩混淆失败${NC}"
  110. exit 1
  111. fi
  112. # 显示文件大小
  113. echo -e "${YELLOW}[5/5] 构建完成,文件信息:${NC}"
  114. echo ""
  115. ls -lh "${DIST_DIR}/"
  116. echo ""
  117. # 计算文件大小
  118. ORIGINAL_SIZE=$(stat -c%s "${DIST_DIR}/fmode-feishu-api.js" 2>/dev/null || stat -f%z "${DIST_DIR}/fmode-feishu-api.js" 2>/dev/null)
  119. MINIFIED_SIZE=$(stat -c%s "${DIST_DIR}/fmode-feishu-api.min.js" 2>/dev/null || stat -f%z "${DIST_DIR}/fmode-feishu-api.min.js" 2>/dev/null)
  120. if [ ! -z "$ORIGINAL_SIZE" ] && [ ! -z "$MINIFIED_SIZE" ]; then
  121. REDUCTION=$(echo "scale=2; (1 - $MINIFIED_SIZE / $ORIGINAL_SIZE) * 100" | bc 2>/dev/null || echo "N/A")
  122. echo -e "${GREEN}压缩率: ${REDUCTION}%${NC}"
  123. fi
  124. echo ""
  125. echo -e "${GREEN}==================================================${NC}"
  126. echo -e "${GREEN} 构建成功!${NC}"
  127. echo -e "${GREEN}==================================================${NC}"
  128. echo ""
  129. echo -e "${YELLOW}输出文件:${NC}"
  130. echo -e " - ${DIST_DIR}/fmode-feishu-api.js (ESM开发版,带source map)"
  131. echo -e " - ${DIST_DIR}/fmode-feishu-api.min.js (ESM生产版,已压缩混淆)"
  132. echo -e " - ${DIST_DIR}/fmode-feishu-api.cjs (CJS开发版,带source map)"
  133. echo -e " - ${DIST_DIR}/fmode-feishu-api.min.cjs (CJS生产版,已压缩混淆)"
  134. echo ""
  135. echo -e "${YELLOW}使用方法:${NC}"
  136. echo -e " ${GREEN}# Deno / Node.js ESM${NC}"
  137. echo -e " import { createFeishuRouter } from './${DIST_DIR}/fmode-feishu-api.min.js';"
  138. echo ""
  139. echo -e " ${GREEN}# Node.js CJS${NC}"
  140. echo -e " const { createFeishuRouter } = require('./${DIST_DIR}/fmode-feishu-api.min.cjs');"
  141. echo ""
  142. echo -e " ${GREEN}# 上传到CDN${NC}"
  143. echo -e " ./upload.sh"
  144. echo ""
  145. echo -e " ${GREEN}# CDN 引用示例${NC}"
  146. echo -e " import { createFeishuRouter } from 'https://repos.fmode.cn/x/fmode-feishu-api/${VERSION}/fmode-feishu-api.min.js?code=xxxxxxx';"
  147. echo ""
  148. exit 0