背景
当每次打包生产环境时的小程序包时,需要在命令行中输入版本号,可以根据项目的需求对输入的版本号进行个性化配置,此版本号会影响到项目的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
函数主要做了这么几件事
- 在命令行输出一个比较漂亮的
PMS
,没有用就是为了好玩
// 设置 命令行的一些样式
const init = () => {
console.log(
chalk.green(
figlet.textSync('PMS', {
font: 'Ghost',
horizontalLayout: 'default',
verticalLayout: 'default'
})
)
);
};
- 然后执行
isNeedVersion
函数,这个函数也就只做了一件事情,就是在提供一个命令行的交互,问一下使用者是否需要打包为正式版本并携带版本号
// 是否需要版本号
const isNeedVersion = () => {
const questions = [
{
name: 'NEED_VERSION',
type: 'list',
message: '是否需要打包为正式版本并携带版本号',
choices: ['需要', '不需要']
}
];
return inquirer.prompt(questions);
};
若是需要打包,则会走打包的流程,不然就时直接打包
- 需要打包,则会走
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.json
中scripts
字段进行处理,利用cross-env
为项目增加了一个RELEASE
,打包完之后,就可以在项目中使用RELEASE
获取打包之后的版本号啦,无论是在接口请求中还是页面展示都可以使用。