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