Node自定义 vue-cli

146 阅读3分钟

1. 项目初始化 启动第一步

初始化项目 npm init -y -y是默认选项

2. 自定义终端命令

package.json 文件内修改 bin 相关配置

    "bin": {
        "mun": "index.js"
    }

在启动文件 index.js 首行配置 #!/usr/bin/env node 该命令是值 在当前电脑内 找到 node 指令

最后一步 使用 npm link 将 bin 和环境变量进行链接 注意:如使用 mac 电脑 需加上 sudo

配置完成后 在终端中输入 mun 即可执行 index.js文件

3. 配置自定义命令

1. 配置版本号

首先需要引用 commander 第三放模块 通过 npm install commander 下载

2. commander使用 及 命令

  1. 配置版本号 index.js
        // 配置版本号
        const progam = require("commander");
    
        progam.version(require("package.json");  // 动态获取package 文件中的 版本号
    
        // 将 options 添加到 dev 中
        proagm.parse(process.dev);
    
  2. 配置自定义指令 bin/core/help
    // 1. 导入 commander
    const progam = require("commander");
    
    // 2. 增加 options 
    const helpOptions = () => {
        proagm.option('-w --why', 'w is yum');  // 配置命令为 --why 简称 -w 后面的是描述
        progam.option('-d --dest <dest>', '表述 <dest> 是必选参数 例如: -d src/component')  // dest 必选参数
    
        // 监听指令  指令执行就会触发回掉函数
        proagm.on('--help', function () {
            console.log("触发回掉函数")
        })
    }
    
  3. 配置 自定义命令 bin/core/create
       const progam = require('commander');
    
       const createCommander = () => {
           // 1. 
           progam.command('create <create> [options...]')  // 例如: mun create a option 打印 create options
           .description("提示信息")  // 提示信息
           .action((create, options) => {
               console.log("执行")
               console.log(create, options);
           })  // .action("执行函数")
    
       };
    
       // 导出
       moduel.exports = createCommander;
    

开始编写

  1. 我们将 .action 中的函数抽取出来 放到 action.js 文件中进行编写 bin/core/action
        // 倒入系统模块 用于判断函数中是否有 err 参数 有 转换成promise
        const { promisity } = require("uitl");
    
        // 第三方库 用于克隆 github 上的模版  
        const download = promisity(require("download-git-repo");
        const open = require("open");
        
        // 导入 util 的 terminal 
        const commanderSpawn = require("./../utils/terminal");
        
        // 导入 定义的github 地址 这里就不过多演示了
        const vueRepo = require("./../config/repo-config");
    
        const actionOption = async (create, options) => {
            // 1. 从 github 上 将模版克隆下来
            // await download('地址', 路径, '克隆');
            await download(vueRepo, create, {close: true});
            
            // 2. 我们将 此操作抽取 到 util 中 
            // npm 为 要运行的命令。['install'] 为 运行指令 {cwd: } 为 当前工作目录
            // 判断操作系统  windows系统是 npm.cmd 而其他电脑是 npm
            const command = process.platform === 'win32' ? 'npm.cmd' : 'npm';
            await commmanderSpawn(command, ['install'], {cwd: `./${create}`});
            
            // 3. 运行 npm run server
             await commanderSpawn(command, ['run', 'server'], {cwd: `./${create}`})
             
            // 4. 打开浏览器 这里使用第三方库 open
            open("https://localhost:8000/");
        };
        
        // 导出
        module.exports = {
            actionOption
        }
    
    util>terminal.js
        // 1. 倒入系统模块
        const { spawn } = require("child_process");
        
        // 2. 开启子进程
        const commanderSpawn = (...args) => {
           return new Promise((resolve, reject), () => {
               // 开启进程
               const childProcess = spawn(...args);
    
               // 合并 terminal 中的信息
               childProcess.stdout.pipe(process.stdout);
               childProcess.stderr.pipe(process.stderr);
    
               // 监听结束
               childProcess.on('close', () => {
                    // 执行 
                    resolve();
               });
           })
        }
    

继续编写创建页面和路由相关配置

bin>core/create

    const progam = require("commander");
    
    const {
        createProjectAction,
        addPageAndRouter
    } = require("./action");
    
    const createComnander = () => {
        progam.command("addPage <name>")
        .description("文件描述")
        .action((name) => {
            createProjectAction(name, progam._optionValues.desc || 'src/component')
        });
        
        progam.command("addpage <name>")
        .description("创建文件及路由")
        .action((name) => {
            addPageAndRouter(name, progam._optionValues.desc || "src/pages");
        })
    }

bin>core/action

    const { writeToFile, compile } = require("./../util/utils");

    // 创建单个文件
    const createProjectAction = async (name, desc) => {
        // 1. 解析 ejs 文件
        const data = {name, lowerName: name.toLowerCase()};
        const result = await compile(name, data);
        // 2. 获取文件地址
        const targetPath = path.resolve(__dirname, desc);
        // 3. 写入文件
        writeToFile(targetPath, result);
    };
    
    // 创建单个文件及路由
    const addPageAndRouter = (name, desc) => {
        // 1. 解析 ejs 文件
        const data = {name, lowerName: name.toLowerCase()};
        const pageResult = await compile(name, data);
        const routerResult = await compile(name, data);
        
        // 2. 获取 文件目录
        const targetPagePath = path.resolve(__dirname, `${desc}.vue`);
        const targetRouterpath = path.resolve(__dirname, "router.js");
        
        // 3. 写入文件
        writeToFile(targetPagePath, pageResult);
        writeToFile(targetRouterPath, routerResult);
    };
    
    module.exports = {
        createProjectAction,
        addPageAndRouter
    };

core/util/uitls

    const fs = require("fs");
    const path = require("path");

    // 解析 ejs 文件  需要安装 ejs 第三方模块
    const ejs = require("ejs")
    
    // ejs
    const compile = (template, data) => {
        // 1. 获取文件路径
        const templatePosition = `../template/${template}`;
        const templatePath = path.resolve(__dirname, templatePosition);
        
        // 2. 解析文件
        return new Promise((resolve, reject) => {
            ejs.renderFile(templatePath, { data }, {}, (err, res) => {
                if (err) reject(err);
                resolve(res);
            }
        })
    }

    // 写入内容工具
    const writeToFile = (path, content) {
        return fs.writeFile(path, content);
    }
    
    module.exports = {
        writeToFile
    }