從零開始寫一個npm包,一鍵生成react元件(偷懶==提高效率)

僅此而已發表於2019-02-16

前言

最近寫專案開發新模組的時候,每次寫新模組的時候需要建立一個元件的時候(包含元件css,index.js,元件js),就只能會拷貝其他元件修改名稱 ,但是寫了1-2個後發現效率太低了,而且極容易出錯,所以自己寫一個npm包來減少工作量,下面就一步一步來建立一個屬於自己的npm倉庫

首先第一步建立一個package.json檔案,開啟終端,輸入以下命令:

 npm init  
複製程式碼

然後會依次提示專案名稱、版本、專案描述、入口檔案...一直回車,直到出現Is this ok? (yes),然後輸入yes,建立一個package.json檔案就完成了,接下來在根目錄建立一個index.js檔案,檔案內容為:

#!/usr/bin/env node   //告訴node使用終端執行
const fs = require('fs'); //檔案系統
const program = require('commander'); //終端輸入處理框架
const package = require('./package.json'); //獲取版本資訊
program.version(package.version, '-v,--version')
       .command('init <name>')
       .action(name=>{
           console.log(name)
       })
  program.parse(process.argv);
複製程式碼

安裝commander:

cnpm i -d commander 
複製程式碼

接下來我們就可以看看效果,安裝執行

node index.js -v 
輸出:1.0.0
node index.js init header
輸出:header
node index.js -h 
輸出: Usage: index [options] [command]

  Options:

    -v,--version  output the version number
    -h, --help    output usage information

  Commands:

    init <name>
複製程式碼

程式碼正常執行,接下來修改package.json裡面bin,增加以下程式碼:

  "bin": {
    "temp": "index.js" 
  },
複製程式碼

到這裡我們第一步就算完成了,怎麼釋出npm包呢?流程如下:

  • 首先在[npm官網][1]中註冊賬號(如有忽略)
  • 註冊完執行npm adduser 依次輸入帳號,密碼,郵箱,
  • npm version patch
  • npm publish就可以提交了 npm釋出流程踩過的坑
  • 使用npm提交,不要使用cnpm
  • 每次修改都需要修改版本號npm version patch
  • 專案名稱 npm倉庫是否有這個專案

釋出成功後,我們全域性安裝,剛剛我提交的專案名稱為template-react-cli,所以執行全域性安裝,使用npm安裝,cnpm會有短暫延遲

npm i template-react-cli -g
temp -v    
輸出:1.0.0 
temp init footer 
輸出: footer
複製程式碼

屬於我們的npm可以正常使用了,接下來豐富我們的npm包,先安裝依賴:

cnpm i -d download-git-repo handlebars inquirer log-symbols ora
複製程式碼

安裝完成後,豐富我們的功能index.js檔案如下:

#!/usr/bin/env node
const fs = require('fs');

const program = require('commander');
const download = require('download-git-repo'); //下載模版檔案
const chalk = require('chalk');  //美化終端
const symbols = require('log-symbols'); //美化終端
const handlebars = require('handlebars'); //修改模版檔案內容

const ora = require('ora'); //提示下載
var inquirer = require('inquirer');  //提示文字
const package = require('./../package.json'); //獲取版本資訊
const re = new RegExp("^[a-zA-Z]+$"); //檢查檔名是否是英文,只支援英文

program
  .version(package.version, '-v,--version')
  .command('init <name>')
  .action(name => {
    if (!re.test(name)) { //檢查檔名是否是英文
      console.log(symbols.error, chalk.red('錯誤!請輸入英文名稱'));
      return 
    } 
    if (!fs.existsSync(name)) { //檢查專案中是否有該檔案
      inquirer  
        .prompt([
          {
            type: 'list',
            name: 'type',
            message: '請選擇模版型別?',
            choices: [
              'react-component------ES6元件',
              'react-function------函式元件',
              'react-redux------ES6元件',
            ],
          },
        ]) 
        .then(answers => {
            //使用者選擇後回撥
          console.log(symbols.success,chalk.green('開始建立..........,請稍候'));
          const spinner = ora('正在下載模板...');
          spinner.start();
          const type = getType(answers)
          download(`github:NewPrototype/template/#${type}`, name, err => {
            if (err) {
              spinner.fail();
            } else {
              spinner.succeed();
              var files = fs.readdirSync(name);
              for(let i=0;i<files.length;i++){ //修改檔案內容
                let fileName=`${name}/${files[i]}`;
                if(fs.existsSync(`${name}/${files[i]}`)){
                  const content = fs.readFileSync(fileName).toString();
                  const result = handlebars.compile(content)({template:name,});
                  fs.writeFileSync(fileName, result);
                }

              }
              let count = 0; //所有檔案標題修改完成,提示
              for (let i = 0; i < files.length; i++) {
                if(files[i]=='index.js'||files[i]=='action.js'||files[i]=='reducer.js'||files[i]=='saga.js'){
                  continue
                }
                //獲取檔案列表
                var index = files[i].indexOf('.');
                fs.rename(
                  `${name}/${files[i]}`,
                  `${name}/${name}${files[i].substring(index)}`,
                  err => {
                    if (err) {
                      console.log('---錯誤');
                    }
                    count++;
                    if (count+1 == files.length) { //排除index.js檔案
                      console.log(symbols.success, chalk.green('模版建立成功'));
                    }
                  }
                );
              }
            }
          });
        });
    } else {
      console.log(symbols.error, chalk.red('有相同名稱模版'));
    }
  });

program.parse(process.argv);

const getType = (type) => {
  let str = 'master';
  switch (type.type) {
    case "react-component------ES6元件":
      str = "component"
      break;
      case "react-function------函式元件":
      str = "master"
      break;
      case "react-redux------ES6元件":
      str = "redux"
      break;
    default:
      break;
  }
  return str
}
複製程式碼

然後重新提交檔案到npm倉庫,方法和上面釋出流程一樣,釋出完成後:

npm i template-react-cli -g
先檢查版本號
temp -v  
輸出:1.02
然後檢查功能:
temp init header 
輸出:? 請選擇模版型別? (Use arrow keys)
❯ react-component------ES6元件
  react-function------函式元件
  react-redux------ES6元件
選擇想要的選項,回車
輸出:✔ 開始建立..........,請稍候
⠏ 正在下載模板...
等待下載完成
輸出:✔ 模版建立成功
複製程式碼

從零開始寫一個npm包,一鍵生成react元件(偷懶==提高效率)
從零開始寫一個npm包,一鍵生成react元件(偷懶==提高效率)
可以看到當前目錄下面建立了一個header資料夾,裡面包含js檔案和stylcss檔案,到這裡整個流程就完成了,這裡是下載了模版檔案[模版地址][2],大家也可以寫出符合自己風格的模版檔案。

後言

有了node我們可以做很多很多的事情,以後開發新模組的時候就可以偷懶了!純手打給個贊可好?

github

github.com/NewPrototyp…

模版github

github.com/NewPrototyp…

相關文章