前端腳手架CLI生成模版命令工具(包括,npm包的發布,腳手架的搭建,注意事項,優化等)


寫在前面

這是停更以后,續更的一篇文章。

為什么好長時間都沒有更新,因為去其他平台更新了,包括掘金,思否,簡書等。

在那些地方感覺沒有歸屬感,有的平台原創審核很麻煩,簡書號稱可以獲得打賞,可是碼了幾十萬字的博主,幾百塊,也沒有什么意義。而且為了能吸粉,可能得違背自己的意願寫一些水文,或者不利於自己成長的文章。

 

 所以,我還是回到這里,博客園——開發者的網上家園。

盡管這里沒有外面那些平台那么fashion,但是,因為ta是我的第一個技術輸出平台,還真有點家園的感覺。

之前博客叫前端嬰兒,最近幾年也成長了,今天改名叫前端小學生,成長任重道遠,一直在路上!一起加油!

回歸第一篇文章,來點干貨!!

 

正文 

NodeJs的出現,讓前端工程化的理念不斷深入,正在向正規軍靠近。先是帶來了Gulp、Webpack等強大的構建工具,隨后又出現了vue-cli和create-react-app等完善的腳手架,提供了完整的項目架構,讓我們可以更多的關注業務,而不必在項目基礎設施上花費大量時間。

平時我們都只專注在業務上的開發,拿起一套開箱即用的模板項目就直接干。但是,這些現成的腳手架未必就能滿足我們的業務需求,也未必是最佳實踐,這時我們就可以自己開發一個腳手架,那么我們使用的腳手架里面到底做了什么,如何自己搭建腳手架呢?

腳手架代碼github地址:https://github.com/hourong88/...

以下為正文,文章結構:

 

 

提問

1.腳手架需要實現什么?

初始化項目模版能力。

2.腳手架需要什么功能?

  1. 問詢功能
  2. 下載模版(模版與腳手架分離,互不影響)
  3. 寫入模版
  4. 優化(git初始化,安裝依賴等)

3.用什么工具實現?

  • commander.js 命令行工具
  • chalk 命令行輸出樣式美化
  • Inquirer.js 命令行交互

當然還有,download-git-repo git倉庫代碼下載,ora 命令行加載中效果等優化依賴工具,都可以在此基礎上,進行豐富。

以下分為兩步完成:

  1. 本地創建cli腳手架並測試 ;
  2. 發布腳手架

我們正常的流程是創建本地腳手架,綁定git倉庫,發布包,從易到難,我們反過來,本文先講怎么發一個最簡單的npm包,然后把腳手架搭好了,走一遍發包流程,就OK了。

一、發布npm包

本地創建項目

首先,我們需要創建一個項目,這里就叫portal-cli, 項目結構如下:

- commands  // 此文件夾用於放置自定義命令
- utils
- index.js  // 項目入口
- readme.md

為了測試,我們先在index.js放點內容:

#!/usr/bin/env node
// 必須在文件頭添加如上內容指定運行環境為node
console.log('hello cli');

對於一般的nodejs項目,我們直接使用node index.js就可以了,但是這里是腳手架,肯定不能這樣。我們需要把項目發布到npm,用戶進行全局安裝,然后就可以直接使用我們自定義的命令,類似portal-cli這樣。

所以,我們需要將我們的項目做下改動,首先在package.json中添加如下內容:

 "bin": {
    "portal-cli": "index.js"
  },

這樣就可以將portal-cli定義為一個命令了,但此時僅僅只能在項目中使用,還不能作為全局命令使用,這里我們需要使用npm link將其鏈接到全局命令,執行成功后在你的全局node_modules目錄下可以找到相應文件。然后輸入命令測試一下,如果出現如下內容說明第一步已經成功一大半了:

anna@annadeMacBook-Air job % > portal-cli
hello cli

*如果全局有bin相同名字的,會報錯,需要把package.json里面bin起的名字修改一下

