UNPKG

dws-cli-ui

Version:

dws-cli dws系列:包括大屏、移动端、设计器项目等待

445 lines (341 loc) 11.5 kB
# 创建VUE-CLI脚手架制作 ## package.json >"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" } ``` ### 1.bin > "bin": { "dws": "index.js" } // 配置bin,是告诉执行环境dws这个指令 ```json { "bin": { "dws": "index.js" } } ``` ```shell npm link # 执行npm link,会让当前的bin与环境变量做个连接 ``` ### 2.sha-bang指令 > `#! /usr/bin/env node` 当前环境找到node来执行(配置环境来执行这个文件 ) ```shell #! /usr/bin/env node console.log('dws cli') # 执行dws 会打印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 ``` ### 1.安装commander及说明 [**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) ``` ### 2.创建根目录入口文件 ```js #!/usr/bin/env node 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); ``` ### 3.创建helpOptions帮助说明 ```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; ``` ### 4.创建createCommands创建命令 ```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} ``` ### 5.安装 与命令行交互库 [【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 ``` ### 6.创建ejs模板 > 创建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> ``` ### 7.读ejs模板,写文件 ```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 } ```