npm 全局安装vuecli报错_前端脚手架CLI生成模版命令工具(包括,npm包的发布,脚手架的搭建,注意事项,优化等)...
NodeJs的出現(xiàn),讓前端工程化的理念不斷深入,正在向正規(guī)軍靠近。先是帶來(lái)了Gulp、Webpack等強(qiáng)大的構(gòu)建工具,隨后又出現(xiàn)了vue-cli和create-react-app等完善的腳手架,提供了完整的項(xiàng)目架構(gòu),讓我們可以更多的關(guān)注業(yè)務(wù),而不必在項(xiàng)目基礎(chǔ)設(shè)施上花費(fèi)大量時(shí)間。
平時(shí)我們都只專注在業(yè)務(wù)上的開發(fā),拿起一套開箱即用的模板項(xiàng)目就直接干。但是,這些現(xiàn)成的腳手架未必就能滿足我們的業(yè)務(wù)需求,也未必是最佳實(shí)踐,這時(shí)我們就可以自己開發(fā)一個(gè)腳手架,那么我們使用的腳手架里面到底做了什么,如何自己搭建腳手架呢?
腳手架代碼github地址:https://github.com/hourong88/portal-cli
點(diǎn)擊文章末尾,【閱讀原文】即可訪問(wèn)
以下為正文,文章結(jié)構(gòu):
提問(wèn)
1.腳手架需要實(shí)現(xiàn)什么?
初始化項(xiàng)目模版能力。
2.腳手架需要什么功能?
3.用什么工具實(shí)現(xiàn)?
- commander.js 命令行工具
- chalk 命令行輸出樣式美化
- Inquirer.js 命令行交互
當(dāng)然還有,download-git-repo git倉(cāng)庫(kù)代碼下載,ora 命令行加載中效果等優(yōu)化依賴工具,都可以在此基礎(chǔ)上,進(jìn)行豐富。
以下分為兩步完成:
我們正常的流程是創(chuàng)建本地腳手架,綁定git倉(cāng)庫(kù),發(fā)布包,從易到難,我們反過(guò)來(lái),本文先講怎么發(fā)一個(gè)最簡(jiǎn)單的npm包,然后把腳手架搭好了,走一遍發(fā)包流程,就OK了。
一、發(fā)布npm包
本地創(chuàng)建項(xiàng)目
首先,我們需要?jiǎng)?chuàng)建一個(gè)項(xiàng)目,這里就叫portal-cli, 項(xiàng)目結(jié)構(gòu)如下:
-?commands??//?此文件夾用于放置自定義命令-?utils
-?index.js??//?項(xiàng)目入口
-?readme.md
為了測(cè)試,我們先在index.js放點(diǎn)內(nèi)容:
#!/usr/bin/env?node//?必須在文件頭添加如上內(nèi)容指定運(yùn)行環(huán)境為node
console.log('hello?cli');
對(duì)于一般的nodejs項(xiàng)目,我們直接使用node index.js就可以了,但是這里是腳手架,肯定不能這樣。我們需要把項(xiàng)目發(fā)布到npm,用戶進(jìn)行全局安裝,然后就可以直接使用我們自定義的命令,類似portal-cli這樣。
所以,我們需要將我們的項(xiàng)目做下改動(dòng),首先在package.json中添加如下內(nèi)容:
?"bin":?{????"portal-cli":?"index.js"
??},
這樣就可以將portal-cli定義為一個(gè)命令了,但此時(shí)僅僅只能在項(xiàng)目中使用,還不能作為全局命令使用,這里我們需要使用npm link將其鏈接到全局命令,執(zhí)行成功后在你的全局node_modules目錄下可以找到相應(yīng)文件。然后輸入命令測(cè)試一下,如果出現(xiàn)如下內(nèi)容說(shuō)明第一步已經(jīng)成功一大半了:
anna@annadeMacBook-Air?job?%?>?portal-cli?hello?cli
*如果全局有bin相同名字的,會(huì)報(bào)錯(cuò),需要把package.json里面bin起的名字修改一下
發(fā)布npm包注意事項(xiàng):
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.
我發(fā)布包的時(shí)候,調(diào)整了幾次,報(bào)錯(cuò),不是403就是404,那個(gè)捉急。下面總結(jié)了幾個(gè)報(bào)錯(cuò)檢查清單:
一般發(fā)布不了,按照以上5點(diǎn)進(jìn)行檢查,可以解決。
檢查第2步npm源的方法
查看本地當(dāng)前使用的源
registry npm config get registry
切換源
registry npm config set registry
臨時(shí)切換
registry npm publish --registry
設(shè)置完以后,再次查看當(dāng)前源是否是http://registry.npmjs.org
注意:國(guó)內(nèi)目前發(fā)布組件時(shí),必須切換為npmjs,否則npm publish也不會(huì)成功
**************
科普npm registry
簡(jiǎn)單來(lái)說(shuō),npm registry就相當(dāng)于一個(gè)包注冊(cè)管理中心。它管理著全世界的開發(fā)者們發(fā)布上來(lái)的各種插件,同時(shí)開發(fā)者們可以通過(guò)npm install的方式安裝所需要的插件。
npm官方registry為:http://registry.npmjs.org/
國(guó)內(nèi)速度較快的為:https://registry.npm.taobao.org/
**************
以上涉及到的關(guān)鍵命令:
npm?link??//?本地調(diào)試npm?publish??//?發(fā)布
npm?whoami??//查看當(dāng)前登陸的用戶名
每次更新包需要同步更新版本號(hào),發(fā)布的包需要發(fā)布72小時(shí)以后才可以廢棄刪除。
二、本地腳手架搭建
上文中,我們既然是搭建腳手架,肯定不能只讓它輸出一段文字吧,我們還需要定義一些命令,用戶在命令行輸入這些命令和參數(shù),腳手架會(huì)做出對(duì)應(yīng)的操作。這里不需要我們自己去解析這些輸入的命令和參數(shù),有現(xiàn)成的輪子commander可以使用,完全可以滿足我們的需要。
npm install chalk commander download-git-repo inquirer ora --save
????"portal-cli":?"bin/index.js"
??},
當(dāng)然目錄結(jié)構(gòu)你可以隨意定義,package.json里面bin從哪里起,主要文件就放哪兒。
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?版本號(hào)
commander.version(version,?'-v,?--version')
??.command('init?')
??.alias("i")
??.description("輸入項(xiàng)目名稱,初始化項(xiàng)目模版")
??.action(async?(projectName,cmd)?=>?{
????await?checkDire(path.join(process.cwd(),projectName),projectName);???//?檢測(cè)創(chuàng)建項(xiàng)目文件夾是否存在
????inquirer.prompt(promptTypeList).then(result?=>?{?//inquirer?交互問(wèn)答
??????const?{url,?gitName,?val}?=?result.type;
??????console.log("您選擇的模版類型信息如下:"?+?val);
??????console.log('項(xiàng)目初始化拷貝獲取中...');
??????if(!url){
????????console.log(chalk.red(`${val}?該類型暫不支持...`));
????????process.exit(1);
??????}
??????exec('git?clone?'?+?url,?function?(error,?stdout,?stderr)?{??//git倉(cāng)庫(kù)代碼下載
????????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(項(xiàng)目模版創(chuàng)建成功)`));
??????????}
????????});
??????});
????})
??});
commander.parse(process.argv);
以上代碼解析:
1). checkDire檢查創(chuàng)建項(xiàng)目文件夾是否存在
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 命令行進(jìn)入交互問(wèn)答?
3). 交互問(wèn)答用inquirer命令交互工具
- question 數(shù)組為交互命令配置,數(shù)組中每一個(gè)對(duì)象都對(duì)應(yīng)一個(gè)執(zhí)行命令時(shí)候的一個(gè)問(wèn)題
- type為該提問(wèn)的類型,name為該問(wèn)題的名字,可以在后面通過(guò)name拿到該問(wèn)題的用戶輸入答案
- message為問(wèn)題的提示
- default則為用戶沒(méi)輸入時(shí)的默認(rèn)為其提供一個(gè)答案
- validate方法可以校驗(yàn)用戶輸入的內(nèi)容,返回true時(shí)校驗(yàn)通過(guò),若不正確可以返回對(duì)應(yīng)的字符串提示文案
- transformer為用戶輸入問(wèn)題答案后將對(duì)應(yīng)的答案展示到問(wèn)題位置,需要有返回值,返回到字符串為展示內(nèi)容
具體使用文檔:https://github.com/SBoudrias/Inquirer.js
4). 問(wèn)答結(jié)束的回調(diào)prompt方法中then里的參數(shù)是一個(gè)對(duì)象,從配置里面拉取git倉(cāng)庫(kù)代碼。后面你們使用的時(shí)候,拉不下來(lái),看不是不是沒(méi)有倉(cāng)庫(kù)代碼權(quán)限。
module.exports??=?{??npmUrl:?'https://registry.npmjs.org/xxx-cli',
??promptTypeList:[{
??????type:?'list',
??????message:?'請(qǐng)選擇拉取的模版類型:',
??????name:?'type',
??????choices:?[{
????????name:?'portal前端框架',
????????value:?{
??????????url:?'http://192.168.3.51/xxx/portal-frame.git',?//框架git倉(cāng)庫(kù)
??????????gitName:?'portal-frame',
??????????val:'portal前端框架'
???
????????}
??????}]
??}],
};
5).git clone下載前端框架。也可以用download-git-repo git倉(cāng)庫(kù)代碼下載
以上,就是全部前端腳手架內(nèi)容,總共四個(gè)文件,index.js是最重要的(引用另外兩個(gè)配置文件),加上一個(gè)package.json。
執(zhí)行以下命令發(fā)布:
npm?link?//?本地調(diào)試npm?publish?//?發(fā)布
三、如何使用?
在需要用到框架的時(shí)候,新建空文件夾,執(zhí)行:
npm?install?portal-cli?-g??//全局安裝portal-cliportal-cli?init???//portal-cli?init?test?,test就是你放文件夾的名稱,可以自己定義
這樣前端腳手架生成模版命令工具就完成了。如果想更個(gè)性化,可以把npm包完善一下,包括包的版本說(shuō)明,readme;豐富腳手架交互問(wèn)詢內(nèi)容,美化操作提示等。
結(jié)語(yǔ)
node.js,本質(zhì)還是js,js熟悉以后,結(jié)合node依賴和語(yǔ)法,各種試錯(cuò),調(diào)試,需要耐心和細(xì)心。
另外,開始做一個(gè)實(shí)例的時(shí)候,構(gòu)思思路,注意流轉(zhuǎn)順序。主要以官方文檔為主,網(wǎng)上博客文章為輔。
官方的還是靠譜一點(diǎn),博客各種坑,不是過(guò)時(shí)了,就是講的不連貫,沒(méi)有可執(zhí)行性。
總的來(lái)說(shuō),學(xué)習(xí)也是一個(gè)探索的過(guò)程,共同進(jìn)步!
以上【完】
參考:
https://www.cnblogs.com/cangqinglang/p/11225166.html
https://segmentfault.com/a/1190000021390776
Inquirer.js:https://github.com/SBoudrias/Inquirer.js
npm包生命周期:https://segmentfault.com/a/1190000017461666
總結(jié)
以上是生活随笔為你收集整理的npm 全局安装vuecli报错_前端脚手架CLI生成模版命令工具(包括,npm包的发布,脚手架的搭建,注意事项,优化等)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 手机上python编程工具3和3h有区别
- 下一篇: reload vue 重新加载_vue面