#!/bin/bash ############################################################################### # fmode-feishu-api 构建脚本 # # 功能: # 1. 使用esbuild打包所有ESM模块 # 2. 使用terser进行代码混淆和压缩 # 3. 生成可发布到npm或CDN的dist文件 # 4. 支持Deno和Node.js环境 # # 使用方法: # chmod +x build.sh # ./build.sh # # 输出: # ./dist/{version}/fmode-feishu-api.js - 打包后的文件 # ./dist/{version}/fmode-feishu-api.min.js - 混淆压缩后的文件 ############################################################################### # 设置错误时退出 set -e # 颜色输出 GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color echo -e "${GREEN}==================================================${NC}" echo -e "${GREEN} fmode-feishu-api 构建脚本${NC}" echo -e "${GREEN}==================================================${NC}" # 检查是否在正确的目录 if [ ! -f "package.json" ]; then echo -e "${RED}错误: package.json 不存在${NC}" echo -e "${YELLOW}请确保在 fmode-feishu-api 目录下运行此脚本${NC}" exit 1 fi # 读取版本号 VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "1.0.0") if [ -z "$VERSION" ]; then echo -e "${RED}错误: 无法从 package.json 读取版本号${NC}" exit 1 fi echo -e "${GREEN}版本号: ${VERSION}${NC}" # 创建dist/{version}目录 DIST_DIR="dist/${VERSION}" echo -e "${YELLOW}[1/5] 创建 ${DIST_DIR} 目录...${NC}" rm -rf "${DIST_DIR}" mkdir -p "${DIST_DIR}" # 检查是否安装了依赖 if [ ! -d "node_modules" ]; then echo -e "${YELLOW}[2/5] 安装依赖...${NC}" npm install else echo -e "${GREEN}[2/5] 依赖已安装,跳过...${NC}" fi # 使用esbuild打包 esm echo -e "${YELLOW}[3/5] 使用esbuild打包 ESM 格式...${NC}" npx esbuild src/index.ts \ --bundle \ --format=esm \ --platform=node \ --target=node16 \ --outfile="${DIST_DIR}/fmode-feishu-api.js" \ --sourcemap \ --external:express if [ $? -eq 0 ]; then echo -e "${GREEN}✓ ESM 打包成功${NC}" else echo -e "${RED}✗ ESM 打包失败${NC}" exit 1 fi # 使用esbuild打包 cjs echo -e "${YELLOW}[3/5] 使用esbuild打包 CJS 格式...${NC}" npx esbuild src/index.ts \ --bundle \ --format=cjs \ --platform=node \ --target=node16 \ --outfile="${DIST_DIR}/fmode-feishu-api.cjs" \ --sourcemap \ --external:express if [ $? -eq 0 ]; then echo -e "${GREEN}✓ CJS 打包成功${NC}" else echo -e "${RED}✗ CJS 打包失败${NC}" exit 1 fi # 使用terser压缩和混淆 ESM echo -e "${YELLOW}[4/5] 使用terser压缩混淆 ESM...${NC}" npx terser "${DIST_DIR}/fmode-feishu-api.js" \ --compress \ --mangle \ --output "${DIST_DIR}/fmode-feishu-api.min.js" \ --source-map "content='${DIST_DIR}/fmode-feishu-api.js.map',url='fmode-feishu-api.min.js.map'" if [ $? -eq 0 ]; then echo -e "${GREEN}✓ ESM 压缩混淆成功${NC}" else echo -e "${RED}✗ ESM 压缩混淆失败${NC}" exit 1 fi # 使用terser压缩和混淆 CJS echo -e "${YELLOW}[4/5] 使用terser压缩混淆 CJS...${NC}" npx terser "${DIST_DIR}/fmode-feishu-api.cjs" \ --compress \ --mangle \ --output "${DIST_DIR}/fmode-feishu-api.min.cjs" \ --source-map "content='${DIST_DIR}/fmode-feishu-api.cjs.map',url='fmode-feishu-api.min.cjs.map'" if [ $? -eq 0 ]; then echo -e "${GREEN}✓ CJS 压缩混淆成功${NC}" else echo -e "${RED}✗ CJS 压缩混淆失败${NC}" exit 1 fi # 显示文件大小 echo -e "${YELLOW}[5/5] 构建完成,文件信息:${NC}" echo "" ls -lh "${DIST_DIR}/" echo "" # 计算文件大小 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) 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) if [ ! -z "$ORIGINAL_SIZE" ] && [ ! -z "$MINIFIED_SIZE" ]; then REDUCTION=$(echo "scale=2; (1 - $MINIFIED_SIZE / $ORIGINAL_SIZE) * 100" | bc 2>/dev/null || echo "N/A") echo -e "${GREEN}压缩率: ${REDUCTION}%${NC}" fi echo "" echo -e "${GREEN}==================================================${NC}" echo -e "${GREEN} 构建成功!${NC}" echo -e "${GREEN}==================================================${NC}" echo "" echo -e "${YELLOW}输出文件:${NC}" echo -e " - ${DIST_DIR}/fmode-feishu-api.js (ESM开发版,带source map)" echo -e " - ${DIST_DIR}/fmode-feishu-api.min.js (ESM生产版,已压缩混淆)" echo -e " - ${DIST_DIR}/fmode-feishu-api.cjs (CJS开发版,带source map)" echo -e " - ${DIST_DIR}/fmode-feishu-api.min.cjs (CJS生产版,已压缩混淆)" echo "" echo -e "${YELLOW}使用方法:${NC}" echo -e " ${GREEN}# Deno / Node.js ESM${NC}" echo -e " import { createFeishuRouter } from './${DIST_DIR}/fmode-feishu-api.min.js';" echo "" echo -e " ${GREEN}# Node.js CJS${NC}" echo -e " const { createFeishuRouter } = require('./${DIST_DIR}/fmode-feishu-api.min.cjs');" echo "" echo -e " ${GREEN}# 上传到CDN${NC}" echo -e " ./upload.sh" echo "" echo -e " ${GREEN}# CDN 引用示例${NC}" echo -e " import { createFeishuRouter } from 'https://repos.fmode.cn/x/fmode-feishu-api/${VERSION}/fmode-feishu-api.min.js?code=xxxxxxx';" echo "" exit 0