這篇文章主要介紹了node如何實(shí)現(xiàn)項目工程自動初始化,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
萊陽ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)建站的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!
傳統(tǒng)的前端項目初始流程一般是這樣:

可以看出,傳統(tǒng)的初始化步驟,花費(fèi)的時間并不少。而且,人工操作的情況下,總有改漏的情況出現(xiàn)。這個缺點(diǎn)有時很致命。
甚至有馬大哈,沒有更新項目倉庫地址,導(dǎo)致提交代碼到舊倉庫,這就很尷尬了。。。
基于這些情況,編寫命令行工具(CLI)的目的就很明確:
用于新項目工程的初始化利用工具進(jìn)行初始化,可以節(jié)省項目初期的準(zhǔn)備時間避免出現(xiàn)改漏的情況杜絕未更新項目版本倉庫地址的問題
以下是新的流程示意圖:

以下是自動化流程圖:

從流程圖可以得出兩個重要的信息:
配置信息模板文件
命令行工具的角色,是負(fù)責(zé)將兩個信息進(jìn)行融合,提供一個交互平臺給用戶。
配置信息的獲得,需要靠和用戶進(jìn)行交互。由于程序員一般是用終端輸入命令進(jìn)行項目操作。所以,這里選擇了兩個工具進(jìn)行支撐。
commander
借鑒Ruby commander理念實(shí)現(xiàn)的命令行執(zhí)行補(bǔ)全解決方案
commander可以接收命令行傳入的參數(shù)
例子:
npg-cli --help ? ???? npm-package-cli ? ???? Usage: npg-cli [options] Options: -V, --version output the version number -h, --help output usage information run testcli and edit the setting.
inquirer
常用交互式命令行用戶界面的集合。
inquirer用詢問式的語句,與用戶進(jìn)行交互,接收參數(shù)
例子:
npg-cli ? ???? npm-package-cli ? ???? Follow the prompts to complete the project configuration. ? project name test ? version 1.0.0 ? description
前端的JavaScript 模板引擎,比如ejs,jade等。可以根據(jù)傳入的參數(shù),對模板標(biāo)簽進(jìn)行替換,最終生成html。
如果把所有項目文件,不管文件后綴名,都看成是ejs模板,則可以在文件內(nèi)容中使用ejs語法。
再根據(jù)配置信息進(jìn)行替換,最終生成新文件。
其實(shí),業(yè)界依據(jù)這個想法,已經(jīng)有成熟的工具產(chǎn)生。
mem-fs
mem-fs是對文件進(jìn)行讀取,存入內(nèi)存中。
mem-fs-editor
mem-fs-editor是對內(nèi)存中的文件信息,使用ejs語法進(jìn)行編譯。最后調(diào)用commit方法輸出最終文件。
提示信息,除了console.log,還可以使用色彩更豐富的chalk。
這樣,可以輸出更直觀、友好的提示。
文件操作,有業(yè)界成熟的shelljs。
利用shelljs,可以在項目中簡化以下步驟:
一些項目文件,不需要修改,只用直接copy。可以使用shelljs.copySync同步方式生成。一些文件夾,需要提前構(gòu)建,可以使用shelljs.mkdir進(jìn)行創(chuàng)建
以下按我做的開源項目——npm-package-cli的創(chuàng)作過程進(jìn)行分拆、講解。
新建項目文件夾npm-package-cli,并在該文件夾下運(yùn)行npm init,生成package.json。
項目結(jié)構(gòu)如下: 
npm-package-cli |-- package.json
這里要生成的全局指令是npg-cli。
新建文件夾bin,并在文件夾下新建名稱為cli的shell腳本文件(注意:不能有后綴名)。clishell腳本文件內(nèi)容如下:
#!/usr/bin/env node
console.log('hello world');其中,#!/usr/bin/env node是告訴編譯器,以node的方式,運(yùn)行代碼。
并在package.json加入以下內(nèi)容:
"bin": {
 "npg-cli": "bin/cli"
}此時,項目結(jié)構(gòu)如下:
npm-package-cli |-- bin |-- cli |-- package.json
鏈接指令有兩種方式:
npm link
npm install -g
兩種方式,都需要在npm-package-cli文件夾下運(yùn)行,才能生效。
作用是把npg-cli指令,指向全局的bin文件下,實(shí)現(xiàn)軟鏈。
在任意文件夾下運(yùn)行命令:
npg-cli # 輸出 hello world
到這里,一個基本的指令就算完成了,接下來是指令的工作內(nèi)容細(xì)化。
Creation的作用是整合所有操作,并提供接口給指令文件cli。Creation的結(jié)構(gòu)如下:
class Creation{
 constructor(){
 // code
 }
 do(){
  // code
 }
 // other function
}其中do方法暴露給腳本文件cli調(diào)用。
Creation類放在src/index.js中。
此時,項目結(jié)構(gòu)如下:
npm-package-cli |-- bin |-- cli |-- src |-- index.js |-- package.json
cli文件#!/usr/bin/env node
const Creator = require('../src/index.js');
const project = new Creator();
project.do();這樣,只要實(shí)現(xiàn)好do方法,就可以完成npg-cli指令的運(yùn)行了。
實(shí)現(xiàn)npg-cli --help,需要借助上文提到的工具commander。
新建src/command.js文件,文件內(nèi)容如下:
const commander = require('commander');
const chalk = require('chalk');
const packageJson = require('../package.json');
const log = console.log;
function initCommand(){
 commander.version(packageJson.version)
  .on('--help', ()=>{
   log(chalk.green(' run testcli and edit the setting.'));
  })
  .parse(process.argv);
}
module.exports = initCommand;此時,項目結(jié)構(gòu)如下:
npm-package-cli |-- bin |-- cli |-- src |-- command.js |-- index.js |-- package.json
然后在Creation.do方法內(nèi)執(zhí)行initCommand()即可生效。
// src/index.js Creation
const initCommand = require('./command');
class Creation{
 // other code
 do(){
  initCommand();
 }
}此時,運(yùn)行npg-cli --help指令,就可以看到:
Usage: npg-cli [options] Options: -V, --version output the version number -h, --help output usage information run testcli and edit the setting.
要獲取用戶輸入的信息,需要借助工具inquirer。
新建src/setting.js文件,文件內(nèi)容如下:
const inquirer = require('inquirer');
const fse = require('fs-extra');
function initSetting(){
 let prompt = [
  {
   type: 'input',
   name: 'projectName',
   message: 'project name',
   validate(input){
    if(!input){
     return 'project name is required.'
    }
    if(fse.existsSync(input)){
     return 'project name of folder is exist.'
    }
    return true;
   }
  },
  // other prompt
 ];
 return inquirer.prompt(prompt);
}
module.exports = initSetting;此時,項目結(jié)構(gòu)如下:
npm-package-cli |-- bin |-- cli |-- src |-- command.js |-- index.js |-- setting.js |-- package.json
然后在Creation.do方法內(nèi)執(zhí)行initSetting()即可生效。
// src/index.js Creation
const initCommand = require('./command');
const initSetting = require('./setting');
class Creation{
 // other code
 do(){
  initCommand();
  initSetting().then(setting => {
   // 用戶輸入完成后,會得到全部輸入信息的json數(shù)據(jù) setting
  });
 }
}這里,inquirer.prompt方法裝載好要收集的問題后,返回的是Promise對象。收集完成之后,要在then方法內(nèi)拿到配置信息,以便進(jìn)行下一步模板替換的操作。
模板文件替換,要用到工具mem-fs和mem-fs-editor。
文件操作,要用到工具shelljs。
新建src/output.js文件,文件內(nèi)容如下(刪除了部分代碼,以下只是示例,完整項目看最后分享鏈接):
const chalk = require('chalk');
const fse = require('fs-extra');
const path = require('path');
const log = console.log;
function output(creation){
 return new Promise((resolve, reject)=>{
  // 拿到配置信息
  const setting = creation._setting;
  const {
   projectName
  } = setting;
  // 獲取當(dāng)前命令行執(zhí)行環(huán)境所在文件夾
  const cwd = process.cwd();
  // 初始化文件夾path
  const projectPath = path.join(cwd, projectName);
  const projectResolve = getProjectResolve(projectPath);
  
  // 新建項目文件夾
  fse.mkdirSync(projectPath);
  // copy文件夾
  creation.copy('src', projectResolve('src'));
  // 根據(jù)配置信息,替換文件內(nèi)容
  creation.copyTpl('package.json', projectResolve('package.json'), setting);
  // 將內(nèi)存中的文件,輸出到硬盤上
  creation._mfs.commit(() => {
   resolve(); 
  });
 });
}
module.exports = output;output方法的作用:
新建項目文件夾
把模板文件讀取出來,根據(jù)配置信息,進(jìn)行替換(調(diào)用的是mem-fs-editor的copyTpl方法)
拷貝其他文件
輸出最終文件到硬盤上
這里最重要的一步,是調(diào)用mem-fs-editor的方法后,要執(zhí)行mem-fs-editor的commit方法,輸出內(nèi)存中的文件到硬盤上。
在Creation.do方法中,調(diào)用output方法即可輸出新項目文件。
打開src/index.js文件,文件內(nèi)容增加如下方法:
// src/index.js Creation
const initCommand = require('./command');
const initSetting = require('./setting');
const output = require('./output');
class Creation{
 // other code
 do(){
  initCommand();
  initSetting().then(setting => {
   // 用戶輸入完成后,會得到全部輸入信息的json數(shù)據(jù) setting
   this._setting = Object.assign({}, this._setting, setting);
   // 輸出文件
   output(this).then(res => {
    // 項目輸出完成
   });
  });
 }
}自動初始化一個項目的流程不外乎以下三點(diǎn):
讀取用戶配置
讀取模板文件
根據(jù)配置,編譯模板文件,輸出最終文件
命令行工具,是對這三點(diǎn)的有效整合,串連成一個規(guī)范的流程。
命令行工具中,使用的第三方工具包,都需要用--save的方式安裝。
體現(xiàn)在package.json的表現(xiàn)是dependencies字段:
"dependencies": {
 "chalk": "^2.4.2",
 "commander": "^3.0.0",
 "fs-extra": "^8.1.0",
 "inquirer": "^6.5.0",
 "mem-fs": "^1.1.3",
 "mem-fs-editor": "^6.0.0",
 "shelljs": "^0.8.3"
},這樣,其他用戶在安裝你發(fā)布的CLI工具時,才會自動安裝這些依賴。
我創(chuàng)作的npm-package-cli,是專門用于生成個人npm package項目的CLI工具。
生成的項目,囊括以下功能點(diǎn):
支持TypeScrpt
mocha+chai自動化測試,支持使用TypeScript編寫測試用例支持測試覆蓋率
coverage支持eslint,包括對TypeScript的lint檢查
Git commit規(guī)范提交
Git版本自動打標(biāo)簽(standard-version),更新CHANGELOG.md
輸出的npm包
支持各種模塊規(guī)范(AMD、CMD、CommonJS、ESModule)
CLI工具安裝方式:
npm install -g npm-package-cli
開源倉庫地址:https://github.com/wall-wxk/npm-package-cli
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“node如何實(shí)現(xiàn)項目工程自動初始化”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
                分享名稱:node如何實(shí)現(xiàn)項目工程自動初始化
                
                當(dāng)前鏈接:http://chinadenli.net/article18/gejjdp.html
            
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、服務(wù)器托管、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、動態(tài)網(wǎng)站、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
