内容简介:学习目录结构:
学习 node.js
生成文件、执行脚本,使用 CI
持续集成,自动构建 工具 之后,想要玩玩自己写点东西试试
- 命令行参数获取使用 commander.js
- 命令行交互使用 Inquirer.js
- 目录树生成使用 treer
目录结构:
D:\node-test ... ├─index.js ├─sh | └sh1.js ├─scripts | └generateComponent.js ├─components | ... | ├─run-sh.js ... 复制代码
D:\node-test
├─ components
├─ components-dir-tree1.json
├─ file.2.js
├─ file.bakeup.js
├─ file.js
├─ index.js
├─ log.js
├─ node-test-dir-tree.json
├─ run-sh.js
├─ test
└─ aa
├─ bb.js
└─ cc
└─ timeFormat.js
├─ index.js
├─ json
├─ a.json
└─ b.json
├─ package-lock.json
├─ package.json
├─ README.md
├─ scripts
└─ generateComponent.js
└─ sh
└─ sh1.js
复制代码
一、生成文件:
npm命令:
package.json:
{
...
"scripts": {
"create:comp": "node scripts/generateComponent --path",
},
...
}
复制代码
--path 这个参数的值可以通过下面获取到:
--path
可以自行设置,获取的时候 [path]
将作为 key
存到 program
const program = require('commander'); // 命令参数处理
program
.version('0.0.1')
.option('-l --path [path]', 'list of customers in CSV file')
.parse(process.argv);
// node scripts/generateComponents --path inputName
const inputName = program.path;
log('\ninputName: ',inputName);
复制代码
命令行交互 inquirer.js 简单使用:
-
name:字段名, 调用then的回调参数值里可以找到匹配的name, -
message:提示信息, - 其他的就是一些选项数据、默认值、过滤规则、校验、配置等
questions数组内一个子对象的 type
可以是:
(以下摘抄自 Inquirer.js )
-
confirm: yes/no,type,name,message, [,default] 属性 -
input: 键盘输入,type,name,message, [,default,filter,validate,transformer] 属性. -
number:type,name,message, [,default,filter,validate] 属性. -
rawlist: 类似于ol标签,有序列表,type,name,message,choices, [,default,filter] 属性 -
list: 类似于ul标签,无序列表,type,name,message,choices, [,default,filter] 属性 -
checkbox: 多选,type,name,message,choices, [,default,filter,validate] 属性 -
expand: 展开menu,type,name,message,choices, [,default] 属性 -
password:type,name,message,mask, [,default,filter,validate] 属性. -
editor:type,name,message,mask, [,default,filter,validate] 属性.
const questions = [
{
type: "confirm",
name: "override",
message: "是否覆盖?"
}
];
inquirer.prompt(questions).then(res => {
if (res.override) {
log('\n文件将被覆盖!');
resolve(path);
} else {
log('\n不覆盖已有文件!');
}
});
复制代码
更多的属性:
{
/* Preferred way: with promise */
filter() {
return new Promise(/* etc... */);
},
/* Legacy way: with this.async */
validate: function (input) {
// Declare function as asynchronous, and save the done callback
var done = this.async();
// Do async stuff
setTimeout(function() {
if (typeof input !== 'number') {
// Pass the return value in the done callback
done('You need to provide a number');
return;
}
// Pass the return value in the done callback
done(null, true);
}, 3000);
}
}
复制代码
生成文件 scripts/generateComponent.js:
const fs = require('fs');
const path = require('path');
const program = require('commander'); // 命令参数处理
const inquirer = require('inquirer'); // 选择
const chalk = require('chalk');
const log = (...text) => console.log(...text);
const componentDir = path.resolve(__dirname, '../components');
const newComp = `
const fs = require('fs');
const path = require('path');
console.log('这是一个自动生成的component');
`;
// npm scripts不能接收参数
// 下面需要 node 运行传入参数
program
.version('0.0.1')
.option('-l --path [path]', 'list of customers in CSV file')
.parse(process.argv);
// node scripts/generateComponents --path inputName
const inputName = program.path;
log('\ninputName: ',inputName);
const questions = [
{
type: "confirm",
name: "override",
message: "是否覆盖?"
}
];
mkdir(componentDir + `\\${inputName||'noname'}`)
.then(path => {
log('\n开始生成文件...');
return new Promise((resolve) => {
fs.writeFile(path+'\\index.js', newComp, 'utf-8', err => {
if (err) throw err;
log(`\n${path}\\index.js 文件创建成功!\n`);
resolve();
});
});
}).catch(err => {
throw err;
});
// 创建目录
function mkdir(path) {
return new Promise((resolve) => {
if (fs.existsSync(path)) {
log(`\n${path}: 文件夹已存在`);
// 命令行交互
inquirer.prompt(questions).then(res => {
if (res.override) {
log('\n文件将被覆盖!');
resolve(path);
} else {
log('\n不覆盖已有文件!');
}
});
} else {
fs.mkdirSync(path);
log('\n文件夹创建成功!');
resolve(path);
}
})
}
module.export = {
mkdir
}
复制代码
命令行打印的提示
- 新文件
$ npm run create:comp aa > test@1.0.0 create:comp D:\node-test > node scripts/generateComponent --path "aa" inputName: aa 文件夹创建成功! 开始生成文件... D:\node-test\components\aa\index.js 文件创建成功! 复制代码
- 文件已存在
$ npm run create:comp aa > test@1.0.0 create:comp D:\node-test > node scripts/generateComponent --path "aa" inputName: aa D:\node-test\components\aa: 文件夹已存在 ? 是否覆盖? No 不覆盖已有文件! 复制代码
二、执行脚本:
使用 child_process
子进程的 exec
执行脚本
以下内容,摘抄自Node.js 中文网
默认情况下, stdin
、 stdout
和 stderr
的管道在父 Node.js
进程和衍生的子进程之间建立。 这些管道具有有限的(和平台特定的)容量。 如果子进程在没有捕获输出的情况下写入超出该限制的 stdout
,则子进程将阻塞等待管道缓冲区接受更多的数据。 这与 shell
中的管道的行为相同。 如果不消费输出,则使用 { stdio: 'ignore' }
选项。
child_process.spawn()
方法异步地衍生子进程,且不阻塞 Node.js
事件循环。 child_process.spawnSync()
方法则以同步的方式提供等效功能,但会阻止事件循环直到衍生的进程退出或终止。
为方便起见, child_process
模块提供了 child_process.spawn()
和 child_process.spawnSync()
的一些同步和异步的替代方法。 注意,这些替代方法中的每一个都是基于 child_process.spawn()
或 child_process.spawnSync()
实现的。
-
child_process.exec(): 衍生一个shell并在该shell中运行命令,当完成时则将stdout和stderr传给回调函数。 -
child_process.execFile(): 类似于child_process.exec(),除了它默认会直接衍生命令且不首先衍生shell。 -
child_process.fork(): 衍生一个新的Node.js进程,并通过建立 IPC 通信通道来调用指定的模块,该通道允许在父进程与子进程之间发送消息。 -
child_process.execSync():child_process.exec()的同步版本,会阻塞Node.js事件循环。 -
child_process.execFileSync():child_process.execFile()的同步版本,会阻塞Node.js事件循环。 对于某些用例,例如自动化的shell脚本,同步的方法可能更方便。 但是在大多数情况下,同步的方法会对性能产生重大影响,因为它会停止事件循环直到衍生的进程完成。
npm命令:
package.json:
{
...
"scripts": {
"sh": "node components/run-sh.js",
},
...
}
复制代码
- 命令生成 sh/sh1.js:
使用npm命令时,需如上所示,在上面 package.json
中 scripts
配置好
const fs = require('fs');
const isDir = dir => fs.statSync(dir).isDirectory();
/**
* 返回相关的 shell 脚本
*/
// 打印指定目录
function ls(dir=null) {
if (dir) {
log('dir: ', dir);
return `cd ${dir} && ls`;
}
return "ls";
}
/**
* 构建前端项目
* @param {项目路径} dir
* @param {执行的 npm 命令} cmd
*/
function buildFE(dir, cmd) {
if (!dir || !isDir(dir) || !cmd) return;
log('build-dir: ', dir);
return `cd ${dir} && ${cmd}`;
}
module.exports = {
ls,
buildFE
}
复制代码
- 执行脚本 components/run-sh.js
// exec 执行shell命令
const { exec } = require('child_process');
const path = require('path');
require('./log');
const timeFormat = require('./timeFormat');
const { ls, buildFE } = require('../sh/sh1.js');
// console.log('sh: ',sh);
const shdir = path.resolve(__dirname, '../sh');
// 打印指定路径目录
//exec(ls('/code/react-t1'), (err, stdout, stderr) => {
// if (err) throw err;
// if ( stderr) log('stderr: ', stderr);
// // 执行的命令所打印的内容
// log('stdout: ', stdout);
// let nowTime = timeFormat({timestamp: new Date(), hasTime: true });
// log('time: ', nowTime);
//})
let nowTime = timeFormat({timestamp: new Date(), hasTime: true });
log('start--time: ', nowTime);
exec(buildFE('/code/react-t1', 'npm run build'), (err, stdout, stderr) => {
if (err) throw err;
if ( stderr) log('stderr: ', stderr);
// 执行的命令所打印的内容
log('stdout: ', stdout);
nowTime = timeFormat({timestamp: new Date(), hasTime: true });
log('end--time: ', nowTime);
})
复制代码
- 命令行打印:
$ npm run sh
> test@1.0.0 sh D:\node-test
> node components/run-sh.js
==log== start--time: 2019-05-08 16:29:24
==log== build-dir: /code/react-t1
==log== stdout:
> react-t1@0.1.0 build D:\code\react-t1
> node scripts/build.js
Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
62.73 KB docs\static\js\4.1fe71077.chunk.js
48.9 KB docs\static\js\7.70929cf8.chunk.js
14.3 KB docs\static\js\3.fe3cf9bc.chunk.js
13.3 KB docs\static\js\0.e70acbb7.chunk.js
3.22 KB docs\static\js\1.6f7cac0f.chunk.js
3.05 KB docs\static\js\2.ba0e413c.chunk.js
1.94 KB docs\static\js\main.eb84215c.chunk.js
1.48 KB docs\static\js\runtime~main.ff53614d.js
634 B docs\static\css\main.fde90119.chunk.css
592 B docs\static\js\8.d5307ac7.chunk.js
438 B docs\static\js\9.1544082f.chunk.js
434 B docs\static\css\0.451ae571.chunk.css
The project was built assuming it is hosted at ./.
You can control this with the homepage field in your package.json.
The docs folder is ready to be deployed.
Find out more about deployment here:
https://bit.ly/CRA-deploy
==log== end--time: 2019-05-08 16:29:31
==log== stderr: { parser: "babylon" } is deprecated; we now treat it as { parser: "babel" }.
复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
编程算法新手自学手册
管西京 / 机械工业 / 2012-1 / 69.80元
《编程算法新手自学手册》主要内容简介:算法是指在有限步骤内求解某一问题所使用的一组定义明确的规则。程序员都会看重数据结构和算法的作用,水平越高,就越能理解算法的重要性。算法不仅是运算工具,更是程序的灵魂。《编程算法新手自学手册》循序渐进、由浅入深地详细讲解了基于C语言算法的核心技术,并通过具体实例的实现过程演练了各个知识点的具体使用流程。全书共11章,分为4篇。1~2章是基础篇,介绍算法开发所必需......一起来看看 《编程算法新手自学手册》 这本书的介绍吧!