• 我想写一个前端开发工具(三):优化!从vue-cli学了几招


      

      我从过年开始写自己的前端工具 coodev,目前已经写出一个基本的架子,大多数预想的功能都能跑通,还剩一些需要解决的问题也都已经列出来了。本来这一周打算解决对不同后端模板的前后端渲染支持的问题。但是看了一下代码,当初很多功能写的还是有很大优化空间的。我打算先停下脚步,多看一些优秀的开源框架的源码,然后优化整理一下我的前端工具。

      在选择阅读源码时,我首先想到的就是vue-cli的源码。毕竟我最初的灵感就是来源于vue-cli。闲话少说,我们先下载一份vue-cli,打开源码先看package.json熟悉整体的代码结构,不过这里我建议直接阅读/bin 文件夹下的几个文件:vue、 vue-init、 vue-build、 vue-list

      引用的比较多的比如vue-init就在一开始引用了一大堆的文件

      

     1 #!/usr/bin/env node
     2 
     3 var download = require('download-git-repo')
     4 var program = require('commander')
     5 var exists = require('fs').existsSync
     6 var path = require('path')
     7 var ora = require('ora')
     8 var home = require('user-home')
     9 var tildify = require('tildify')
    10 var chalk = require('chalk')
    11 var inquirer = require('inquirer')
    12 var logger = require('../lib/logger')
    13 var generate = require('../lib/generate')
    14 var checkVersion = require('../lib/check-version')
    15 var warnings = require('../lib/warnings')

      它们都是干嘛用的,我们调一些比较重要的说一下。

    一、优化参数处理

      先看vue:

    1 #!/usr/bin/env node
    2 
    3 require('commander')
    4   .version(require('../package').version)
    5   .usage('<command> [options]')
    6   .command('init', 'generate a new project from a template')
    7   .command('list', 'list available official templates')
    8   .command('build', 'prototype a new project')
    9   .parse(process.argv)

      可以看出这个文件主要是对 ‘commander’的使用。那么‘commander’这个npm包又是什么呢?字面意思‘指挥官’,我们在 https://www.npmjs.com/ 网站上可以搜一下,会有一些简单的文档用例。其实‘commander’就是命令控制器,vue-cli用这个库来管理用户输入的命令,来完成在终端上用户命令行的交互。

      回到vue-cli能看到一个很大的链试调用,完成了一些列的任务,我们要先了解这些api,就能明白这个文件在干什么了。关于 ‘commander’的API,可以看npm上的官方例子,后续我也会写一篇有关于使用 ‘commander’的文章。我这里先介绍几个我用到的:

      我原先是通过一个map定义命令,用到的地方require一下,通过 process.argv.splice(2) 拿到参数。后来改用‘commander’,就比较省心直接注册参数:

      

     1 var program = require('commander');
     2 
     3 
     4 program
     5     .version(require('./package').version)
     6     .option('-i, --init', '初始化项目文件夹')
     7     .option('-d, --dev', '以开发模式启动coodev 即时编译 不压缩')
     8     .option('-b, --build', '以生产模式启动coodev 编译一次 压缩')
     9     .option('-s, --server', '本地server调试')
    10     .option('-p, --publish', '提交到发布仓库')
    11     .parse(process.argv);
    12 
    13 /** init */
    14 if (program.init) {
    15     require('./src/tasks/task-init.js').render();
    16 }
    17 
    18 /** dev */
    19 if (program.dev) {
    20     require('./src/tasks/task-dev.js').render();
    21 }
    22 
    23 /** build */
    24 if (program.build) {
    25     require('./src/tasks/task-build.js').render();
    26 }
    27 
    28 /** start */
    29 if (program.start) {
    30     require('./src/tasks/task-server.js').render();
    31 }
    32 
    33 /** publish */
    34 if (program.publish) {
    35     require('./src/tasks/task-publish.js').render();
    36 }
    37 
    38 program.on('--help', function () {
    39   console.log('  Examples:')
    40   console.log()
    41   console.log(chalk.gray('    # create a new project with an official template'))
    42   console.log('    $ coodev --init')
    43   console.log()
    44   console.log(chalk.gray('    # develop project'))
    45   console.log('    $ coodev --dev')
    46   console.log()
    47   console.log(chalk.gray('    # start local server'))
    48   console.log('    $ coodev --start')
    49   console.log()
    50 });

      其中version和我原来的方式差不多,版本号就直接引用package.json,自己觉得预设的命令就用option定义(简写,全名,描述),简写和全名是调用的时候用的,描述是在输入命令'--help'的时候会自动抓取的。最后的‘on’,就像是jquery中的事件绑定一样,给命令追加额外的处理逻辑。

      这里只是一些常用的,我后期还要加上一些交互性质的参数处理,比如引导用户配置工程等等,虽然原来自己写的也能满足目前的需求,但为了后期的功能,还是先改成‘commander’好一些。

    二、按需拉取github上的模板

      这事我最想学习的功能。用过vue-cli的朋友都知道有一个这样的命令 $ vue init webpack-simple yourproject-name 的初始化命令,他会作为几个脚手架给我们初始化模板,那么模板都放哪了?如果放在vue-cli里面,随着后期维护,就会越来越大,这不就毁了吗。我看了一下官方的描述说模板放在了另一个git仓库里,我也在github里找到了。我起初的时候为了独立维护模板,也是这样做的放在了别处,每次coodev发布时,用脚本同步过来,但我的方式虽然快,但是也就是现在模板数少还可以。因此我打算按需要拉取模板。

      这个功能无疑是在vue-init文件里面,我发现有一个 var download = require('download-git-repo') ,在npm上查了一下,描述是这样“从节点下载并提取一个git存储库”,那么应该就是它了。

      我的模板放在了github上的另一个仓库,https://github.com/grARM/coodev-temp-normal。现在想拉到coodev中只需要调用如下代码:

    1 /** get code from github */
    2 var loadNormalTmpl = function(cb){
    3     download('grARM/coodev-temp-normal', proPath, function (err) {
    4         if(err){
    5             console.log('err', err);
    6         }
    7         cb && cb(err);
    8     });
    9 }

      其中proPath是我的工程目录,这样就比我之前的递归文件拷贝高端了不少。

    三、交互式命令

      既然可以从别处拉模板,那么我的coodev一下子就可以精简很多,我以后可以拥有一大堆模板,都放在github上,我想拉哪一个,就拉哪一个。我还需要给用户提供交互式的命令。在vue-init中也是有这个例子的。 var inquirer = require('inquirer') 

      'inquirer'是一个提供交互式命令的npm包,地址: https://www.npmjs.com/package/inquirer。这个库在Github的examples文件夹里有详细的例子。每一个问答都会被封装到answers里。

     1 inquirer.prompt([{
     2         type: 'list',
     3         message: 'which template do you need:',
     4         name: 'template',
     5         choices: ['normal', 'wap', 'h5']
     6     }]).then(function (answers) {
     7         console.log(answers)
     8             done();
     9     })        

      如图:  

    总结:  

      就这样,我就在vue-cli中学习了3招:命令管理、按需拉取模板、交互式命令。

      接下来就是处理不同的主流后端模板引擎的支持了。

      

      

  • 相关阅读:
    border-color
    animation
    servlet injection analysis
    事务隔离级别
    write RE validation
    Filter
    Annotation
    Injector
    gradle的安装
    Build tool
  • 原文地址:https://www.cnblogs.com/webARM/p/6505683.html
Copyright © 2020-2023  润新知