《大前端進階 Node.js》系列 P6必備腳手架/CI構建能力(下)

接水怪發表於2020-04-01

前言

Coding 應當是一生的事業,而不僅僅是 30 歲的青春?
本文已收錄 Github https://github.com/ponkans/F2E,歡迎 Star,持續更新?

P6 前端必備腳手架 /CI 構建能力,順著怪怪的思路往下看,然後獲取文章末尾的原始碼,跟著原始碼操作一遍,就是一個完整的前端腳手架構建、釋出、部署工程化專案。

本文中 cli 已釋出至 npm 倉庫,如下:


每篇文章都希望你能收穫到東西,這篇是前端專案的自動化構建部署,希望你看完,能夠有這些收穫:

  • CLI 建立遠端倉庫
  • CLI 打包
  • Nginx 部署
  • Webhook 觸發 Jenkins 打包部署服務
  • Jenkins 打包部署
  • CI 構建

架構圖

下圖中左邊部分的專案初始化、模板拉取、專案執行部分,在《大前端進階 Node.js》系列 P6 必備腳手架/CI 構建能力(上)中,已經實現了。

今天實現右邊部分,也就是 CI 部分(大家平時經常用的前端專案釋出系統,大致就是這麼個東西)。

完整架構
完整架構

前期準備

GitHub 賬號

專案如果只是儲存在本地很容易因為一些意外情況(比如咖啡倒了、和媳婦吵架電腦摔了等等)導致程式碼丟失,而且不方便多人合作開發維護,所以我們都是需要遠端倉庫儲存專案的,本文使用的是 GitHub 倉庫,如果大家想要跟蹤實踐,要先準備好 GitHub 賬號。

server

為了讓使用者可以通過網路瀏覽器之類的客戶端在因特網上訪問我們的網頁,我們需要一臺 server 來部署專案,這樣使用者就可以通過公網 IP 訪問我們的網頁了。

本文用的是 aliyun server,有條件的話也可以準備一個,當然沒條件也不要慌,我們電腦也是一臺 server,有它在手四海八荒都可以走一朝。

server 部署

  • 安裝 Nginx

  • 安裝 node

  • 安裝 yum

    PS:yum 是一個 Shell 前端軟體包管理器。基於 RPM 包管理,能夠從指定的 server 自動下載 RPM 包並且安裝,可以自動處理依賴性關係,並且一次安裝所有依賴的軟體包,無須繁瑣地一次次下載、安裝。

    比如,Jenkins 使用 yum 安裝就很方便快捷。

CLI 建立遠端倉庫

命令列建立倉庫

有時候為了將本地的專案倉庫同步到 Github,我們還得開啟瀏覽器去自己的 Github 賬戶下建立一個空倉庫,打斷了自己的工作流,如果我們可以通過命令列的形式建立 Github 倉庫並關聯本地專案豈不是完美,並且命令列還可以整合到我們的 CLI 工具裡,只要想不到沒有做不到的,下面我們就介紹下如何通過命令列建立倉庫。

首先在你的 Github 上建立一個 token 建立地址,在命令列建立專案的時候需要這個 token 做校驗

(select scopes 我全部勾上了,畢竟加班加點趕文章,來不及仔細研究,見諒見諒)

一定要把生成的 personal access token 儲存下來,只會顯示一遍,不記下來以後就找不到了

通過命令列建立 Github 倉庫
curl -u "$username:$token" https://api.github.com/user/repos -d '{"name":"$repo_name"}'
複製程式碼

這裡需要把上述 username 和 token 分別換成實際的使用者名稱和剛才記住的 personal access token,把 repo_name 換成任何想要的倉庫名。

將命令列建立 Github 倉庫的功能整合到 CLI 工具裡

我們上期文章有介紹到 CLI 有個初始化的功能,接下來我們將命令列建立 Github 倉庫的功能補充到初始化命令裡,先列 yi 一下 CLI 初始化要做的事情:

  • Git 初始化
  • 建立 Github 倉庫
  • 關聯 Github 倉庫
  • 更新 package.json 的 repository 配置
  • 提交程式碼到 Github 倉庫
  • 安裝依賴

相關程式碼在 little-bird-cli/src/init.js

