搭建一個屬於本身的腳手架

好處

  • 讓項目從"搭建-開發-部署"更加快速以及規範
  • 不要讓本身成爲碼畜, 既要會寫還要懂原理

什麼是腳手架?

  • node.js相關api開發
  • 命令式的構建項目(解析命令,拷貝項目到本地),提供項目的配置(構建,編譯,代碼規範檢查)
  • 好比用vue-cli生成了一個項目,下次若是還有相似的項目使用, 那若是是把代碼copy一遍, 就顯的太傻了, 最好的辦法,就是經過sheel命令直接生成一個模版, 而後就直接能夠業務開發了;不管是create-react-app,vue-cli,create-umi都是這樣的套路

經常使用的npm包

  • commander:nodejs命令行接口的完整解決方案。
  • inquirer:nodeJs 交互式命令行工具。
  • handlebars:一個 javascript 語義話模版庫。
  • chalk:修改控制檯中字符串的樣式 字體樣式(加粗、隱藏等) 字體顏色 背景顏色。
  • download-git-repo:從github,lab獲取其餘倉庫下載模版代碼e。
  • ora: 實現node.js 命令行環境的 loading效果, 和顯示各類狀態的圖標等.

建立項目

  • npm init生成paackage.json文件 而後在項目根目錄執行操做: mkdir bin && touch bin/jsm.js 在jsm.js文件中添加javascript

    #!/usr/bin/env node
    console.log('Hello CLI')
    複製代碼
  • #!/usr/bin/env node,告訴操做系統執行這個腳本的時候,調用/usr/bin下的node解釋器前端

  • package.json文件只有加上了bin字段,才能在控制檯使用你的命令,對應的這裏的命令就是jsm,對應的執行文件爲bin/jsm.js。 其實"jsm"命令就是 "node bin/jsm.js" 的別稱,只有你用npm i -g tools全局安裝後才能夠用,開發的過程當中直接用node bin/jsm.js便可vue

解析命令

  • 依賴 commanderjava

  • commander是一個輕巧的nodejs模塊,提供了用戶命令行輸入和參數解析強大功能node

  • 關於commander的說明參考連接apireact

    const program = require('commander');
     program
      .command('create <type> [name] [otherParams...]')
      .alias('c')
      .description('Generates new code')
      .action(function (type, name, otherParams) {
        console.log('type', type);
        console.log('name', name);
        console.log('other', otherParams);
        // 在這裏執行具體的操做
      });
    
    program.parse(process.argv);
    複製代碼

    說明linux

    • command第一個參數爲命令名稱,alias爲命令的別稱, 其中<>包裹的爲必選參數 []爲選填參數 帶有...的參數爲剩餘參數的集合webpack

    • 而後執行命令node bin/jsm.js c component myComponent state=1 title=HelloCLI 輸出的應該是下面的內容git

  • ora: 實現node.js 命令行環境的 loading效果, 和顯示各類狀態的圖標github

  • 想全部人都能下載。能夠用http下載的方式,若是直接使用SSH地址, 會提示: 'git clone' failed with status 128

    download('direct:https://github.com/xxx/react-template.git', name, {clone: true}, (err) => {})
    複製代碼

文件操做

  • 文件的操做,複製,粘貼,增長,刪除,文件內容的新增,替換;能夠藉助fs-extra實現

  • fs-extra是加強版的fs模塊,模擬了相似如linux的命令

    root$ rm -rf /
    root$ mv tmpDir tmpNewDir
    root$ mkdir -p one/two
    root$ cp -r tmp tmpNew
    複製代碼

具體實現

  1. npm init生成paackage.json文件

  2. mkdir bin && touch bin/init.js

  3. 在init.js添加 #!/usr/bin/env node

    const program = require('commander');
    
     program
      .command('create <type> [name] [otherParams]')
      .alias('cli')
      .description('Generates new code')
      .action(function (type, name, otherParams) {
        console.log('type', type, name, otherParams);
        // 在這裏執行具體的操做
        switch(type) {
          case 'download':
            // 從倉庫下載模版文件
            const downloadFunc = require('./download.js');
            downloadFunc(name);
            break;
          case 'create':
            // 命令行建立模板文件
            const createFunc = require('./create.js');
            createFunc(name, otherParams);
            break;
          default: return false;
        }
      });
    
    program.parse(process.argv);
    複製代碼
  4. touch bin/create.js bin/download.js

  5. download.js實現從git倉庫下載模板腳手架到本地

    const downloadFunc = (name) => {
        if(!fs.existsSync(name)){
            inquirer.prompt([
                {
                    name: 'description',
                    message: '請輸入項目描述'
                },
                {
                    name: 'author',
                    message: '請輸入做者名稱'
                }
            ]).then((answers) => {
                const spinner = ora('正在下載模板...');
                spinner.start();
                // name是第二個參數,下載路徑
                download('direct:http://gitlab.alibaba-inc.com/xxxx#master', name, {clone: true}, (err) => {
                    if(err){
                        spinner.fail();
                        console.log(symbols.error, chalk.red(err));
                    }else{
                        spinner.succeed();
                        const fileName = `${name}/package.json`;
                        const meta = {
                            name,
                            description: answers.description,
                            author: answers.author
                        }
                        if(fs.existsSync(fileName)){
                          // 對源文件的package.json進行處理
                          const content = fs.readFileSync(fileName).toString();
                          const result = handlebars.compile(content)(meta);
                          fs.writeFileSync(fileName, result);
                        }
                        console.log(symbols.success, chalk.green('項目初始化完成'));
                    }
                })
            })
        }else{
            // 錯誤提示項目已存在,避免覆蓋原有項目
            console.log(symbols.error, chalk.red('項目已存在'));
        }
    }
    複製代碼
  6. create.js實現建立模板文件, 具體代碼,參見下面連接;

發佈到npm

  • npm login 登錄, 沒有帳號,先註冊帳號
  • 而後在項目根目錄, npm publish發佈
  • 注意若是package.json中的name若是和已發佈的包重複,會報403錯誤
  • 而後就能夠在使用了, 全局安裝
    npm i xxxTools -g;
        xxxTools create myAPP;
    複製代碼

Create-umi 建立項目

  • 全局安裝create-umi, 而後就可使用yarn create umi生成項目腳手架
  • 判斷node版本,node版本必須8.0.0以上
  • 根據提示選擇要生成的項目類型,包括: ant-design-pro, app, block, library,plugin
  • 根據選擇的project類型,進入不一樣的generator
  • 每一個project的generator繼承於公共的BasicGenerator,
  • 單獨的generator進行各自的業務操做,以app爲例, 是否選擇ts支持,是否選擇antd,dva,dll等
  • 全部選擇完畢,開始進行文件操做
  • 模板複製到指定目錄, 寫入以前配置的選項

vue-cli 建立項目

  • cli3.0更加複雜, 固然功能也更增強大,好比vue create,vue add, vue serve, vue ui 等
  • 項目初始化主要在 vue create命令中, 具體分析參看下文連接

Create-react-app 建立項目

  • 主要包括2部分: 項目初始化和react-scripts
  • 項目初始化就是咱們輸入 create-react-app project-name,到結束所作的事情, 而react-scripts所要作的包括start,test,eject,build以及各類webpack打包編譯的工做
  • 圖解項目初始化

so easy 搭建前端腳手架

一次nodejs開發CLI的過程

create-react-app源碼分析

vue-cli源碼分析

源碼

相關文章
相關標籤/搜索