Skip to content

创建 npm 脚手架

  • 基本内容

index.js
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

help.js
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('')
    })
}
  • 创建命令

create.js
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
  • 创建行为

actions.js
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: []
}