前端工程化- 实现简易 CLI

简介: 前端工程化- 实现简易 CLI

创建工程

  • 初始化

    mkdir kkb-vue-auto-router-cli
    cd kkb-vue-auto-router-cli
    npm init -y
    npm i commander download-git-repo ora handlebars figlet clear chalk open -s
  • 设置启动入口
    bin/kkb.js

    #!/usr/bin/env node
    console.log('cli....');

    package.json

    "bin": {
      "kkb": "./bin/kkb.js"
    }
  • 将npm 模块链接到对应的运⾏项⽬目中去,相当于设置全局命令或全局安装

    npm link
    
    # 安装完成测试
    kkb # 输出 cli...

定制命令行界面

  • 初始化交互
    kkb.js

    #!/usr/bin/env node
    const program = require('commander');
    program.version(require('../package').version);
    
    program
      .command('init <name>')
      .description('init project')
      .action(name => {
        console.log(`init ${name}`);
      });
    
    program.parse(process.argv);

    测试

    kkb init test-app
    # 输出 init test-app
  • 将初始化模块化,并制作欢迎界面
    lib/init.js

    const { promisify } = require('util');
    const figlet = promisify(require('figlet'));
    const clear = require('clear');
    const chalk = require('chalk');
    const log = content => console.log(chalk.green(content));
    
    module.exports = async name =>  {
      clear();
      const data = await figlet('KKB Welcome');
      log(data);
    };

    kkb.js

    #!/usr/bin/env node
    const program = require('commander');
    program.version(require('../package').version);
    
    program
      .command('init <name>')
      .description('init project')
      .action(require('../lib/init'));
    
    program.parse(process.argv);

远程下载

  • 添加下载模块
    lib\download.js

    const { promisify } = require('util');
    
    const downloadGitRepo = require('download-git-repo');
    const ora = require('ora');
    
    module.exports.clone = async function(repo, desc) {
      const download = promisify(downloadGitRepo);
      const process = ora(`下载...${repo}`);
      process.start();
      await download(repo, desc);
      process.succeed();
    }
  • 下载模板
    lib\init.js

    const { promisify } = require('util');
    const figlet = promisify(require('figlet'));
    const clear = require('clear');
    const chalk = require('chalk');
    const log = content => console.log(chalk.green(content));
    const { clone } = require('./download');
    
    module.exports.init = async name =>  {
      // 欢迎界面
      clear();
      const data = await figlet('KKB Welcome');
      log(data);
      // 下载模板
      await clone('github:cellinlab/vue-template', name);
    };
  • 测试

    kkb init testapp

安装依赖

lib/init.js

// ...
module.exports.init = async name =>  {
  // ...

  // 安装依赖
  log('安装依赖');
  await spawn(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['install'], { cwd: `./${name}` });
  log(chalk.green(`
安装完成:
To get Start:
===========================
cd ${name}
npm run serve
===========================
 `))
};

// 对接输出流
const spawn = async (...args) => {
  const { spawn } = require('child_process');
  return new Promise((resolve, reject) => {
    const proc = spawn(...args);
    proc.stdout.pipe(process.stdout);
    proc.stderr.pipe(process.stderr);
    proc.on('close', () => {
      resolve();
    });
  });
};

自动启动

lib/init.js

const open = require('open');

module.exports.init = async name =>  {
  // ...

  // 启动项目
  open(`http://localhost:8080`);
  await spawn(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['run', 'serve'], { cwd: `./${name}` });
};