try {
  await loadCmd(`git init`'git初始化');
  if (username === '' || token === '') {
    console.log(symbol.warning, chalk.yellow('缺少入參無法建立遠端倉庫'));
  } else {
    const projectName = process.cwd().split('/').slice(-1)[0];

    await loadCmd(`curl -u "${username}:${token}" https://api.github.com/user/repos -d '{"name": "${projectName}"}'`'Github倉庫建立')
    await loadCmd(`git remote add origin https://github.com/${username}/${projectName}.git`'關聯遠端倉庫')
    let loading = ora();
    loading.start(`package.json更新repository: 命令執行中...`);
    await updateJsonFile('package.json', {
      "repository": {
        "type""git",
        "url"`https://github.com/${username}/${projectName}.git`
      }
    }).then(() => {
      loading.succeed(`package.json更新repository: 命令執行完成`);
    });

    await loadCmd(`git add .`'執行git add')
    await loadCmd(`git commit -a -m 'init'`'執行git commit')
    await loadCmd(`git push --set-upstream origin master`'執行git push')
  }
  await loadCmd(`npm install`'安裝依賴')
catch (err) {
  console.log(symbol.error, chalk.red('初始化失敗'));
  console.log(symbol.error, chalk.red(err));
  process.exit(1);
}
複製程式碼

為了方便大家體驗,我這裡是把 username 和 token 作為命令列入參傳進來的,如果是你自己的專案,可以將其直接寫死在程式碼裡,在你的專案目錄下執行 lbc init -u username -t ​token 如果得到以下結果,那麼恭喜你成功啦,快去 Github 遠端倉庫檢視你的專案程式碼

image-20200330133928513

至此,大家就可以直接跨越千山和萬水,開始 Coding 啦,兩耳不聞窗外事,一心只用寫程式碼,果然是很爽

手動打包 & 部署

打包

打包可以理解為上線釋出時的預處理工作, 會將瀏覽器不能識別的語法做預處理轉換,把所有的 js 檔案, css 檔案都分別壓縮合併為一個 All in One 的 .js 和 .css 檔案。

這樣瀏覽器就可以通過少量的 HTTP 請求獲取到所需要的前端資源了, 節省流量, 加快頁面載入速度,目前比較流行的打包工具有 Gulp, Grunt, Webpack 等。

我們的 CLI 工具已經引入了 webpack,所以打包這一步還是使用 webpack 來實現。

lbc build

little-bird-cli/src/main.js命令管理檔案裡增加打包命令lbc build

webpack.build.js

增加 webpack 打包配置檔案webpack.build.js,它和我們的本地專案啟動 webpack 配置檔案的主要區別是增加了打包輸出,減少一些不需要的方法比如監聽。

output: {
  filename:'[name].[hash].js',
  path: process.cwd() + '/dist',
  publicPath'/',
}
複製程式碼
執行指令碼

增加 build 執行指令碼檔案 little-bird-cli/src/build.js

let build = () => {
    webpack(config, (error) => {
        if (error !== null){
            console.log(symbol.error, chalk.red(error));
        } else {
            console.log(symbol.success, chalk.green('打包完成'));
        }
        process.exit(1);
    });
}
複製程式碼

在專案目錄下執行lbc build,檢視 dist 目錄就可以看到打包生成的 html/js 檔案了

部署

在開始自動打包部署之前我們先來體驗下手動打包部署,正好可以校驗下我們的 CLI 打包命令在 server 端 是否可以正常使用。

接下來的操作都是在 server 環境哦~?

登入

登入你的 server,將專案程式碼 clone 到你的 server( clone 後別忘了安裝依賴npm install

安裝腳手架 npm 包

全域性安裝 CLI 包 npm i -g little-bird-cli@latest

lbc build 打包

在專案目錄執行 lbc build 打包命令,檢視在你 clone 的專案的 dist 目錄是不是生成了 html/js 檔案,如果有的話代表 CLI 打包功能在服務端正常運轉。

Nginx

修改 Nginx 配置,開啟配置檔案vim /etc/nginx/nginx.conf,root 為你 clone 專案的 dist 目錄

啟動 Nginx 服務,重啟 Nginx 服務 nginx -s reload,通過 ip:80 埠就可以訪問你的頁面了

雖然通過手動操作也能夠提供我們的專案網頁給使用者使用,但是每次有程式碼更新的時候,都需要本地 push 程式碼到遠端倉庫, 然後登入 server pull 程式碼再打包程式碼,重複性的工作能省則省,工具都是懶人發明的?,下面懶人法寶就要登場了,一勞永逸 ~

很多公司有自己的一套前端釋出系統,並不是自動部署滴,需要手動去觸發打包、部署

自動打包 & 部署基礎建設

接下我們通過使用 Jenkins+Github+Webhook 自動打包部署專案,實現 master 分支進行提交的時候,自動執行指令碼進行打包部署操作。

大家可能會疑問 Jenkins 是什麼

Jenkins 是一款開源 CI 軟體,用於自動化各種任務,包括構建、測試和部署軟體。想了解更多大家可以去官網檢視。

Webhook 又是什麼呢

通常稱其為鉤子(不是 React Hook,hhhh~~),通過定製 Webhook 來檢查 Github 上的各種事件,最常見的就是 push 事件了。

如果你設定了一個監聽 push 事件的 Webhook,每次你的專案有任何提交,這個 Webhook 都會被觸發,這時 Github 會傳送一個 HTTP POST 請求到你配置好的地址。

概念先簡單瞭解下(具體的自行 Google),接下來我們要正式開始了哦~

部署 server

我們第一步先來部署 server,首先要登入你的 server(我好像廢話了,哈哈?)。

接下來為你的 server 安裝 Jenkins。因為 jenkins 的執行需要 JDK 環境,所以我們還需要在自己的 server 上安裝 java 執行環境。

安裝 java 執行環境

檢視你的 server 是否安裝了 JDK

java -version
複製程式碼

如果出現以上資訊則表示沒有按照 JDK。可以通過 yum 安裝,步驟如下

執行命令 yum -y list java* 檢視可安裝 java 版本

選擇一個 java 版本進行安裝 yum install java-1.8.0-openjdk-devel.x86_64,根據提示完成安裝。

輸入java -version 檢視是否安裝成功

安裝 Jenkins

yum 的 repos 中預設是沒有 Jenkins 的,需要先將 Jenkins 儲存新增到 yum repos

sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
複製程式碼

執行 yum install jenkins 安裝 Jenkins

修改 Jenkins 配置

預設情況下 Jenkins 是使用 Jenkins 使用者啟動的,但是這個使用者目前系統是沒有賦予許可權的,所以我們將啟動使用者改為 root,另外 Jenkins 預設埠 8080,如果你沒有其他服務佔用 8080 埠可以不修改。

vim /etc/sysconfig/jenkins
複製程式碼

修改配置

JENKINS_USER = 'root'
JENKINS_PORT = '8001'
複製程式碼

執行 service jenkins start 啟動 Jenkins 服務

出現上述資訊表示 Jenkins 啟動成功,在瀏覽器輸入*ip:8001訪問 Jenkins 登入頁面。

然而~然而~一直在轉圈圈,訪問不了,我是誰我在哪發生了什麼❓

懵逼 1 秒鐘,開始排查問題

首先確認下 Jenkins 是否真的啟動成功了,執行 systemctl status jenkins 檢視 Jenkins 狀態

Jenkins 執行正常,為何無法訪問呢,噢!!!

再來檢測下防火牆,執行systemctl status firewalld檢視防火牆狀態

防火牆未啟動,好的, 沒問題,讓我們來啟動它 systemctl start firewalld

防火牆已啟動,讓我們來檢視防火牆有沒有開放我們設定的 Jenkins 埠,執行 firewall-cmd --list-ports 發現沒有 Jenkins 的埠,沒有也沒問題我們開啟就好了

firewall-cmd --permanent --zone=public --add-port=80/tcp  // 開啟已配置好的Jenkins埠
systemctl reload firewalld // 重啟防火牆,重啟上一步才會生效
複製程式碼

當我滿懷希望, 信誓旦旦去訪問時,又心痛了~~~

接著檢視 aliyun 防火牆,aliyun server 自帶防火牆,預設只開發 80 埠,我們用了其他埠需要去 aliyun 防火牆開放埠才行

再試試,淚目~~ 總算可以訪問了

配置 Jenkins

Jenkins 給我們提供了網頁配置介面 愛了 愛了

進入登入頁面後,Jenkins 提示我們需要輸入超級管理員密碼進行解鎖。根據提示,我們可以在/var/lib/jenkins/secrets/initialAdminPassword檔案裡找到密碼。

tail /var/lib/jenkins/secrets/initialAdminPassword
複製程式碼

找到密碼後,複製密碼,貼上到 Jenkins 解鎖頁面,點選Continue繼續初始化配置。短暫的等待後,進入外掛安裝頁面。

這裡我們點選的 Install suggested plugins,安裝預設外掛,當然你也可以點選另一個按鈕安裝指定的外掛。點選後,頁面進入了外掛下載安裝頁面。

全部安裝完成後,頁面自動進入管理員賬戶註冊頁面。

輸完資訊點選 save and finish,進入 Jenkins 歡迎頁(此圖省了),然後點選 start using Jenkins,進入 Jenkins 主頁面。

至此,Jenkins 基本配置完成,大家不要慌~不要慌~,還有事情要做,接下來我們還要對 Jenkins 全域性做些其他配置。

在 Github 外掛的配置中,點選“高階”按鈕,啟用 Hook URL,並將 Hook URL 複製出來,並儲存剛才的設定,這樣他讓它可以接受 Github 的請求。

配置 Github 倉庫

因為 Github 經常有程式碼處理動作,需要配置 Github 專案倉庫在處理這些動作的同時會傳送訊號至 Jenkins,才能觸發 Jenkins 自動構建。

在"Webhooks"選項卡中,點選"Add webhook",將在 Jenkins 生成的 Hook URL 填入至 Payload URL 中,另外,選擇自主事件,events 裡選擇了 pushes,當 Github 收到了客戶端有 Push 動作時,會觸發一個 Hook

image-20200326180636869
image-20200326180636869

配置完成後,展示如下

自動打包部署實戰

前期準備已經差不多了,實戰開始,先送上自動打包 CI 架構圖

其實就是文章開頭架構圖中的**右邊 CI 部分的詳細版?~

建立

建立 Jenkins 專案,選擇 freestyle project

配置

配置專案,點選 Configure 進入配置頁面,進行相關配置

配置 Github 專案的專案 URL: https://github.com/xxxxx/test

配置 Git 倉庫地址:https://github.com/xxxxx/test.git

配置構建觸發事件

配置構建指令碼

儲存之後,serve r 裡就有了我們的倉庫程式碼了,可以去/var/lib/jenkins/workspace 目錄下里檢視,或者網頁的 workspace 檢視,網頁檢視至少需要構建一次才有。


執行構建

構建完成後,可以去 workspace 裡檢視 dist 裡是否有打包檔案

修改 nginx 配置檔案,手動打包的時候我們已經配過 nginx 了,指向目錄是我們手動 clone 專案的 dist 目錄。

接下來我們把 root 指向地址換成 jenkins 建立的專案 dist 目錄 /var/lib/jenkins/workspace/hello/dist,重新啟動 nginx,訪問的就是我們 jenkins 服務建立的專案了

好啦,該寫的都寫了,該做的也都做了,下面見證奇蹟的時刻到了,修改你的程式碼 =》git push =》 稍等一下,重新整理頁面看是否成功更新。哇偶~

總結

本文已收錄 Github https://github.com/ponkans/F2E(怪怪整理了大前端知識技能樹在 GitHub),歡迎 Star,持續更新?

✨ 怪怪我人懶話不多,本期程式碼和圖有點多,小夥伴們可以直接獲取原始碼,對照著原始碼,自己理一遍思路,實現一遍。

相信正在看文章的多數小夥伴,每天都會用腳手架去做專案,去打包,釋出。怪怪覺得了解並自己實現整個前端工程化的流程,是十分必要並且極具意義的一件事~~

近期原創傳送門,biubiubiu~~~


喜歡的小夥伴麻煩加個關注,點個贊哦,感恩??

聯絡我 / 公眾號

本文腳手架 /CI 構建原始碼,公眾號回覆【腳手架】即可獲取,如果有興趣參與腳手架後期共建,請微信私聊怪怪~


微信搜尋【接水怪】或掃描下面二維碼回覆”加群“,我會拉你進技術交流群。講真的,在這個群,哪怕您不說話,光看聊天記錄也是一種成長。(阿里技術專家、敖丙作者、Java3y、蘑菇街資深前端、螞蟻金服安全專家、各路大牛都在)。

接水怪也會定期原創,定期跟小夥伴進行經驗交流或幫忙看簡歷。加關注,不迷路,有機會一起跑個步? ↓↓↓

相關文章