dws-cli-ui
Version:
dws-cli dws系列:包括大屏、移动端、设计器项目等待
445 lines (341 loc) • 11.5 kB
Markdown
>"main": "index.js", // 入口文件
```json
{
"name": "dws-cli",
"version": "1.0.0",
"description": "dws-系列cli / 包括大屏、移动端、设计器项目等待",
"main": "index.js", // 入口文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://gitee.com/uidkj/dws-cli.git"
},
"keywords": [],
"author": "",
"license": "ISC"
}
```
> "bin": { "dws": "index.js" } // 配置bin,是告诉执行环境dws这个指令
```json
{
"bin": {
"dws": "index.js"
}
}
```
```shell
npm link
```
> `
```shell
console.log('dws cli')
```
```shell
npm install commander download-git-repo inquirer@8.2.5 ejs chalk@4.1.2 open --save
npm install commander --save
npm install download-git-repo --save
npm install inquirer@8.2.5 --save
npm install ejs --save
npm install chalk@4.1.2 --save
npm install open --save
```
[**commander使用说明 **](https://blog.csdn.net/Ardently_life/article/details/104483035)
> commander.js是node.js的轻量级,富有表现力和强大的命令行框架
>
> npm install commander --save
```js
const program = require('commander');
program
// version方法:定义命令行程序的版本号,第一个参数是版本号,第二个参数是自定义flag 自定义flag可省略
// 默认为-V和--version 执行 node index.js -V 或者 node index.js --version得到版本号
.version('1.0.0', '-s, --version')
.description('It is my cli') // 描述
// .option('-a,--add','add something') 第一个参数为flag,第二个参数为当选项的描述可省略
//短flag使用-,长flag使用--
//执行 node index.js -a 或者 node index.js -add 会打印Youchoose:add something
.option('-a,--add','add something')
.option('-u,--update','update something')
.option('-r,--remove','remove somthing')
.parse(process.argv) // 回调函数 parse方法:用于解析process.argv 参数说明
if(program.add) console.log(' add somthing')
if(program.update) console.log(' update something')
if(program.remove) console.log(' remove something')
.parse(process.argv)
```
```js
const program = require('commander');
const helpOptions = require('./lib/core/help');
const createCommands = require('./lib/core/create');
const log = require('./lib/utils/log');
// 定义显示模块的版本号
program.version(require('./package.json').version);
// 给help增加其他选项
helpOptions();
// 创建命令
createCommands();
// 解析终端指令
program.parse(process.argv);
```
```js
// lib/core/help.js
const program = require('commander');
const helpOptions = () => {
program.option('-w --why', 'a coderwhy option');
program.option('-s --src <src>', 'a source folder');
program.option('-d --dest <dest>', 'a destination folder, 例如: -d src/pages, 错误/src/pages');
program.option('-f --framework <framework>', 'your framework name');
program.on('--help', function() {
console.log("");
console.log("usage");
console.log(" coderwhy -v");
console.log(" coderwhy -version");
})
}
module.exports = helpOptions;
```
```js
const program = require('commander')
const { createProject, addComponent, addPage, addStore } = require('./actions')
// 创建项目指令
const createCommands = () => {
// 创建create指令
program
.command('create <project> [otherArgs...]')
.description('clone a repository into a newly created directory')
.action(createProject)
// 创建addcpn指令
program
.command('addcpn <name>')
.description(
'add vue component, 例如: coderwhy addcpn NavBar [-d src/components]'
)
// name项目名称,others:输入参数
.action((name,others) => addComponent(name, program.dest || 'src/components'))
// 创建addpage指令
program
.command('addpage <name>')
.description('add vue page, 例如: coderwhy addpage Home [-d dest]')
.action((name) => {
addPage(name, program.dest || `src/pages/${name.toLowerCase()}`)
})
program
.command('addstore <name>')
.description('add vue store, 例如: coderwhy addstore favor [-d dest]')
.action((name) => {
addStore(name, program.dest || `src/store/modules/${name.toLowerCase()}`)
})
program.command('test').action(() => {
// terminal.spawn("npm", ['--version']);
// terminal.exec("npm --version");
// open('http://localhost:8080/');`
})
}
module.exports = createCommands
```
> 封装一个actions函数
>
> 安装 npm install download-git-repo
```js
const path = require('path');
const fs = require('fs');
const { promisify } = require('util'); // util(node库)把异步转同步
const program = require('commander');
const downloadRepo = promisify(require('download-git-repo')); // 下载项目模板 download-git-repo
const open = require('open');
const log = require('../utils/log');
const terminal = require('../utils/terminal');
const { ejsCompile, writeFile, mkdirSync } = require('../utils/file');
const repoConfig = require('../config/repo_config');
/**
* 1.提示信息
* 2.clone项目从仓库
* 3.执行终端命令npm install
* 4.打开浏览器
* 5.运行项目
*/
const createProject = async (project, otherArg) => {
// 1.提示信息
log.hint('coderwhy helps you create your project, please wait a moment~');
// 2.clone项目从仓库
await downloadRepo(repoConfig.vueGitRepo, project, { clone: true });
// 3.执行终端命令npm install
// terminal.exec('npm install', {cwd: `./${project}`});
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
await terminal.spawn(npm, ['install'], { cwd: `./${project}` });
// 4.打开浏览器
open('http://localhost:8080/');
// 5.运行项目
await terminal.spawn(npm, ['run', 'serve'], { cwd: `./${project}` });
}
// 对Ejs的操作
const handleEjsToFile = async (name, dest, template, filename) => {
// 1.获取模块引擎的路径
const templatePath = path.resolve(__dirname, template);
const result = await ejsCompile(templatePath, {name, lowerName: name.toLowerCase()});
// 2.写入文件中
// 判断文件不存在,那么就创建文件
mkdirSync(dest);
const targetPath = path.resolve(dest, filename);
writeFile(targetPath, result);
}
const addComponent = async (name, dest) => {
handleEjsToFile(name, dest, '../template/component.vue.ejs', `${name}.vue`);
}
const addPage = async (name, dest) => {
addComponent(name, dest);
handleEjsToFile(name, dest, '../template/vue-router.js.ejs', 'router.js')
}
const addStore = async (name, dest) => {
handleEjsToFile(name, dest, '../template/vue-store.js.ejs', 'index.js')
handleEjsToFile(name, dest, '../template/vue-types.js.ejs', 'types.js')
}
module.exports = { createProject, addComponent, addPage, addStore}
```
[【Inquirer与命令行交互库】](https://blog.csdn.net/qq_26733915/article/details/80461257)
```js
// npm install inquirer
const setProjectInfo = async () => {
const tagsList = configJson
const promptList = [
{ type: "password", message: "请输入密码:", name: "pwd" }, // 密码为密文输入
{ type: "input", message: "设置一个用户名:", name: "name", default: "test_user" }, // default: "test_user" 默认值
{ type: "confirm", message: "是否使用监听?", name: "watch", prefix: "前缀" },
// 当watch为true的时候才会提问当前问题
{ type: "confirm", message: "是否进行文件过滤?", name: "filter", suffix: "后缀", when: answers => answers.watch },
//checkbox有2种 pageSize设置行数
{ type: "checkbox", message: "选择颜色:", name: "color", choices: ["red", "blur", "green", "yellow"], pageSize: 2 },
{
type: "checkbox",
message: "选择颜色:",
name: "color",
choices: [
{ name: "red" },
{ name: "blur", checked: true }, // 默认选中
{ name: "green" },
new inquirer.Separator("--- 分隔符 ---"), //空为默认,也可以自定义分隔符
{ name: "yellow" }
]
},
{ type: "list", name: "tag", choices: tagsList, message: "Place choose a tag to create project" },
{
type: "list", // 'rawlist'
message: "请选择一种水果:",
name: "fruit",
choices: ["Apple", "Pear", "Banana"],
filter: val => val.toLowerCase() // 使用filter将回答变为小写
},
{
type: "input",
message: "请输入手机号:",
name: "phone", // 校验位数
validate: function (val) {
if (val.match(/\d{11}/g)) return val
return "请输入11位数字"
}
},
{
type: "expand",
message: "请选择一种水果:",
name: "fruit",
choices: [
{ key: "a", name: "Apple", value: "apple" },
{ key: "O", name: "Orange", value: "orange" },
{ key: "p", name: "Pear", value: "pear" }
]
}
]
const { tag } = await inquirer.prompt(promptList[0])
return tag
}
module.exports = setProjectInfo
```
> 创建component.vue.ejs模板(已vue2做示例)
```vue
<template>
<div class="<%= data.lowerName %>">
<h2>{{ message }}</h2>
</div>
</template>
<script>
export default {
name: "<%= data.name %>",
components: {
},
mixins: [],
props: {
},
data: function() {
return {
message: "Hello <%= data.name %>"
}
},
created: function() {
},
mounted: function() {
},
computed: {
},
methods: {
}
}
</script>
<style scoped>
.<%= data.lowerName %> {
}
</style>
```
```js
const fs = require('fs')
const path = require('path')
const ejs = require('ejs')
const log = require('./log')
const ejsCompile = (templatePath, data = {}, options = {}) => {
return new Promise((resolve, reject) => {
ejs.renderFile(templatePath, { data }, options, (err, str) => {
if (err) {
reject(err)
return
}
resolve(str)
})
})
}
const writeFile = (path, content) => {
if (fs.existsSync(path)) {
log.error('the file already exists~')
return
}
return fs.promises.writeFile(path, content)
}
const mkdirSync = (dirname) => {
if (fs.existsSync(dirname)) {
return true
} else {
// 不存在,判断父亲文件夹是否存在?
if (mkdirSync(path.dirname(dirname))) {
// 存在父亲文件,就直接新建该文件
fs.mkdirSync(dirname)
return true
}
}
}
module.exports = { ejsCompile, writeFile, mkdirSync }
```