Taro打包增加版本号

1,563 阅读3分钟

背景

当每次打包生产环境时的小程序包时,需要在命令行中输入版本号,可以根据项目的需求对输入的版本号进行个性化配置,此版本号会影响到项目的package.json文件和项目中需要使用的版本号,可以通过package.json便可以查看当前生产的版本号,也可以在业务代码中使用这个版本号,无论是页面的展示还是接口的请求。

实现

  • 编写一个脚本,用于收集用户在命令行中的行为,在根据用户的行为做对应的处理

首先定义一个run函数,用于脚本启动时应行

const run = async () => {
  // 打印点东西玩
  init();

  // 是否需要版本号
  const { NEED_VERSION } = await isNeedVersion();

  // 需要
  if (NEED_VERSION === '需要') {
    while (true) {
      let { VERSION } = await stdinVersion();
      // 根据版本号 做处理
      if (VERSION && validateVersion(VERSION)) {

        const rootPath = process.cwd();
        const packageFilePath = path.resolve(rootPath, './package.json');

        const source = getPackageFile(VERSION, packageFilePath);
        const newSource  = updateVersion(source, VERSION)
        updatePackageFile(newSource, packageFilePath)
        break;
      }
    }
  }

  console.log(chalk.green('打包开始'));
  shell.exec('npm run build:weapp');
  console.log(chalk.green('打包结束'));
};

run();

run函数主要做了这么几件事

  1. 在命令行输出一个比较漂亮的PMS,没有用就是为了好玩
// 设置 命令行的一些样式
const init = () => {
  console.log(
    chalk.green(
      figlet.textSync('PMS', {
        font: 'Ghost',
        horizontalLayout: 'default',
        verticalLayout: 'default'
      })
    )
  );
};

  1. 然后执行isNeedVersion函数,这个函数也就只做了一件事情,就是在提供一个命令行的交互,问一下使用者是否需要打包为正式版本并携带版本号
// 是否需要版本号
const isNeedVersion = () => {
  const questions = [
    {
      name: 'NEED_VERSION',
      type: 'list',
      message: '是否需要打包为正式版本并携带版本号',
      choices: ['需要', '不需要']
    }
  ];
  return inquirer.prompt(questions);
};

若是需要打包,则会走打包的流程,不然就时直接打包

  1. 需要打包,则会走if(NEED_VERSION === '需要')
if (NEED_VERSION === '需要') {
    while (true) {
      let { VERSION } = await stdinVersion();
      // 根据版本号 做处理
      if (VERSION && validateVersion(VERSION)) {

        const rootPath = process.cwd();
        const packageFilePath = path.resolve(rootPath, './package.json');

        const source = getPackageFile(VERSION, packageFilePath);
        const newSource  = updateVersion(source, VERSION)
        updatePackageFile(newSource, packageFilePath)
        break;
      }
    }
  }

stdinVersion函数是用来获取用户输入的版本号,需要注意的是这里使用了一个while(true),因为当用户选择需要时,若是用户不输入内容则会一直的提示,县城会被卡在这个地方,知道用户输入版本号。

获取用户的输入并进行简单的校验,是在validateVersion函数中进行。

// 校验 version 是否符合
const validateVersion = (version) => {
  const reg = /^\d+\.\d+\.\d+/gi

  if(!reg.test(version)){ // 不合法
    console.log(chalk.red('请确保版本号符合 x.x.x 格式'));
    return false
  }else{
    return true
  }
}

当用户输入合法的版本号并校验通过之后,便会通过getPackageFile方法来获取项目中的package.json文件,然后利用updateVersion方法将文件中的version进行修改,然后调用updatePackageFile方法进行修改

// 获取 package.json 的内容
const getPackageFile = (inputVersion, packageFilePath) => {
  try {
    return  fs.readFileSync(packageFilePath);
  } catch (error) {
    console.log(chalk.red('获取文件失败'));
  }
};

// 根据输入的 version 进行修改
const updateVersion = (source, version ) => {
  let newSource = JSON.parse(source);

  const newVersion = version;
  const oldVersion = newSource.version
  newSource.version = newVersion;

  const scripts = newSource.scripts

  // 将 scripts 中的所有旧的 version 替换为新的
  for (const key in scripts) {
    if (scripts.hasOwnProperty(key)) {
      let element = scripts[key];
      scripts[key] = element.replace(oldVersion, newVersion)
    }
  }

  return newSource
}

// 修改 package.json 文件内容
const updatePackageFile = (newSource, packageFilePath) => {
  try {
    fs.writeFileSync(packageFilePath, JSON.stringify(newSource));
    console.log(chalk.green('修改文件 package.json 成功'));
  } catch (error) {
    console.log(chalk.red('文件修改失败'));
  }
}

重点来啦,每次打包的时候都会将package.jsonscripts字段进行处理,利用cross-env为项目增加了一个RELEASE,打包完之后,就可以在项目中使用RELEASE获取打包之后的版本号啦,无论是在接口请求中还是页面展示都可以使用。