mixone
Version:
MixOne is a Node scaffolding tool implemented based on Vite, used for compiling HTML5, JavasCript, Vue, React and other codes. It supports packaging Web applications with multiple HTML entry points (BS architecture) and desktop installation packages (CS a
237 lines (230 loc) • 9.13 kB
JavaScript
const path = require('path');
const fs = require('fs');
const { spawn } = require('child_process');
const { Logger, createLogger } = require('./logger');
const { stdout } = require('process');
// 获取工作目录
const cwd = process.cwd();
// 获取命令行参数
const [command, ...args] = process.argv.slice(2);
// 新增:支持多种版本号命令
const VERSION_COMMANDS = ['-v', '-V', '-version', 'version'];
const viteErrLog = new createLogger('<red bold>[mixone cli] </red>');
if (VERSION_COMMANDS.includes(command)) {
let pkgPath, pkg;
try {
pkgPath = path.join(__dirname, 'package.json');
pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
} catch (e) {
console.error('Fail to read package.json:', e.message);
process.exit(1);
}
console.log(pkg.version);
// 读取 package.json 并输出 version
process.exit(0);
}
function readProjectPkg () {
let projectPkgFile = path.join(cwd, 'package.json');
try {
let projectPkg = JSON.parse(fs.readFileSync(projectPkgFile, 'utf-8'));
return projectPkg;
} catch (e) {
viteErrLog('Fail to read package.json:', e.message);
process.exit(1);
}
}
function checkVite () {
const nodeVersion = process.version;
const cleanStr = nodeVersion.replace(/^v/, '');
const [nodeMajor, nodeMinor] = cleanStr.split('.').map(Number);
const cleanViteStr = viteVersion.replace('^', '');
const [viteMajor, viteMinor] = cleanViteStr.split('.').map(Number);
if (viteMajor === 7 && nodeMajor < 20) {
viteErrLog(`vite7 requires a node version of 20.0 or above, current node version is ${nodeVersion}`);
process.exit(1);
}
else if ([5, 6].includes(viteMajor) && nodeMajor < 18) {
viteErrLog(`vite6 requires a node version of 18.0 or above, current node version is ${nodeVersion}`);
process.exit(1);
} else if ([4].includes(viteMajor) && nodeMajor < 16) {
viteErrLog(`vite4 requires a node version of 16.0 or above, current node version is ${nodeVersion}`);
process.exit(1);
}
}
let viteVersion, ppkg;
if (!['create'].includes(command)) {
ppkg = readProjectPkg();
viteVersion = ppkg.devDependencies ? (ppkg.devDependencies['vite'] ? ppkg.devDependencies['vite'] : '') : '';
checkVite();
}
// 支持的命令列表
const VALID_COMMANDS = ['create', 'compile', 'dev', 'serve', 'package', 'preview', 'build', 'watch','check'];
// 检查命令是否有效
if (!command || !VALID_COMMANDS.includes(command)) {
console.log('Please use the following command:');
console.log(' mixone create "Create a project"');
console.log(' mixone compile "Compile project"');
console.log(' mixone dev "Start the development mode"');
console.log(' mixone serve "Start the service"');
console.log(' mixone preview "Preview application"');
console.log(' mixone package "Package application"');
console.log(' mixone build "Build project"');
console.log(' mixone check "Check project dependencies"');
console.log(' mixone -v "View version number"');
process.exit(1);
}
// console.log(' mixone watch "Watch file changes"');
// 构建命令文件路径
const commandFile = path.join(__dirname, `${command}.js`);
// const byteCodeCli = path.join(__dirname,'node_modules','bytenode','lib','cli.js');
// 定义一个函数来使用 spawn 执行 serve.js
function runServeScript (cwd, args) {
const slog = new createLogger('<yellow bold>[serve process] </yellow>');
const serveProcess = spawn('node', ['devServe.js', ...args], {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: path.join(cwd, 'out')
});
let watchMode = args.includes('--watch')
let watchProcess = null;
serveProcess.stdout.on('data', (data) => {
if (!(data.indexOf('[vite]') > -1 && data.length == 7)) {
slog(`${data}`);
}
// process.stdout.write(output);
if (watchMode) {
const wlog = new createLogger('<brightMagenta bold>[watch process] </brightMagenta>');
if (data.indexOf('Local') > -1) {
watchProcess = spawn('node', [path.join(__dirname, 'watch.js')], {
stdio: ['pipe', 'pipe', 'pipe']
});
watchProcess.stdout.on('data', (data) => {
wlog(`${data}`);
})
watchProcess.on('close', (code) => {
wlog(`<red>watch process exit</red>,code: ${code}`)
})
watchProcess.on('error', (err) => {
wlog(`<red>watch process error</red>: ${err}`)
})
}
}
});
serveProcess.stderr.on('data', (data) => {
slog(`<red>${data}</red>`);
});
serveProcess.on('close', (code) => {
if (watchProcess) {
watchProcess.kill('SIGTERM');
}
if (code !== 0) {
slog(`serve.js <red>exit</red>,code: ${code}`)
process.exit(code);
}
});
serveProcess.on('error', (err) => {
if (watchProcess) {
watchProcess.kill('SIGTERM');
}
});
}
// 执行对应的命令
try {
if (command === 'dev') {
// 使用 spawn 调用 node 执行 compile.js
const compileProcess = spawn('node', [path.join(__dirname, 'compile.js'), ...args], { stdio: 'inherit' });
compileProcess.on('close', (code) => {
if (code !== 0) {
console.error(`compile.js exit,code: ${code}`);
process.exit(code);
} else {
// 调用独立的函数来执行 serve.js
runServeScript(cwd, args);
}
});
} else if (command == 'compile') {
// 使用 spawn 调用 node 执行 compile.js
const compileProcess = spawn('node', [path.join(__dirname, 'compile.js'), ...args], { stdio: 'inherit' });
compileProcess.on('close', (code) => {
if (code !== 0) {
console.error(`compile.js Process exit, exit code: ${code}`);
process.exit(code);
}
});
} else if (command == 'watch') {
const watcherCli = path.join(__dirname, 'watch.js');
const watchProcess = spawn('node', [watcherCli, ...args], { stdio: 'inherit' });
process.on('SIGINT', () => {
watchProcess.kill('SIGTERM');
console.log('The monitoring process has been terminated');
process.exit();
});
watchProcess.on('close', (code) => {
console.log(`watch process exit, exit code: ${code}`);
});
} else if (command == 'serve') {
runServeScript(cwd, args);
} else if (command == 'preview') {
const compileProcess = spawn('node', [path.join(__dirname, 'preview.js'), ...args], { stdio: 'inherit' });
compileProcess.on('close', (code) => {
if (code !== 0) {
console.error(`preview.js Process exit, exit code: ${code}`);
process.exit(code);
}
});
} else if (command == 'package') {
const compileProcess = spawn('node', [path.join(__dirname, 'package.js'), ...args], { stdio: 'inherit' });
compileProcess.on('close', (code) => {
if (code !== 0) {
console.error(`package.js Process exit, exit code: ${code}`);
process.exit(code);
}
});
} else if (command == 'build') {
const compileProcess = spawn('node', [path.join(__dirname, 'build.js'), ...args], { stdio: 'inherit' });
compileProcess.on('close', (code) => {
if (code !== 0) {
console.error(`build.js Process exit, exit code: ${code}`);
process.exit(code);
}
});
} else if (command == 'create') {
// 获取项目名称(第一个参数)
const projectName = args[0] || 'electron-app';
const projectOutDir = projectName + path.sep + 'out';
// 构建项目路径
const projectPath = path.join(cwd, projectOutDir);
// 使用 spawn 调用 node 执行 compile.js
const compileProcess = spawn('node', [path.join(__dirname, 'project.js'), ...args], { stdio: 'inherit' });
compileProcess.on('close', (code) => {
if (code !== 0) {
console.error(`project.js Process exit, exit code: ${code}`);
process.exit(code);
} else {
const clog = new createLogger('<yellow bold>[project process] </yellow>');
clog(`<green>The project has been successfully created.</green> Preview it by executing the following command`);
clog(`<white>cd ${projectName}</white>`);
clog(`<white>npm install</white>`);
clog(`<white>npm run dev</white>`);
}
});
} else if (command == 'check') {
const checkProcess = spawn('node', [path.join(__dirname, 'check.js'), ...args], { stdio: 'inherit' });
checkProcess.on('close', (code) => {
if (code !== 0) {
console.error(`check.js Process exit, exit code: ${code}`);
process.exit(code);
}
});
} else {
// 检查命令文件是否存在
if (!fs.existsSync(commandFile)) {
console.error(`Error: The file corresponding to the command "${command}" does not exist`);
process.exit(1);
}
require(commandFile);
}
} catch (err) {
console.error(`An error occurred when executing the command "${command}" :`, err);
process.exit(1);
}