發布npm包注意事項:

  1. npm官網注冊一個npm賬戶,已有賬戶的可以跳過這一步
  2. 使用npm login登錄,需要輸入usernamepasswordemail
  3. npm whoami 檢查自己是否成功登陸
  4. npm link本地調試,上面已經調試的,跳過這一步
  5. 使用npm publish發布
  6. 每次發布npm包,都要修改版本號
//npm publish報錯
npm notice integrity:     sha512-Jkfy0M/VyAkQb[...]B9Ifdw2hF2CGQ==
npm notice total files:   7                                       
npm notice 
npm ERR! code E403
npm ERR! 403 403 Forbidden - PUT http://registry.npmjs.org/portal-portal-cli-hourong - Forbidden
npm ERR! 403 In most cases, you or one of your dependencies are requesting
npm ERR! 403 a package version that is forbidden by your security policy.

我發布包的時候,調整了幾次,報錯,不是403就是404,那個捉急。下面總結了幾個報錯檢查清單:

  1. 檢查npm包的名字跟已有的包名是否重復,要么就改個名字,或者加后綴
  2. 如果用的是cnpm源,要改成npm,方法見下面說明registry
  3. 如果還是報403,你的賬號看是不是剛剛注冊的,如果是的話,需要進入你的郵箱,驗證一下郵箱。
  4. 版本號是否更新
  5. 如果以上3步修改了,還是報403錯誤,就連接手機4g熱點再發布一下。

一般發布不了,按照以上5點進行檢查,可以解決。

檢查第2步npm源的方法

查看本地當前使用的源

registry npm config get registry

切換源

registry npm config set registry <http://registry.npmjs.org/>

臨時切換

registry npm publish --registry <http://registry.npmjs.org/>

設置完以后,再次查看當前源是否是http://registry.npmjs.org

注意:國內目前發布組件時,必須切換為npmjs,否則npm publish也不會成功


科普npm registry

簡單來說,npm registry就相當於一個包注冊管理中心。它管理着全世界的開發者們發布上來的各種插件,同時開發者們可以通過npm install的方式安裝所需要的插件。

npm官方registry為:http://registry.npmjs.org/

國內速度較快的為:https://registry.npm.taobao.org/


以上涉及到的關鍵命令:

npm link  // 本地調試
npm publish  // 發布
npm whoami  //查看當前登陸的用戶名

每次更新包需要同步更新版本號,發布的包需要發布72小時以后才可以廢棄刪除。

二、本地腳手架搭建

上文中,我們既然是搭建腳手架,肯定不能只讓它輸出一段文字吧,我們還需要定義一些命令,用戶在命令行輸入這些命令和參數,腳手架會做出對應的操作。這里不需要我們自己去解析這些輸入的命令和參數,有現成的輪子commander可以使用,完全可以滿足我們的需要。

  1. 安裝commander

npm install chalk commander download-git-repo inquirer ora --save

  1. 創建目錄 bin/index.js
  2. package.json 里面bin改為
 "bin": {
    "portal-cli": "bin/index.js"
  },

當然目錄結構你可以隨意定義,package.json里面bin從哪里起,主要文件就放哪兒。

  1. 創建commander init命令
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const chalk = require('chalk'); //命令行輸出樣式美化
const commander = require('commander'); //命令行工具
const inquirer = require('inquirer'); //命令行交互
const checkDire = require('./utils/checkDire.js');
const { exec } = require('child_process');
const { version } = require('../package.json');
const { promptTypeList } = require('./config');
function resolve(dir) {
  return path.join(__dirname,'..',dir);
}
//version 版本號
commander.version(version, '-v, --version')
  .command('init <projectName>')
  .alias("i")
  .description("輸入項目名稱,初始化項目模版")
  .action(async (projectName,cmd) => {
    await checkDire(path.join(process.cwd(),projectName),projectName);   // 檢測創建項目文件夾是否存在
    inquirer.prompt(promptTypeList).then(result => { //inquirer 交互問答
      const {url, gitName, val} = result.type;
      console.log("您選擇的模版類型信息如下:" + val);
      console.log('項目初始化拷貝獲取中...');
      if(!url){
        console.log(chalk.red(`${val} 該類型暫不支持...`));
        process.exit(1);
      }
      exec('git clone ' + url, function (error, stdout, stderr) {  //git倉庫代碼下載
        if (error !== null) {
          console.log(chalk.red(
            `clone fail,${error}`
          ));
          return;
        }
        fs.rename(gitName, projectName, (err)=>{
          if (err) {
            exec('rm -rf '+gitName, function (err, out) {});
            console.log(chalk.red(`The ${projectName} project template already exist`));
          } else {
            console.log(chalk.green(`✔ The ${projectName} project template successfully create(項目模版創建成功)`));
          }
        });
      });
    })
  });
