搭建自己的脚手架(二)---启动阶段

130 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情

前言

今天我们来完成脚手架启动阶段需要完成的一些任务,就是启动阶段需要做的一些检查

core函数

我们先来写一下core函数的模板

core/cli/lib/index.js

"use strict";

const log = require("@wson-koa2-cli/log");

// 命令启动前的检查
function prepare() {
    
}

function cli() {
  try {
    // 命令启动前的检查
    prepare();
  } catch (error) {
    log.error(error);
  }
}

module.exports = cli;

这样只要prepare里面只要有报错的话,错误信息都会被抓去住,并且不会在向下执行

检查node版本号

why do the node version check?

因为我们用到了node新版本的api,如果用户是低版本的话,运行脚手架会报错。所以需要提醒用户升级到最新版本的node

semver 库

Semver是一个专门分析Semantic Version(语义化版本)的工具,“semver”其实就是这两个单词的缩写。Npm使用了该工具来处理版本相关的工作。

semver可以作为一个node模块,同时也可以作为一个命令行工具。功能包括:

  • 比较两个版本号的大小
  • 验证某个版本号是否合法
  • 提取版本号,例如从“=v1.2.1”体取出"1.2.1"
  • 分析版本号是否属于某个范围或符合一系列条件

在此处我们用来检查用户本地的版本号是否小于我们规定的版本号

const semver = require("semver");
const LOWEST_NODE_VERSION = "12.0.0";

// 检查node的版本号
function checkNodeVersion() {
  // 因为脚手架执行时就是一个node进程,所以可以从process拿到node版本号
  const currentVersion = process.version;
  const lowestVersion = LOWEST_NODE_VERSION;
  // 通过semver这个库来比对版本号的大小
  if (!semver.gte(currentVersion, lowestVersion)) {
    throw new Error(
      // 当前node版本小于指定版本,请升级版本
       log.info(`The node version is less than ${LOWEST_NODE_VERSION}, please upgrade the node version`)
    );
  }
}

检查当前包是否是最新版本

const pkg = require("../package.json");

// 检测package.json版本是否小于最低版本
function checkPkgVersion() {
  const currentPkgVersion = pkg.version;
  if (!semver.gte(currentPkgVersion, LOWEST_PKG_VERSION)) {
    throw new Error(
      `imooc-ws-cli-dev suggest that your current version should greater than v${LOWEST_PKG_VERSION}, Please upgrade you version`
    );
  } else {
    log.info("cli", currentPkgVersion);
  }
}

提醒用户可升级到最新版本

这个函数要写的内容比较多,那么我们在util中新建一个包

lerna create @wson-koa2-cli/get-npm-info utils

utils/get-npm-info/lib/index.js中写

获取数据源函数

function getDefaultRegistry(isOriginal = false) {
    // 默认是从淘宝源的仓库获取
    return isOriginal
      ? 'https://registry.npmjs.org'
      : 'https://registry.npmmirror.com'
}

获取npm信息

// 获取npm信息
function getNpmInfo(npmName) {
  if (!npmName) {
    return null;
  }
  const registryUrl = getDefaultRegistry();
  const npmInfoUrl = `${registryUrl}/${npmName}`;
  return axios
    .get(npmInfoUrl)
    .then((res) => {
      if (res.status === 200) {
        return res.data;
      } else {
        return null;
      }
    })
    .catch((err) => {
      throw new Error(err);
    });
}

获取包所有版本

// 全部采用async/await的写法
async function getNpmVersions(npmName) {
    const data = await getNpmInfo(npmName)
    if (data) {
      return Object.keys(data.versions)
    } else {
      return []
    }
}

获取比本地版本大的版本列表

// 获取比当前脚手架版本大的版本信息
function getSemverVersions(baseVersion, versions) {
  return versions
    .filter(version =>
      // semver.satisfies函数表示获取大于^1.0.4的版本,^有大于等于的意思
      semver.satisfies(version, `^${baseVersion}`)
    )
    // 有可能从npm上获取的版本不是排序之后的
    .sort((a, b) => {
      if (semver.gt(b, a)) {
        return 1
      } else {
        return -1
      }
    })
}

获取包最新版本

// 获取最新版本
async function getNpmSemverVersions(baseVersion, npmName) {
    const versions = await getNpmVersions(npmName)
    const newVersions = getSemverVersions(baseVersion, versions)
    if (newVersions && newVersions.length > 0) {
      return newVersions[0]
    }
}

上面函数实现了以后

core/cli/lib/index.js中写

// 提示更新到最新版本
async function npmUpdateLatestVersionWarning() {
  const currentVersion = pkg.version;
  const npmName = pkg.name;
  const lastVersion = await getNpmLatestVersions(currentVersion, npmName);
  if (lastVersion && semver.gt(lastVersion, currentVersion)) {
    log.warn(
      `Please update manually ${npmName},The latest version is ${lastVersion},Update command:npm install -g ${npmName}`
    );
  }
}

在测试这个功能的时候一定要先发布包

参考