Ctrl K
ComunidadGuías…

plugins/withVersionSync.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * Expo Config Plugin:自动从 expo.version 派生 Android versionCode
 *
 * 单一数据源:app.json.expo.version
 *
 * versionName 由 expo prebuild 模板自动从 app.json.expo.version 读取,无需此 plugin 处理。
 * versionCode 计算规则:major * 10000 + minor * 100 + patch
 *   例:0.2.1 → 0*10000 + 2*100 + 1 = 201
 *
 * 使用方式:在 app.json 的 expo.plugins 数组中注册即可。
 */
const { withAppBuildGradle } = require('expo/config-plugins');

module.exports = (config) => {
  const version = config.version;
  // 缺 version 时静默跳过会让 android 里留着旧 versionCode,发布脚本只能靠 aapt 事后发现
  if (!version) {
    throw new Error('withVersionSync: app.json 缺少 expo.version,无法派生 versionCode');
  }

  const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
  if (!match) {
    throw new Error(`withVersionSync: app.json.expo.version "${version}" 不符合 X.Y.Z 格式`);
  }
  const [, majorStr, minorStr, patchStr] = match;
  const major = parseInt(majorStr, 10);
  const minor = parseInt(minorStr, 10);
  const patch = parseInt(patchStr, 10);
  if (minor >= 100 || patch >= 100) {
    throw new Error(`withVersionSync: minor/patch 必须 < 100(当前 ${major}.${minor}.${patch})`);
  }
  const versionCode = major * 10000 + minor * 100 + patch;

  return withAppBuildGradle(config, (config) => {
    if (!config.modResults?.contents) {
      throw new Error('withVersionSync: 无法读取 build.gradle 内容');
    }
    let contents = config.modResults.contents;
    const regex = /versionCode\s*=?\s*\d+/;
    if (!regex.test(contents)) {
      throw new Error('withVersionSync: 在 build.gradle 中未找到 versionCode 字段');
    }
    contents = contents.replace(regex, `versionCode ${versionCode}`);
    config.modResults.contents = contents;
    return config;
  });
};