邂逅CLI开发-woker开发过程

邂逅CLI开发-woker开发过程

在前端开发过程中,我们会使用各种各样的脚手架 vue-cli、create-react-app等工具。

这些工具是怎么开发出来的?当我们输入一个命令其内部帮我们处理了哪些事情?

最近写了一个叫 woker 的小工具,记录下其开发过程。文档会分成两部分

CLI 脚手架开发过程;

woker 使用介绍;

Vue 项目模板:github.com/coderx-wape…

脚手架地址:github.com/coderx-wape…

如对你有帮助,欢迎一键三联~ 点个 star 还是要 求一下的?


开发过程

一、项目开始

  • 创建空文件夹 作为我们项目的存放位置

    例如:cd woker
    复制代码
  • 创建 package.json文件

    在终端执行 npm init -y ,即可生成 package.json 文件

    {
      "name": "woker",
      "version": "1.0.1",
      "description": "vue-cli",
      "main": "index.js",
      "bin": {
        "woker": "index.js"
      },
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": ["vue-cli","coderz","vue","woker"],
      "author": "coderz", 
      "license": "ISC",
      "homepage": "https://github.com/coderx-waper/woker.git",
      "repository": {
        "type": "git",
        "url": "https://github.com/coderx-waper/woker.git"
      },
      "dependencies": {
        "commander": "^7.2.0",
        "download-git-repo": "^3.0.2",
        "ejs": "^3.1.6",
        "inquirer": "^8.0.0"
      }
    }
    
    复制代码
  • 配置文件夹

    最终 woker 项目中文件目录结构

    ├── lib
    | ├── config // 配置文件
    │ │   └── repo_config.js
    | ├── core // 核心文件
    │ │   ├── react // 待增加... 
    │ │   ├── vue
    │ │   ├── └── action.js
    │ │   ├── └── create.js 
    │ │   ├── └── help.js
    | ├── templates // ejs 模板文件
    │ │   └── vue-component.ejs
    │ │   └── vue-router.ejs
    │ │   └── vue-store.ejs
    │ │   └── vue-types.ejs
    | ├── untils // 
    │ │   └── terminal.js
    │ │   └── utils.js
    ├── index.js
    ├── package-lock.json
    ├── package.json
    ├── README.md
    复制代码

二、创建命令

必须注意一点 ,这段代码必须放在 index.js 文件的最上面

#!/usr/bin/env node
复制代码

修改 package.json 文件

  "bin": {
    "woker": "index.js"
  },
复制代码

执行 npm link woker 才会生效

创建命令需要借助 commander 库来实现,用法可自行参考官网 commander

三、创建项目指令

program.command('create <project> [others...]')
        .description('clone repo into a folder')
        .action(createVueProjectAction)
复制代码

createVueProjectAction 是封装在 action.js 文件中的一个动作,在action中的创建过程:

// create a vue template action
const createVueProjectAction = async (project, others) => {

    console.log(project, others)

    // 1 clone project
    console.log('coderz helps you clone a vue template, this requires a budget...')

    await download(vuerepo, project, {
        clone: true
    });

    // 2 npm install
    const commandTerminal = process.platform === 'win32' ? 'npm.cmd' : 'npm'
    await commandSpawn(commandTerminal, ['install'], {
        cwd: `./${project}`
    })
    // 3 run serve
    commandSpawn(commandTerminal, ['run', 'serve'], {
        cwd: `./${project}`
    })

    // 4 z-vue-template install it --open 

}
复制代码

这里涉及几个几个问题:

  • download :可以进行 clone 的一个第三方库 download-git-repo 可自行在 npm 中查看其用法
  • commandSpawn:执行终端命令的函数 可在 terminal.js 文件中找到其实现方法
  • vuerepo:vue-template 模板地址,封装在 lib/config/repo-config.js 中,后续考虑可自定义模板地址,目前使用自己写的 z-vue-template

四、添加组件指令

添加指令

program.command('addcpn <name>')
        .description('add vue component, eg: addcpn NavBar [-d src/components]')
        .action((name) => {
            addComponentAction(name, program.dest || 'src/components')
        })
复制代码
  • addComponentAction 逻辑
// create component action
const addComponentAction = async (name, dest) => {
    // needs ejs template ->  .vue 
    const result = await compile('vue-component.ejs', {
        name,
        lowerName: name.toLowerCase()
    })
    // write to source folder
    const targetPath = path.resolve(dest || 'src/components', `${name}.vue`)
    writeFile(targetPath, result)

}
复制代码

这里面存在一个问题即创建当文件夹不存的时,创建会出错,故而在调用 writeFile 中进行了文件夹的递归调用根据targetPath创建对应文件夹,其中的实现逻辑:

const mkdirSync = (dirname) => {
    if (fs.existsSync(dirname)) {
        return true
    } else {
        // 不存在,判断上一级文件夹是否存在?
        if (mkdirSync(path.dirname(dirname))) {
            // 存在父文件,就直接新建该文件
            fs.mkdirSync(dirname)
            return true
        }
    }
}

复制代码

添加组件需要去了解 ejs用法,项目中已经根据需要提前写好了vue-component.ejs模板

<template>
  <div class="<%= data.lowerName %>">
    <h2>{{ message }}</h2>
  </div>
</template>

<script>
  export default {
    name: "<%= data.name %>",
    components: {
    },
    mixins: [],
    props: {
    },
    data: function() {
      return {
        message: "Hello <%= data.name %>"
      }
    },
    created: function() {
    },
    mounted: function() {
    },
    computed: {
    },
    methods: {
    }
  }
</script>

<style scoped>
  .<%= data.lowerName %> {
    
  }
</style>
复制代码

模板ejs 编译核心:需要使用到 ejs

/**编译文件 */
const compile = (template, data) => {
    // 获取 路径
    const temp = `../templates/${template}`
    const temPath = path.resolve(__dirname, temp)
    return new Promise((resolve, reject) => {
        ejs.renderFile(temPath, {
            data
        }, {}, (err, result) => {
            if (err) {
                reject(err)
            }
            resolve(result)
        })
    })
}

复制代码

五 、添加其他指令

添加 page指令和 store 指令同上,逻辑可以查看 woker 中的实现。这里不再累述。

六、发布到npm

在发布之前,所有指令必须测试无问题

修改package.json:添加 homepage、repository

  "homepage": "https://github.com/coderx-waper/woker.git", //此处填写你的 homepage
  "repository": {
    "type": "git",
    "url": "https://github.com/coderx-waper/woker.git" //此处填写你的 repository
  },
复制代码

在命令行中登录:

npm login //根据提示输入信息即可
复制代码

发布到npm registry中

npm publish
复制代码

woker使用介绍

  • woker 是什么?

    Front-end scaffolding, currently supports vue

  • 后续打算?

    支持 支持 react template

如何安装?

npm install -g woker
复制代码

创建项目

目前woker仅支持vue,cli已经帮你配置了

  • 常用的目录结构
  • axios
  • vue-router
  • vuex
  • vue.config.js
    创建项目
woker create <project>[^project]: 你的项目名称 例如: woker create demo

复制代码

自动拉取z-vue-template项目模板,自动打开 http://localhost:8080/、启动项目

创建组件

woker addcpn <component>[^component]: 你的组件名称 例如: woker addcpn HelloWold
复制代码

创建页面

创建页面过程中会自动配置路由

woker addpage <profile>[^profile]: 你的页面名称 例如: woker addpage profile
复制代码

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享