preface

Recently, I forgot to change the version number during a small version distribution test, and got the idea to prompt for the version number before packaging, and then type the version number into the release notes. The final effect is to double-click the BAT file in the terminal to prompt you to input the version number, and save the version number after input.

Although batch processing can also do this thing, but with JS to write more handy point, so choose JS processing.

The process is divided into four steps

  • Bat executive js
  • The terminal prompts you to enter the version number and run the package command
  • Modify the version number file
  • Gulp reads the json file with the version number

In simple terms, the bat file is used to trigger the packaging command for packaging.

1. Bat executes JS

Start by creating two files: buildversion. bat and buildversion.js.

Buildversion. bat uses Node to run js files

@echo off
set curpath=%~dp0
%curpath%nodejs\node.exe %curpath%buildVersion.js
pause
Copy the code

%~dp0 is the current directory. You can also pass arguments after js, such as –buildType default

2. The terminal prompts you to enter the version number and run the package command

Readline is used for the q&A effect, and child_process is used to execute the packaged command line.

Go to the buildversion. js file and start with a simple prompt input effect.

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
rl.question('Please enter a new version number:'.(name) = >{});Copy the code

That won’t do the trick. We display the previous version number and then prompt for a new version number, using the previous version number if the input is empty.

// Get the version information in step 3
var versionInfo;
const versionInfoUrl = './src/config/version/version.js';
function getVersion() {
    var buildVersion = "";
    try {
        versionInfo = require(versionInfoUrl);
        buildVersion = versionInfo.version;
    } catch (error) {

    }
    return buildVersion;
}
Copy the code

The prompt for input looks like this

const chalk = require('chalk');  // Introduce the color library
rl.question(`${chalk.cyan("Current version:")}${chalk.bold.red(getVersion())}\n Please enter the new version number: '.(name) = >{! name && (name=versionInfo? versionInfo.version:"");
    console.log(`${chalk.cyan("The new version number is:")}${chalk.bold.yellow(name)}`);
Copy the code

The effect on the terminal is zero

// Write the default value
rl.write("Version ")
Copy the code

Next, run the package command. The current project is packaged using GULP. To display gulp prompts on the terminal, select child_process.spawn

// Parse the arguments passed in by the bat run
var minimist = require('minimist');
var argv = minimist(process.argv.slice(2), {
    string: ["name"]});const child_process = require('child_process');
rl.question(`${chalk.cyan("Current version:")}${chalk.bold.red(getVersion())}\n Please enter the new version number: '.(name) = >{! name && (name=versionInfo? versionInfo.version:"");
    console.log(`${chalk.cyan("The new version number is:")}${chalk.bold.yellow(name)}`);
    // Record the new version number
    changeVersion(name);
    
    var buildType = argv.buildType || "build"  // The command is configured in gulp

    var gulpCmd = `gulp ${buildType} --buildVersion "${name}" --color --f ${__dirname}/gulpfile.js`;
    console.log(gulpCmd);
    let spawnProcess = child_process.spawn(gulpCmd, [], {
        shell: true
    });
    spawnProcess.stdout.on('data'.(data) = > {
        console.log(`${data.toString()}`);
    });
    spawnProcess.stderr.on('data'.(data) = > {
        console.log(`stderror: ${data}`);
    });
    spawnProcess.on('close'.(code) = > {
        if(code ! = =0) {
            console.log(`close: ${code}`); }}); spawnProcess.on('exit'.(code) = > {
        // console.log(`exit: ${code.toString()}`);
        console.log(chalk.bold.yellow("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"));
    });
});

function changeVersion(params) {
    if(versionInfo && versionInfo.changeVersion) { versionInfo.changeVersion(params); }}Copy the code

The effect on the terminal is zero

let exec = require('child_process').execSync;
exec('vue-cli-service --mode dev build', {
    stdio: 'inherit'
});
Copy the code

3. Modify the version file

I thought of using fs.writefile to write files, but this is very easy to handle json format, js file processing is very inconvenient. So I kept the version information in a separate JSON file. Create two files version.js and version.json.

var VersionInfoJson;
// For possible references in HTML, we make a distinction
if (typeof module! = ='undefined' && typeof module.exports ! = ='undefined') {
    getVersionInfo(true);
} else {
    if (typeof define === 'function' && define.amd) {
        getVersionInfo(false);
    } else{ getVersionInfoLocal(); }}function getVersionInfo(isModule) {
    try {
        VersionInfoJson = require("./version.json");
    } catch (error) {
        VersionInfoJson = {};
    }
    VersionInfoJson.buildTime = getNowFormatDate();
    VersionInfoJson.changeVersion = changeVersion;

    if (isModule) {
        module.exports = VersionInfoJson;
    }else{
        define([], function () {
            returnVersionInfoJson; }); }}async function getVersionInfoLocal() {
    try {
        VersionInfoJson = await getVersionJson();
    } catch (error) {
        VersionInfoJson = {};
    }
    VersionInfoJson.buildTime = getNowFormatDate();
    window.VersionInfo = VersionInfoJson;
}

function getVersionJson() {
    return new Promise((resolve, reject) = >{
        var request = new XMLHttpRequest();
        request.open("get"."config/version/version.json");
        request.send(null);
        request.onload = function () {
            if (request.status == 200) {
                var json = JSON.parse(request.responseText);
                resolve(json);
            }else{
                varjson = {}; resolve(json); }}}); }function changeVersion(version) {
    var copyVersion = cloneObj(VersionInfoJson);
    copyVersion.version = version;
    if (copyVersion.hasOwnProperty("changeVersion")) {
        delete copyVersion["changeVersion"]}// console.log(copyVersion, __dirname, __filename)
    let fs = require('fs');
    fs.writeFile(__dirname + "/version.json".JSON.stringify(copyVersion), (err) = >{}); }// use the new obj.constructor () function to create an empty object instead of {} or [], which preserves the inheritance of the original chain;
// 2, use obj. HasOwnProperty (key) to check whether the property is from the prototype chain, because for.. in.. It also iterates through enumerable properties on its prototype chain.
// 3, the above function uses a recursive algorithm, as long as the function has a name and the name will not change, this definition is fine. But the problem is that the execution of this function is tightly coupled with the name factorial. To eliminate this tight coupling, you need to use arguments.callee.
function cloneObj(obj) {
    if (obj === null) return null
    if (typeofobj ! = ='object') return obj;
    if (obj.constructor === Date) return new Date(obj);
    if (obj.constructor === RegExp) return new RegExp(obj);
    var newObj = new obj.constructor(); // Maintain the inheritance chain
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) { // Do not iterate over properties on its prototype chain
            var val = obj[key];
            newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // Use arguments.callee to uncouple function names}}return newObj;
}

function getNowFormatDate() {
    var date = new Date(a);var seperator1 = "-"; // Year month day interval
    var seperator2 = ":"; // The interval between minutes and seconds
    var month = date.getMonth() + 1;
    var strDate = date.getDate();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
    }
    var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate +
        "" + date.getHours() + seperator2 + date.getMinutes() +
        seperator2 + date.getSeconds();
    return currentdate;
}
Copy the code

4. Gulp reads the JSON file with the version number

That’s the easy part. You can reference JSON directly.

const versionInfo = require('./src/config/version/version.js');

You can also get the version number from the gulp command.

var minimist = require('minimist');
var argv = minimist(process.argv.slice(2), {
    string: ["name"]});console.log(argv.buildVersion)
Copy the code

Do the next step.


The completion of