[腳手架搭建]如何搭一個本身的腳手架

因爲react的腳手架配置項過多,致使項目生成很慢,每次都要等待好久。本身搭建環境的話,每次都進行搭建又有不少重複性的工做。javascript

因此筆者就打算本身搭建一個腳手架name:simple-create-react,簡化了打包環境配置並提供可選配置(axios,react-router-dom,redux,react-redux)的功能。java

1、初始化包

npm init -ynode

package.json中增長兩項react

"bin":{
	testCli:"./main.js"
}
"private":false
複製代碼

bin目錄下的testCli 表示,咱們在命令行輸入testCli 則會調用main.js內的內容,ios

private:false 表示內容是公開的,便可以被npm發佈的git

在main.js中增長github

#!/usr/bin/env node 
複製代碼

其中 #!/usr/bin/env node 的做用就是這行代碼是當系統運行到這一行的時候,去 env 中查找 node 配置,而且調用對應的解釋器來運行以後的 node 程序shell

而後咱們須要測試代碼,這裏可能須要用到 npm link 或者 npm install -g 。這樣在命令行執行testCli就能夠看到你在main.js中寫入的代碼,這裏寫一個hello worldnpm

console.log("Hello World")
複製代碼

npm link: 將當前package連接到全局 —— npm unlinkjson

npm install -g: 將當前package安裝到全局 —— npm uninstall -g

2、增長功能

交互命令—— 使用commander

const { program } = require('commander')

program
    .version('0.1.0')  // --version 版本
    .command('init <name> [branch]') // 初始化命令
    .description('初始化項目文件')
    .action( (name,branch) => { // 獲得name 
        console.log('Hello World') // 進行輸出
    })

program.parse(process.argv) // 解析變量
複製代碼

The arguments may be <required> or [optional],尖括號必須,optional可選

文件拉取 —— 使用download-git-repo