约定路由

  • 生成文件
    lib/refresh.js

    const fs = require('fs');
    const handlebars = require('handlebars');
    const chalk = require('chalk');
    
    module.exports = async () => {
      // 获取页面列表
      const list = fs.readdirSync('./src/views')
        .filter(fname => fname !== 'Home.vue')
        .map(fname => ({
          name: fname.replace('.vue', '').toLowerCase(),
          file: fname,
        }));
      
      // 生成路由
      compile({
        list,
      }, './src/router.js', './template/router.js.hbs');
    
      // 生成菜单
      compile({
        list,
      }, './src/App.vue', './template/App.vue.hbs');
    
      /**
       * 编译模板文件
       * @param {*} meta 
       * @param {*} filePath 
       * @param {*} templatePath 
       */
      function compile(meta, filePath, templatePath) {
        if (fs.existsSync(templatePath)) {
          const content = fs.readFileSync(templatePath).toString();
          const result = handlebars.compile(content)(meta);
          fs.writeFileSync(filePath, result);
        }
        console.log(chalk.green(`${filePath} 创建成功`));
      }
    };
    
  • 自动刷新
    bin/kkb.js

    #!/usr/bin/env node
    const program = require('commander');
    // ...
    program
      .command('refresh')
      .description('refresh project')
      .action(require('../lib/refresh'));
    
    program.parse(process.argv);

发布 npm

  • 新建发布脚本
    publish.sh

    #!/usr/bin/env bash
    npm config get registry
    npm config set registry=http://registry.npmjs.org
    echo "请进行登录操作:"
    npm login
    echo "---publishing---"
    npm publish
    npm config set registry=https://registry.npm.taobao.org
    echo "发布完成"
    exit
  • 发布

    ./publish.sh # win
相关文章
|
9月前
|
资源调度 前端开发 测试技术
前端工程化实践:从零搭建现代化项目构建流程
【4月更文挑战第6天】本文介绍了前端工程化的概念和重要性,包括模块化、自动化、规范化和CI/CD。接着,讨论了选择合适的工具链,如包管理器、构建工具和测试框架。然后,详细阐述了如何从零开始搭建一个基于React的现代化项目构建流程,涉及初始化、代码规范、测试、CSS处理、代码分割和CI/CD配置。最后,提到了持续优化与迭代的方向,如性能优化、类型检查和微前端。通过这样的实践,开发者可以提升开发效率和代码质量,为项目长远发展奠定基础。
393 0
|
9月前
|
前端开发 测试技术 持续交付
版本控制和团队协作:前端工程化的关键要素
版本控制和团队协作:前端工程化的关键要素
|
9月前
|
自然语言处理 前端开发 测试技术
前端工程化最佳实践:项目结构、代码规范和文档管理
前端工程化最佳实践:项目结构、代码规范和文档管理
|
7月前
|
JSON 前端开发 JavaScript
前端工程化:Webpack配置全攻略
【7月更文挑战第14天】
90 6
|
7月前
|
JSON 缓存 前端开发
前端工程化:Webpack配置全攻略
【7月更文挑战第18天】
72 1
|
8月前
|
缓存 前端开发 JavaScript
前端性能优化实践与工程化
前端性能优化实践与工程化
|
9月前
|
资源调度 JavaScript 前端开发
【前端开发---Vue2】史上最详细的Vue入门教程(六) --- 工程化开发和脚手架、组件注册
【前端开发---Vue2】史上最详细的Vue入门教程(六) --- 工程化开发和脚手架、组件注册
【前端开发---Vue2】史上最详细的Vue入门教程(六) --- 工程化开发和脚手架、组件注册
|
8月前
|
前端开发 安全 JavaScript
前端工程化实战 - 日程管理
前端工程化实战 - 日程管理
56 0
|
8月前
|
存储 JavaScript 前端开发
前端工程化
前端工程化
64 0
|
8月前
|
运维 前端开发 JavaScript
什么是前端工程化❓
什么是前端工程化❓
92 0

热门文章

最新文章

  • 1
    【Java若依框架】RuoYi-Vue的前端和后端配置步骤和启动步骤
  • 2
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 4
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 5
    详解智能编码在前端研发的创新应用
  • 6
    巧用通义灵码,提升前端研发效率
  • 7
    智能编码在前端研发的创新应用
  • 8
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 9
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 10
    抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
  • 1
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    29
  • 2
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
    50
  • 3
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    26
  • 4
    巧用通义灵码,提升前端研发效率
    93
  • 5
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    139
  • 6
    详解智能编码在前端研发的创新应用
    96
  • 7
    智能编码在前端研发的创新应用
    83
  • 8
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    37
  • 9
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    118
  • 10
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    75