创建 npm 脚手架
基本内容
js
#!/usr/bin/env node
//自动执行 配置node路径 shebang
const program = require('commander')
const getHelp = require('./lib/core/help')
const createCommand = require('./lib/core/create')
// 查看版本号
program.version(require('./package.json').version)
// 增加options与 help
getHelp();
// 创建其他指令
createCommand()
// console.log('dest', program.dest);
// 监听某一指令
// program.on('--help', function (val) {
// console.log('--help 参数', val);
// })
// 获取 -p 结果
// console.log('process.port', process.port)
// 解析终端指令
program.parse(process.argv);
配置options
js
const program = require('commander');
// 监听某一指令
module.exports = getHelp = () => {
program.option('-d, --dest <dest>', 'destination ,描述信息')
program.on('--help', function (val) {
console.log('')
console.log('Other:')
console.log('')
})
}
创建命令
js
const program = require('commander')
const { createProject, addpage, addApi, addRouter } = require('./actions')
const createCommand = function () {
// 创建工程
program
.command('create <name> [others...]')
.description('clone repository into a folder')
.action(createProject)
// 添加 组件模板
program
.command('addCmp <name>')
.description('创建Components;例如:创建Components yhx addCmp name [-d src/Componentss] ')
.action((name) => addpage(name, program.dest || 'src/components'))
// 添加路由
program
.command('addRouter <name>')
.description('创建router;例如:创建router yhx addRouter name')
.action((name) => addRouter(name , program.dest || 'src/views'))
// 添加api模板
program
.command('addApi <name>')
.description('创建api;例如:创建api yhx addApi name [-d src/apis] ')
.action((name) => addApi(name, program.dest || 'src/apis'))
}
module.exports = createCommand
创建行为
js
const { promisify } = require('util') // 异步回调转成 promise
const download = promisify(require('download-git-repo')) //为了git clone
// const open = require('open')
const { VueRepo } = require('../config/repo-config')
const { commandSpawn } = require('../utils/terminal')
const fs = require('fs')
const path = require('path')
// const log = require('../utils/log');
const { ejsCompile, writeFile, mkdirSync } = require('../utils/files');
const createProject = async (name, ...args) => {
// 1.执行 gitclone 命令
await download(VueRepo, name, { clone: true })
// git clone https://gitee.com/yhx825/yhxnotedist.git
// 2.npm install
// windows npm 报错 实际上执行的是 npm.cmd
const command = process.platform === 'win32' ? 'npm.cmd' : 'npm'
await commandSpawn(command, ['install'], { cwd: `./${name}` })
// 3.npm run dev
commandSpawn(command, ['run', 'serve'], { cwd: `./${name}` })
// 动画库
// install 下载 动画
// 4.打开浏览器
// open("http://localhost:8080/")
// 选项询问向 vue3 Inquirer插件实现
}
const handleEjsToFile = async (name, dest, template, filename) => {
// 1.获取模块引擎的路径
const templatePath = path.resolve(__dirname, template);
const cpnPath = `${dest.replace('router', 'views').replace("src", "@") }/${name}/${filename}`
const routePath = `${dest.replace('/router', '').replace('src', '')}/${ name }/${name}.vue`
const result = await ejsCompile(templatePath, { name, lowerName: name.toLowerCase(), cpnPath , routePath });
// 2.写入文件中
const targetPath = path.resolve(dest, name);
mkdirSync(targetPath);
writeFile(path.resolve(targetPath, filename), result);
}
const addpage = async (name, dest, template = '../templates/vue-component.vue.ejs', extname = "vue") => {
handleEjsToFile(name, dest, template, `${name}.${extname}`);
}
const addRouter = async (name, dest) => {
addpage(name, dest, '../templates/vue-component.vue.ejs', 'vue');
// 添加路由 这里是不正确的 每次添加 应该去重写 routerjs 或者直接 按目录生成路由结构
handleEjsToFile(name, dest, '../templates/vue-router.js.ejs', 'router.js')
}
const addApi = (name, dest) => {
//添加一个api模板页面
addpage(name, dest, '../templates/api.js.ejs', 'js');
}
module.exports = {
createProject,
addpage,
addRouter,
addApi
}
添加模板
ejs
import { request } from "@/utils/request.js";
/**
* @description <%= data.description %>
* @export
* @param
* @return {*}
*/
export function <%= data.name %>(data) {
return request({
url: '<%= data.url %>',
method: 'post',
data
})
}
ejs
<script setup name="<%= data.lowerName %>">
</script>
<template>
<div class="<%= data.lowerName %>">
<h2>
<%= data.lowerName %>
</h2>
</div>
</template>
<style scoped>
.<%=data.lowerName %> {
}
</style>
ejs
const <%= data.name %> = () => import('<%= data.cpnPath %>')
export default {
path: '<%= data.routePath %>',
name: '<%= data.name %>',
component: <%= data.name %>,
children: []
}