這是第 55 篇不摻水的原創,想獲取更多原創好文,請掃 👆 上方二維碼關注咱們吧~ 本文首發於政採雲前端團隊博客:分分鐘教會你搭建企業級的 npm 私有倉庫html
npm 做爲一種包管理工具,不管你是泛前端仍是大前端都已經離不開它。它的出現方便了萬千少年。讓咱們跨過了 Ctrl+C、Ctrl+V ,經過 npm install x
的方式將別人的優秀代碼模塊引入到本身的項目中。這些優秀的模塊能被共享的緣由,一方面是有 npm 這麼一個包管理工具,另外就是 npm 倉庫。前端
對於 npm 倉庫,若是你還停留在使用 npm 或者 cnpm 這類官方源的狀況下。那麼你有必要想一想如何搭建一個私有的 npm 倉庫。下面從三個方面講解企業級 npm 私有倉庫搭建那些事兒,分分鐘教會你。node
爲何須要搭建公司的私有 npm 倉庫mysql
如何搭建私有倉庫linux
搭建私有倉庫擴展篇nginx
照慣例,先講講爲啥要搭建私有倉庫。目前已經有不少成熟的 npm 源可使用,好比:git
在已經有如此多公共倉庫的狀況下,是否有必要搞一套私有 倉庫?重複"造輪子"?仍是自嗨?若是從下面幾方面來考慮的話,或許能打消心中的疑問。github
1. 穩定性web
首先是網絡訪問穩定性,私有倉庫由於是本身公司在維護,有什麼問題能第一時間處理,好比服務宕機…其次資源的穩定性,試想一下,若是哪天你依賴的某個很重要的模塊忽然被做者刪了,那是否是完犢子了,畢竟咱們不少時候都奉行的是「拿來主義」,一旦碰見這種狀況,基本上全抓瞎。若是有私有倉庫,上面的問題能夠從容面對,有效的保障了業務穩定。sql
2. 私密性
每一個公司都有和本身業務強相關的模塊,或者對某些開源模塊進行個性化的改造,改造後的模塊只知足本公司的業務場景,這些模塊咱們並不但願發佈到公共的倉庫中去,這時就能夠發佈到本身的私有倉庫在公司內部共享。
3. 安全性
有了私有倉庫後,能夠在 npm 模塊的質量和安全上作文章,可以有效的防治惡意代碼攻擊。
綜上,搭建本身公司的私有倉庫徹底有必要,這並非秀。固然,若是你所在的公司比較 mini ,對於上面的幾點需求並非那麼迫切,使用公共倉庫也挺好。但當公司發展到必定規模,在將來可預見的狀況下,那就是時候準備搭建本身的私有倉庫了。
目前已經有許多成熟開源方案,選擇站在巨人的肩膀上不失爲一種良策。這裏選擇cnpmjs.org方案,緣由有三:
目前國內像淘寶這樣的大廠內部也是選擇的它,足以證實它的可靠行和穩定性
擴展性強
配置多樣化
固然缺點也不是沒有,就是部署有那麼一丟丟複雜。
兵馬未動,糧草先行,既然是搭建企業級的應用,基礎環境得備好。
Linux 服務器
node 環境
數據庫( Mysql )
nginx
大概就這些,若是你只是熟悉一下,搭着玩兒。也不必定得用 Linux 服務器,Windows 也行,可是若是是做爲線上應用,建議仍是使用 Linux 服務器,畢竟 Linux 的穩定性在那裏擺着。
下面的示例是在雲服務器(Ubuntu)上完成的。
建議經過 git 將 cnpmjs.org 的項目源碼克隆到服務器本地某個目錄下。或者將代碼fork到本身git倉庫後,再基於內部倉庫進行部署,這樣方便之後對源碼進行個性化的改造。
git clone https://github.com/cnpm/cnpmjs.org.git
複製代碼
安裝項目依賴:
npm i
複製代碼
安裝完成後找到項目根目錄下的配置文件config/index.js
,這裏配置文件很是多,剛開始能夠只關注下面幾項便可,詳細配置戳這裏。
服務訪問端口
registryPort: 7001, //倉庫服務訪問端口
webPort: 7002, //web站點訪問端口
bindingHost: '', //監聽綁定的 Host,默認127.0.0.1,外網訪問註釋掉此項便可,通常咱們不會把咱們內部端口暴露出去,能夠在nginx層作一個轉發,因此這個配置能夠註釋掉。若是直接外網訪問,配置爲 0.0.0.0
複製代碼
數據庫配置
database: {
db: 'npm',數據庫名稱
username: 'admin',//用戶
password: 'admin123',//密碼
// 數據庫類型
// - 目前支持 'mysql', 'sqlite', 'postgres', 'mariadb'
dialect: 'mysql',//默認是sqlite,我選擇的mysql
host: '127.0.0.1', //數據庫服務地址
port: 3306, // 端口
// 數據庫鏈接池使用默認配置就好
// 目前只支持 mysql 和 postgresql (since v1.5.0)
pool: {
maxConnections: 10,
minConnections: 0,
maxIdleTime: 30000
},
...//其餘的暫時不用關注
},
複製代碼
是否啓用私有模式
enablePrivate: false,//默認不啓用
複製代碼
私有模式下,只有管理員才能發佈模塊。非管理員發佈模塊式命名必須以 scopes 字段開頭例如:@catfly/packagename
。
發佈前綴
scopes: ['@catfly'],
複製代碼
這個和啓用非私有模式配套使用,非私有模式要發佈必須配置該項。
管理員帳號配置
admins: {
fengmk2: 'fengmk2@gmail.com',
admin: 'admin@cnpmjs.org',
dead_horse: 'dead_horse@qq.com',
}
複製代碼
若是啓用私有模式,只有該配置項中的用戶能夠發佈私有包。至於其餘的配置項暫時不用關注,後面根據須要在逐漸配置起來。
同步模式
// 同步模式選項
// none: 不進行同步,只管理用戶上傳的私有模塊,公共模塊直接從上游獲取
// exist: 只同步已經存在於數據庫的模塊
// all: 定時同步全部源registry的模塊
syncModel:'exist'
複製代碼
數據庫
我選擇的 mysql ,這裏不介紹怎麼安裝 mysql 了,有須要請戳這裏。固然你也能夠選擇其餘數據庫,目前支持mysql 、 sqlite 、 postgres 、 mariadb ,默認是 sqlite 。
先檢查一下數據庫服務狀態,確保數據庫服務沒毛病:
登陸數據庫
mysql -u root -p test123456
複製代碼
建立數據庫
create database npm;
複製代碼
查看數據庫列表:
建立數據庫表
cnpmjs.org 項目 docs 目錄下已經給咱們備好了建立數據庫的腳本 db.sql 。執行:
source docs/db.sql;
複製代碼
默認當前操做路徑就在 cnpmjs.org 項目下,若是不是,請用 db.sql 的絕對路徑。
查看結果:
上面兩步完成後,就能夠將項目跑起來一睹芳容了。由於咱們經過 git 克隆的,因此須要進入到項目目錄下執行啓動服務的命令
npm run start
複製代碼
啓動成功後,訪問 web 頁面,發現以前配置文件中的 web 端口 7002 訪問不了。
這是由於服務器防火牆的緣由,能夠選擇關閉防火牆,可是這種方式不推薦;另一種就是開放指定端口。
iptables -A INPUT -p tcp --drop -j 7002 DROP
複製代碼
若是你是使用的雲服務器,須要去雲服務控制檯,新增安全組,將暴露的端口放開。
端口開放後,訪問 web 頁面:xxx.xxx.xxx.xx:7002,就能夠看見熟悉的 cnpm 頁面了。
在上面這張的訪問地址能夠看到,用了域名,並非用的 IP+ 端口的形式,由於做爲一個企業級的應用,IP+ 端口的方式就如同裸奔同樣,建議採用域名的方式。我在本身的雲服務域名管理下新增了一個子域名。
而後配置 nginx 將 IP 和域名進行綁定,統一使用默認的 80 端口,儘可能不要將私有倉庫服務的真實端口和 IP 暴露出來。這裏順便把 nginx 配置也說一下,若是你能接受 IP+ 端口訪問的方式,能夠跳過下面這一步。
若是沒有安裝nginx,戳這裏。找到 nginx 配置文件,在 conf.d 文件夾信息新增 npm.conf 配置文件,這樣功能清楚明白,由於不少時候 nginx 不是隻代理這個一個服務。
server{
listen 80;
server_name www.mirrors.catfly.vip;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://127.0.0.1:7002/; #代理到cnpmjs.org提供的web服務
proxy_set_header X-Real-IP $remote_addr;
}
location /registry/ {
proxy_pass http://127.0.0.1:7001/; # 代理到cnpmjs.org提供的註冊服務
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
# error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
複製代碼
重啓 nginx :
service nginx restart
複製代碼
檢查 nginx 狀態,防止配置錯誤,致使重啓失敗。
經過上面的環境搭建和部署,基本工做就完成了,下面開始驗證功能。
在驗證以前推薦安裝一個 npm 源管理模塊 nrm ,有了它咱們能夠在各類源之間自由切換。
npm i nrm -g
複製代碼
安裝成功後新增咱們本身的私有源到nrm源列表中。
nrm add catfly http://www.mirrors.catfly.vip/registry
複製代碼
切換到私有源:
nrm use catfly
複製代碼
這個時候本地執行 npm 操做的時候就會去找到咱們本身的私有地址。
私有包發佈
註冊用戶:
npm adduser
複製代碼
登陸私有倉庫:
npm login
複製代碼
登陸成功後,發佈 npm ,在已準備好的模塊目錄執行:
npm publish
複製代碼
這個時候可能會出現各類錯誤,主要是403權限問題,由於私有倉庫在不一樣模式下須要知足不一樣的條件,例如:
在非私有模式( enablePrivate: false)下,當用戶不用具有管理員權限,模塊命名前綴必須帶有配置中規定的scope ,若是不存在或者 scopes 中不包含該 scope 就會報錯。
在私有模式(enablePrivate: true)下,若是用戶不在配置文件的 admins 中,則不容許執行發佈操做,反過來若是在,那麼他的權限就很是大了,不只能發佈還能刪除。因此真實場景下不要讓管理員帳號氾濫。
包下載安裝
發佈成功後,嘗試安裝發佈的私有包:
npm i xxxxx
複製代碼
沒毛病。
Web工做臺
訪問私有倉庫的web站點
經過這個 站點能夠對私有包的發佈、刪除以及下載進行統計,還能夠私有包搜索功能。也能夠對這個 web站點進行個性化改造。代碼、數據都在咱們這邊,想怎麼造就怎麼造。
在真實的企業級應用中,在上面的基礎上還能夠進行擴展,下面介紹一下能夠擴展的幾個方面:
推薦使用 pm2 進行進程管理,雖然項目自己提供了npm run start
和npm run stop
的能力,可是這對於一個企業級的應用來講仍是太弱了,使用 pm2 的好處以下:
npm i pm2 -g
複製代碼
pm2 start ./dispatch.js //dispatch.js在cnpmjs.org項目的根目錄下
複製代碼
執行完後,能夠看見該服務的基本信息,簡潔明瞭。
pm2 monit dispatch //diapatch爲當前進程name
複製代碼
這裏能夠實時查看進程運行的詳細信息,方便平時項目的維護。pm2 還有好多強大的功能,這裏就不一一介紹了,有興趣的戳這裏。
cnpmjs.org 項目配置項裏面有一個 nfs
配置,這裏定義了一個 npm 文件系統(NFS)。私有倉庫在同步和上傳的時候,會交給 NFS 對象相應的函數去處理,NFS 對象返回處理結束以後再返回下載連接,因此經過自定義 NFS 模塊能夠實現 npm 包的各類定製存儲。目前官方默認使用fs-cnpm
,該模塊會將上傳或者同步的包保存在服務器本地的/root/.cnpmjs.org/doenloads/
目錄下。這種方式比較傳統,一方面隨着私有包數量的不斷增長,存儲資源會是一個瓶頸。另外一方面須要定時的備份資源,否則哪天磁盤壞了,那就只有
這個時候將私有包或者同步的資源放到雲上就是一個很是好的方案。cnpmjs.org 官方早就爲咱們想到了這點,給出了下面幾種 NFS 模塊:
這些模塊已經可以知足咱們絕大部分的場景,若是你有特殊的需求,能夠參看nfs模塊規範進行定製化開發。這裏拿阿里雲 oss 存儲做爲示例。
首先在 cnpmjs.org 項目目錄下安裝oss-cnpm
模塊
cnpm i oss-cnpm
複製代碼
而後在雲服務控制檯 oss 管理中新增了一個 bucket 來存儲 npm 包,也能夠經過上傳路徑區分來複用其餘 bucket,畢竟在公司中 bucket 資源通常仍是比較緊張的。而後修改項目配置文件,將默認的fs-cnpm
模塊替換成oss-cnpm
。
var oss = require("oss-cnpm");
var nfs = oss.create({
accessKeyId: 'xxxx',
accessKeySecret: 'xxx',
endpoint: 'oss-cn-beijing.aliyuncs.com',
bucket: 'catfly-xxx',
mode: 'private',
})
var config = {
...,
nfs:nfs,
...
}
複製代碼
重啓項目,這個時候再發布或者同步資源的時候,服務器本地目錄不會有新發布或同步的包了,在 oss 對應的 bucket 裏面能找到剛剛發佈或者同步的資源。
但願這篇文章對你有所幫助。
政採雲前端團隊(ZooTeam),一個年輕富有激情和創造力的前端團隊,隸屬於政採雲產品研發部,Base 在風景如畫的杭州。團隊現有 50 餘個前端小夥伴,平均年齡 27 歲,近 3 成是全棧工程師,妥妥的青年風暴團。成員構成既有來自於阿里、網易的「老」兵,也有浙大、中科大、杭電等校的應屆新人。團隊在平常的業務對接以外,還在物料體系、工程平臺、搭建平臺、性能體驗、雲端應用、數據分析及可視化等方向進行技術探索和實戰,推進並落地了一系列的內部技術產品,持續探索前端技術體系的新邊界。
若是你想改變一直被事折騰,但願開始能折騰事;若是你想改變一直被告誡須要多些想法,卻無從破局;若是你想改變你有能力去作成那個結果,卻不須要你;若是你想改變你想作成的事須要一個團隊去支撐,但沒你帶人的位置;若是你想改變既定的節奏,將會是「 5 年工做時間 3 年工做經驗」;若是你想改變原本悟性不錯,但老是有那一層窗戶紙的模糊… 若是你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的本身。若是你但願參與到隨着業務騰飛的過程,親手推進一個有着深刻的業務理解、完善的技術體系、技術創造價值、影響力外溢的前端團隊的成長曆程,我以爲咱們該聊聊。任什麼時候間,等着你寫點什麼,發給 ZooTeam@cai-inc.com