download("direct:https://github.com/oniya24/simple-create-react_template.git",
targetPath,{ clone:true }, // 目標路徑
(err)=>{ // 回調函數
    console.log(err)
}
複製代碼

坑:'git clone' failed with status 128 經過git clone拉取出錯

將git改成經過 direct: http:// URl的方式進行clone

命令行交互 —— 使用inquirer

program
    .version('0.1.0')
    .command('init <name>')
    .description('初始化模板')
    .action( (name) => {
        inquirer.prompt([
            {
                name:"description",
                message:"請輸入描述"
            },{
                name:"author",
                message:"請輸入做者"
            }
        ]).then((paramater)=>{
            console.log(paramater);
        })})
複製代碼

prompt提交一個詢問數組,name是key值,message是輸入時的提示,

返回一個對象,返回上述字段輸入的value,{ description: xxx, author: yyy}

替換模板內容 —— 使用 handlebars

// 輸入源模板
const source = "<p>description is {{description}} , author is {{ author }}</p> ";
// 進行模板的解析
const template = Handlebars.compile(source);
// 內容的定義
const paramater = { description: 'xxx', author: 'yyy' };
// 進行內容的替換
console.log(template(paramater));
// description is xxx,author is yyy
複製代碼

由這個模板咱們能夠替換掉配置文件的內容,因此咱們須要將模板的package.json進行改造,而後下載模板成功後,經過inquirier查詢到的變量,進行內容的替換

// package.json

author: "{{ author }}",
description: "{{ description }}"
複製代碼

拉取到代碼以後,經過fs模塊首先判斷是否有package.json文件,若是有則讀取文件內容,對文件內容經過handlebars進行內容的替換,而後再寫入文件中。

const content = fs.readFileSync(packagePath).toString();
const template = Handlebars.compile(content);
const result = template(paramater);
fs.writeFileSync(packagePath,result);
複製代碼

美化命令行 —— 使用chalk ora

高亮終端打印出來的信息:chalk。

終端加載效果:ora, 在代碼拉取過程有加載的效果

const spinner = ora("模板下載中^.^ 請稍後");
spinner.start();
spinner.success();
chalk.green('成功了');
chalk.red('失敗了')
複製代碼

總體代碼

靜態拉取代碼見:github.com/oniya24/sim… 的staticFillPull的文件

3、可選擇配置項

咱們發現基礎功能已經實現了,可是還存在兩個問題

  1. 拉取的是靜態代碼,對於一些咱們不須要的配置,如react-router、loadsh沒法選擇
  2. 拉取代碼後還須要本身進行npm install,不能直接使用

如何實現按需添加 —— inquirer的type + handlebars的判斷

查閱資料後發現,咱們的inquirer功能比較強大,還能夠經過更改type,來支持confirm判斷或者list選擇,因此選擇的部分咱們就能夠用inquirer來實現,而後根據咱們查詢獲得的結果進行package.json的更改。

Confirm - {type: 'confirm'}

Take type, name, message, [default] properties. default is expected to be a boolean if used.

package.json中咱們須要用到模板的寫法,這裏再次查閱handlebars的文檔,發現它支持判斷語句(nice!)

官網文檔:handlebarsjs.com/guide/

{{#if isReactRedux}}
 "react-redux": "^7.2.0",
 {{/if}}
 {{#if isReactRouterDom}}
 "react-router-dom": "^5.1.2",
 {{/if}}
 {{#if redux}}
 "redux": "^4.0.5",
 {{/if}}
複製代碼

這樣可選配置的部分咱們就完成了,你們能夠根據本身的須要來增刪配置。

如何實現node命令的使用 —— child_process

process.cwd()返回當前執行目錄

使用child_process的spawn()啓動一個子進程執行命令,參數(command, [args], [option])

這裏增長了三個參數,cwd命令執行目錄,stdio:"inherit"繼承父進程的輸入輸出流,shell:在shell下執行

與exec()方法均開啓一個子進程執行命令,不一樣的是exec()有一個回調函數貨值子進程的狀態

const spawn = require('child_process').spawn;
const chalk = require("chalk");

let runInstall = async function(cwd,callback,executable = 'npm',args = ['install']){
    console.log(chalk.greenBright("正在安裝項目依賴……\n"));
    // 執行executable args 對應到默認參數即 npm install 安裝依賴
    await new Promise((resolve, reject) => {
        const installProcess = 
        spawn(executable, args, { cwd: cwd,stdio: "inherit", shell: true });
        //文件目錄, 繼承父進程的輸入輸出【即控制檯能夠看到子進程輸出】,開啓shell 
        installProcess.on('exit', () => {
            console.log(chalk.greenBright("依賴安裝完成!"));
            resolve();
        });
        installProcess.on('error',(err)=>{
            console.log(chalk.red("依賴安裝失敗"));
            reject(err);
        })
    }).then(()=>{ callback(); })
    .catch((err)=> { console.log(chalk.red("出現錯誤"));console.log(err) });

}
複製代碼

4、打包發佈

--- main.js

--- utils

------ outputFunc

------ npmInstall

------ inquirerArr

增長了重名文件判斷,再總體再進行一下結構優化,就能夠準備發佈啦!

配置更改

發佈前要對package.json的配置進行更改

name: 主要是包名,必須惟一
version: 版本號,每次發佈至 npm 須要修改版本號
description: 描述。
main: 入口文件,import/require的
keyword:關鍵字,以空格分離但願用戶最終搜索的詞。
author:做者
private:是否私有,須要修改成 false 才能發佈到 npm
複製代碼

發佈

npm login 登陸

npm publish packageName 發佈

可能存在的問題

1.報錯 Private mode enable, only admin can publish this module [no_perms] Private mode enable, only admin can publish this module: clitest
錯誤:403
這是由於咱們設置了淘寶鏡像,https://registry.npm.taobao.org/,將registry設置爲原來的鏡像
命令:npm config set registry=http://registry.npmjs.org

2. 報錯If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator (though this is not recommended).
清理下緩存:刪除C:\Users\Administrator\下的.npmrc文件
而後再次登陸
(還有一個緣由多是忘記登陸了,捂臉QAQ)

3. 打包使用的時候,要將__dirname 替換爲 process.cwd()

複製代碼

發佈成功後,就能夠快樂的使用啦!

npm install -g simple-create-react 全局安裝

simple-create-react init projectName 拉取模板進行初始化

如圖:

5、總結

  1. 經過commander實現命令行的交互
  2. 經過download-git-repo實現倉庫代碼的拉取
  3. 經過inquirer實現配置的選擇和相關項的填寫,實現可選配置
  4. 經過handlebars實現對package.json模板的替換
  5. 經過chalk和ora對命令行的輸出進行美化
  6. 經過child_process模塊開啓子進程,實現依賴的npm install

源碼github.com/oniya24/sim…

參考:

相關文章
相關標籤/搜索