16-利用node构建自己的脚手架工具¶
统计信息:字数 5371 阅读11分钟
课程大纲¶
1、如何利用node编写命令行脚本(操作命令行) 2、脚手架工具常用的包有哪些 3、带你手撸一个自己的 vue-cli
可以自己做项目专属的脚手架工具
如何操作命令行¶
npm run build
执行的是 build.js 脚本
常见的 nodeJS 包¶
chalk 输出不同颜色的文字(开发脚本的效果的包)
ora loading 的效果
commander 解析命令(-v)
inquirer 提问查询的包(npm init 然后会提问,名称是什么)
练习 build.js
process.env.NODE_ENV = 'production';
const ora = require('ora');
const rm = require('rimraf');
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const config = require('../config');
const webpackConfig = require('./webpack.prod.conf');
// 开始loading状态
const spinner = ora('building for production...loading...');
spinner.start();
const { assetsRoot, assetsSubDirectory } = config.build;
rm(path.join(assetsRoot, assetsSubDirectory), err => {
if (err) {
throw err;
}
webpack(webpackConfig, (err, stats) => {
// webpack 编译结束后,停止loading状态
spinner.stop();
if (err) {
throw err;
}
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // if use ts-loader, set this true
chunks: false,
chunkModules: false
}) + '\n\n');
if (stats.hasError()) {
// handle error
console.log(chalk.red('Build failed with errors.\n'));
process.exit(1);
}
console.log(chalk.cyan('Build complete.\n'));
});
});
下面是一步一步的教程
npm install chalk ora commander inquirer --save
const chalk = require('chalk');
console.log(chalk.red.bgBlue('Hello'));
console.log(chalk.rgb(126,126,126).bgRgb(22,33,89)('hello'));
const spinner = ora('this is a loading').start();
spinner.color = 'yellow';
spinner.text = 'hello nodeJS';
setTimeout(function() {
spinner.stop();
}, 3000);
自定义命令 package.json
{
"bin": {
"mytool": 'index.js'
}
}
如果已经发布这个库,直接运行执行脚本即可。如果没有发布,本地首先运行 npm link 链接(可能报错,链接多次),然后才能正常使用命令。
Index.js 脚本
#!/usr/bin/env node
const cm = require('commander');
const iq = require('inquirer');
cm.version('1.0.0', '-v, --version');
cm.option('-a -atest', 'this is test');
console.log(1);
cm.command('init <name>').action((name) => {
console.log(name);
iq.prompt([
{
type: 'input',
name: 'author',
message: 'what is your name'
}
]).then((answers) => {
require('./bin/dowuload.js')(answers.author);
});
});
cm.parse(process.argv);
download.js
const fs = require('fs');
const chalk = require('chalk');
const ora = require('ora');
module.exports = function(answer) {
// 数据驱动
// fs.readFile fs.read fs.createWriteStream
//[
// {type: 'file', path: './app.js'},
// {type: 'dir', path: './src'},
// {type: 'dir', path: './src/route'},
//]
const demoPath = './project';
const targetPath = './' + answer;
const ob = [];
function downdemo() {
// fs.mkdir(targetPath, () => { pushArr(demoPath); });
pushArr(demoPath);
console.log(ob);
ob.forEach((item) => {
if (ob[i][0] == 'file') {
fs.readFile(ob[i][1], (err, data) => {
fs.writeFile(targetPath + '/' + ob);
});
} else {
fs.mkdir(targetPath + '/' + item[1].replace('./project', ''), function() {})
}
});
}
function pushArr(path) {
fs.readdir(path, function(files) {
files.forEach((item, index) => {
fs.stat(path + '/' + item, (err, stat) => {
if (stat.isDirectory()) {
ob.push(['dir', path]);
pushArr(path + '/' + item);
} else {
ob.push(['file', path]);
}
});
});
});
}
}
如何构建CLI¶
项目脚手架 Vue-cli
- 下载项目初始化模板
- 定义项目规则
- 定义项目操作命令
CLI 工具工作流程:用户输出初始化命令-打开脚本与用户交互-根据命令下载模板-模板下载成功-提示用户
递归,每次递归将文件路径拿出来,变成数组;然后遍历数组,创建文件
具体的文件不好操作时,先把树结构抽象出来;创建文件和创建文件夹;读写和遍历,耦合比较高
读写文件是异步操作;循环中如果有异步操作,node,最好是forEach,避免异步
for循环会造成异步错误
前端为什么趋向于软件工程?前端现在变成独立的种类。前端项目的复杂化,带来难度增加,所以软件工程内容开始在前端出现。
工程化:标准
- 命令行工具:vue-cli react-create-app
- 规范 ESLint
- 测试:单元测试,e2e
- 构建:webpack
- 集成和部署:CI CD docker
- 代码管理:git
自己尝试把SDK打包压缩了,现在只是babel处理了,没有压缩(现在只是编译成ES5,没有打包和压缩,实际上可以使用webpack压缩,因为内部三个模块是互相依存的,对外输出一个模块);自己的JS基础要很扎实,否则后期工程化会遇到很多问题;
Last update:
November 9, 2024