commander.parse(process.argv);
 以上代碼解析: 1). checkDire檢查創建項目文件夾是否存在
const fs = require('fs');
const chalk = require('chalk');
const path = require('path');
module.exports = function (dir,name) {
  let isExists = fs.existsSync(dir);
  if (isExists) {
    console.log(chalk.red(
      `The ${name} project already exists in  directory. Please try to use another projectName`
    ));
    process.exit(1); //存在則跳出
  }
};

2). commander init 命令行進入交互問答 

3). 交互問答用inquirer命令交互工具

  • question 數組為交互命令配置,數組中每一個對象都對應一個執行命令時候的一個問題
  • type為該提問的類型,name為該問題的名字,可以在后面通過name拿到該問題的用戶輸入答案
  • message為問題的提示
  • default則為用戶沒輸入時的默認為其提供一個答案
  • validate方法可以校驗用戶輸入的內容,返回true時校驗通過,若不正確可以返回對應的字符串提示文案
  • transformer為用戶輸入問題答案后將對應的答案展示到問題位置,需要有返回值,返回到字符串為展示內容

具體使用文檔:https://github.com/SBoudrias/...

4). 問答結束的回調prompt方法中then里的參數是一個對象,從配置里面拉取git倉庫代碼。后面你們使用的時候,拉不下來,看不是不是沒有倉庫代碼權限。

module.exports  = {
  npmUrl: 'https://registry.npmjs.org/xxx-cli',
  promptTypeList:[{
      type: 'list',
      message: '請選擇拉取的模版類型:',
      name: 'type',
      choices: [{
        name: 'portal前端框架',
        value: {
          url: 'http://192.168.3.51/xxx/portal-frame.git', //框架git倉庫
          gitName: 'portal-frame',
          val:'portal前端框架'
   
        }
      }]
  }],
};

5).git clone下載前端框架。也可以用download-git-repo git倉庫代碼下載

以上,就是全部前端腳手架內容,總共四個文件,index.js是最重要的(引用另外兩個配置文件),加上一個package.json。

執行以下命令發布:

npm link // 本地調試 npm publish // 發布

三、如何使用?

在需要用到框架的時候,新建空文件夾,執行:

npm install portal-cli -g  //全局安裝portal-cli
portal-cli init <projectName>  //portal-cli init test ,test就是你放文件夾的名稱,可以自己定義

這樣前端腳手架生成模版命令工具就完成了。如果想更個性化,可以把npm包完善一下,包括包的版本說明,readme;豐富腳手架交互問詢內容,美化操作提示等。

 

 

 

 

結語

node.js,本質還是js,js熟悉以后,結合node依賴和語法,各種試錯,調試,需要耐心和細心。

另外,開始做一個實例的時候,構思思路,注意流轉順序。主要以官方文檔為主,網上博客文章為輔。

官方的還是靠譜一點,博客各種坑,不是過時了,就是講的不連貫,沒有可執行性。

總的來說,學習也是一個探索的過程,共同進步!

以上【完】

參考:

https://www.cnblogs.com/cangq...

https://segmentfault.com/a/11...

Inquirer.js:https://github.com/SBoudrias/...

npm包生命周期:https://segmentfault.com/a/11...

 

這篇文章最初是發布在思否上,也可以看那邊排版,文章鏈接 :https://segmentfault.com/a/1190000038614759

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM