NodeJs的出現,讓前端工程化的理念不斷深刻,正在向正規軍靠近。先是帶來了Gulp、Webpack等強大的構建工具,隨後又出現了vue-cli和create-react-app等完善的腳手架,提供了完整的項目架構,讓咱們能夠更多的關注業務,而沒必要在項目基礎設施上花費大量時間。html
平時咱們都只專一在業務上的開發,拿起一套開箱即用的模板項目就直接幹。可是,這些現成的腳手架未必就能知足咱們的業務需求,也未必是最佳實踐,這時咱們就能夠本身開發一個腳手架,那麼咱們使用的腳手架裏面到底作了什麼,如何本身搭建腳手架呢?前端
腳手架代碼github地址:https://github.com/hourong88/...vue
如下爲正文,文章結構:node
1.腳手架須要實現什麼?react
初始化項目模版能力。git
2.腳手架須要什麼功能?github
3.用什麼工具實現?vue-cli
固然還有,download-git-repo git倉庫代碼下載,ora 命令行加載中效果等優化依賴工具,均可以在此基礎上,進行豐富。npm
如下分爲兩步完成:json
咱們正常的流程是建立本地腳手架,綁定git倉庫,發佈包,從易到難,咱們反過來,本文先講怎麼發一個最簡單的npm包,而後把腳手架搭好了,走一遍發包流程,就OK了。
首先,咱們須要建立一個項目,這裏就叫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 login
登陸,須要輸入username
、password
、email
npm whoami
檢查本身是否成功登錄npm link
本地調試,上面已經調試的,跳過這一步npm publish
發佈//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,那個捉急。下面總結了幾個報錯檢查清單:
通常發佈不了,按照以上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
可使用,徹底能夠知足咱們的須要。
npm install chalk commander download-git-repo inquirer ora --save
"bin": { "portal-cli": "bin/index.js" },
固然目錄結構你能夠隨意定義,package.json裏面bin從哪裏起,主要文件就放哪兒。
#!/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
命令交互工具
具體使用文檔: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...