文章出處

隨著前端隊伍越來越壯大,項目間共享代碼就變得尤為重要。常用的框架/類庫沒必要在每個項目都放一份,團隊內部產出的公共模塊也需要有合理的共享機制。現在,用npm管理前端代碼已經是業界趨勢。樓主嘗試用私有npm+資源管理系統的方式搭建起一套前端資源倉庫,用以在公司內部托管公共代碼,并為開發環境提供代碼源。本文記錄一下搭建過程,或許可以給大家做個參考。

 

整體架構

搭建私有npm的話其實是非常簡單的,github上有一個叫做sinopia(https://github.com/rlidwka/sinopia)的項目,使用相當簡單,無需配置數據庫。用阿里的cnpm也是可以搭建私有npm的,不過配置稍微麻煩些。鑒于只是beta階段,所以我就先采用簡單的sinopia了。npm有兩個作用:1.托管公共代碼;2.為開發環境提供代碼源。也就是說在開發環境,只需npm install,相應的代碼就被下載到項目中。當然我們應該配置ignore,使得node_modules文件夾不被提交到代碼庫。線上的資源都是走cdn的。

光是私有npm還是不夠的,考慮到公司不斷有新的前端入職,有些還是新手,所以有必要為每個模塊提供詳細的說明。包括不限于基本信息、使用方法、在線demo、cdn地址等等。使用README.md文件雖然也能描述很多信息,但它只是一個靜態文件,我們的系統還需要具備發布到npm、同步到cdn的功能。以后也可能進行功能擴充,比如為前端工程化提供支持。所以還需要一個資源管理系統,這個系統用于維護公共資源的各種信息。

所以,這么考慮下來,我們的前端資源倉庫應該包含兩部分:資源管理系統、私有npm。各自的功能如下:

 

資源倉庫的維護

所謂維護就是把源代碼錄入到資源管理系統、發布到npm、同步到cdn這一過程。按照npm的規格來組織模塊的目錄結構,但也不完全一致,因為有些是不需要的。模塊都用UMD格式包裝,這樣無論用加載器還是直接寫<script>標簽都是可用的。具體格式如下:

  1. 用模塊的名稱命名根目錄

  2. 模塊的不同版本,新建不同的目錄,如jquery/1.8.3/src/jquery.js,jquery/2.1.0/src/jquery.js

  3. src目錄,用于放置未壓縮的源碼

  4. dist目錄,用于放置壓縮后的代碼

  5. 使用package.json文件的規格來描述本模塊

這樣就夠了,系統提供發布功能,上傳的文件會自動發布到我們的npm,并且同步到cdn。至于模塊的使用方法等其他信息,則需要模塊維護者手動錄入到系統中。這樣,私有npm與這個資源管理系統就沒有任何耦合,將來也好做擴展。流程如下:

關于cdn的同步,我們只同步dist目錄下的文件,因為線上只需要壓縮版。至于模塊的打包,不在本系統的職責范圍內,由項目內的構建程序去完成。

 

如何使用

對于使用者,也就是前端同事們,需要做這么幾件事:

  1. 項目中配置好package.json,npm install安裝好所需的模塊

  2. 從資源管理系統中獲取到各模塊的cdn地址

  3. 配置項目中的各模塊地址,開發環境請求本地node_modules下的文件,線上環境請求cdn。

  4. 使用gulp進行相關的構建,發布到測試環境/線上環境

在npm install前,需要把倉庫地址指向我們搭的私有npm,而不再是npm官方的地址。使用npm set resigtry命令。如果你覺得麻煩,或者需要經常改動地址,github上有一個很方便的registry管理工具,nrm(https://github.com/Pana/nrm),推薦使用。

第3步需要做一個說明,因為我們現在項目很多,各項目的目錄結構也不一致,有的前后端還未分離,所以無法做到用同一套構建程序搞定所有的項目。配置的方法視項目的情況而定,可以依靠后端來動態給require.config賦值,也可以用gulp來進行編譯,總之能達到在不同環境請求不同路徑就行。

 

技術細節

sinopia的話照著文檔去安裝就行。因為我們是安裝在服務器上,所以有兩點配置需要注意:

  1. node_modules/sinopia/conf下的default.yaml中,listen: - 0.0.0.0:4873,使得其他機器可以訪問到該端口

  2. 在sinopia的存儲目錄下,有一個config.yaml,把proxy: npmjs注掉。我們公司內部可能只維護幾個特定版本,所以沒必要和官方倉庫同步。

sinopia有一個機制,當你從私有npm安裝一個模塊時,如果不存在,會從npm官方倉庫拉取,也就是這個proxy配置的地址。我們注掉后,也就無法去官方倉庫去拉了,而這正是我需要的。一方面通過一個代理去訪問npm有不穩定的風險,另一方面,我需要使用者時刻清楚,自己安裝的模塊是哪個倉庫的。

至于資源管理系統的開發,后端使用nodejs、express,mongodb數據庫,前端使用mvvm框架,還用了一個叫semantic的UI框架。基本就是對資源的增刪改查操作,基本也沒什么難度 。資源包含的字段如下:

其中,類別暫時分為三類:

  1. 框架/類庫。已經成熟的框架/類庫,基本不會修改其代碼,如jquery、requirejs

  2. 第三方組件。UI組件及功能組件,來自于第三方,不像框架那樣穩定且有長期維護,例如:datepicker、彈框插件

  3. 自研模塊。公司內部自己寫的模塊,通用的業務模塊、功能模塊

關于發布npm。在系統中上傳源碼的zip文件,先進行解壓,然后使用了nodejs的child_process模塊用來執行npm install命令,代碼片段如下:

var exec = require('child_process').exec;
exec('npm publish '+targetPath, function (error, stdout, stderr) {
    if (error !== null) {
        console.log('exec error: ' + error);
        res.json({success: false, message: error});
    }
    res.json({success: true, message: {name: filePath} });
});

至于cdn的同步,請到了我們運維同學的幫忙,我只要把文件上傳至相關目錄即可,后面的操作由他來搞~。

至此,我們的前端資源倉庫就搭建起來了,服務器上使用pm2來管理,把sinopia和資源管理系統的server.js起來就可以了。

 

總結

搭建這個項目其實難度并不大,但由于是抽空閑時間來搞,前前后后花了兩個月時間。主要是花在系統的設計上。目前還是beta版,陸續會更新內容,先運行起來讓同事們嘗嘗,估計會有大量的建議和問題,后面再做升級吧。各位朋友有任何建議,也可以給我留言,不甚感激。最后,截圖來曬一下吧:

 

注:本篇博客的微信公眾號轉發唯一授權給前端早讀課,其他微信公眾號不得轉發,否則將受到侵權投訴。

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()