Vue項目打包部署總結

本文發佈於個人我的網站: http://wintc.top/article/29,轉載請註明出處。

使用Vue作先後端分離項目時,一般前端是單獨部署,用戶訪問的也是前端項目地址,所以前端開發人員頗有必要熟悉一下項目部署的流程與各種問題的解決辦法了。Vue項目打包部署自己不復雜,不過一些前端同窗可能對服務器接觸很少,部署過程當中仍是會遇到這樣那樣的問題。本文介紹一下使用nginx服務器代理前端項目的方法以及項目部署的相關問題,內容概覽:css

Vue項目打包發佈問題彙總

1、準備工做——服務器和nginx使用

1. 準備一臺服務器

個人是ubuntu系統,linux系統的操做都差很少。沒有服務器怎麼破?html

若是你只是想體驗一下,能夠嘗試各大廠的雲服務器免費試用套餐,好比華爲雲免費試用,本文相關操做便是在華爲雲上完成的。不過若是想時常練練手,我以爲能夠購買一臺雲服務器,好比上面的華爲雲或者阿里雲都還挺可靠。個人我的網站就是部署在阿里雲,你能夠點擊個人推廣連接進行購買,近期有活動首次購買不到100塊/年。前端

2. nginx安裝和啓動

輕裝簡行,這部分不做過多贅述,畢竟網上相關教程一大堆。vue

# 安裝,安裝完成後使用nginx -v檢查,若是輸出nginx的版本信息代表安裝成功
sudo apt-get install nginx
# 啓動
sudo service nginx start

啓動後,正常狀況下,直接訪問http://服務器ip 或 http://域名 (本文測試用的服務器沒有配置域名,因此用ip,就本文而言,域名和ip沒有太大區別)應該就能看到nginx服務器的默認頁面了——若是訪問不到,有多是你的雲服務器默認的http服務端口(80端口)沒有對外開放,在服務器安全組配置一下便可。linux

Vue項目打包發佈問題彙總

3. 瞭解nginx: 修改nginx配置,讓nginx服務器代理咱們建立的文件

查看nginx的配置,linux系統下的配置文件一般會存放在/etc目錄下,nginx的配置文件就在/etc/nginx文件夾,打開文件/etc/nginx/sites-available/default(nginx能夠有多個配置文件,一般咱們配置nginx也是修改這個文件):webpack

Vue項目打包發佈問題彙總

能夠看到默認狀況下,nginx代理的根目錄是/var/www/html,輸入 http://服務器ip會訪問這個文件...,會根據index的配置值來找默認訪問的文件,好比index.html、index.htm之類。nginx

咱們能夠更改root的值來修改nginx服務代理的文件夾:git

  1. 建立文件夾/www,並建立index.html,寫入"Hello world"字符串github

    mkdir /www
    echo 'Hello world' > /www/index.html​
  2. 修改root值爲 /www
    Vue項目打包發佈問題彙總
  3. sudo nginx -t 檢查nginx配置是否正確
    Vue項目打包發佈問題彙總
  4. 加載nginx配置:sudo nginx -s reload

再次訪問頁面,發現頁面內容已經變成了咱們建立的index.html:web

Vue項目打包發佈問題彙總

2、Vue項目打包同步文件到遠程服務器

1. 打包

默認狀況下,使用vue-cli建立的項目,package.json裏的script應該已經配置了build指令,直接執行yarn build 或者 npm run build便可。

2. 同步到遠程服務器

咱們使用nginx部署Vue項目,實質上就是將Vue項目打包後的內容同步到nginx指向的文件夾。以前的步驟已經介紹了怎樣配置nginx指向咱們建立的文件夾,剩下的問題就是怎麼把打包好的文件同步到服務器上指定的文件夾裏,好比同步到以前步驟中建立的/www。
同步文件能夠在git-bash或者powershell使用scp指令,若是是linux環境開發,還可使用rsync指令:

scp -r dist/* root@117.78.4.26:/www
或
rsync -avr --delete-after dist/* root@117.78.4.26:/www

注意這裏以及後續步驟是root使用用戶遠程同步,應該根據你的具體狀況替換root和ip(ip換爲你本身的服務器IP)。

爲了方便,能夠在package.json腳本中加一個push命令,以使用yarn爲例(若是你使用npm,則push命令中yarn改爲npm  run便可):

"scripts": {
    "build": "vue-cli-service build",
    "push": "yarn build && scp -r dist/* root@117.78.4.26:/www"
  },

這樣就能夠直接執行yarn push 或者npm run push直接發佈了。不過還有一個小問題,就是命令執行的時候要求輸入遠程服務器的root密碼(這裏使用root來鏈接遠程的,你能夠用別的用戶,畢竟root用戶權限過高了)。

爲了不每次執行都要輸入root密碼,咱們能夠將本機的ssh同步到遠程服務器的authorized_keys文件中。

3. 同步ssh key

  1. 生成ssh key:使用git bash或者powershell執行ssh-keygen能夠生成ssh key。會詢問生成的key存放地址,直接回車就行,若是已經存在,則會詢問是否覆蓋:
    Vue項目打包發佈問題彙總-同步ssh key
  2. 同步ssh key到遠程服務器,使用ssh-copy-id指令同步

    ssh-copy-id -i ~/.ssh/id_rsa.pub root@117.78.4.26

    Vue項目打包發佈問題彙總
    輸入密碼後,以後再次同步就不須要輸入密碼了。其實ssh_key是同步到了服務器(此處是root用戶家目錄)~/.ssh/authorized_keys文件裏:

    Vue項目打包發佈問題彙總
    固然你也能夠手動複製本地~/.ssh/id_rsa.pub(注意是pub結尾的公鑰)文件內容追加到服務器~/.ssh/authorized_keys的後面(從命名能夠看出該文件能夠存儲多個ssh key)

注意: 這裏全程使用的是root用戶,因此沒有文件操做權限問題。若是你的文件夾建立用戶不是遠程登陸用戶,或許會存在同步文件失敗的問題,此時須要遠程服務器修改文件夾的讀寫權限(命令 chmod)。

建立了一個測試項目(點擊本連接能夠在gihub查看)試一下,打包、文件上傳一句指令搞定啦:

Vue項目打包發佈問題彙總

訪問一下,果真看到了咱們熟悉的界面:

Vue項目打包發佈問題彙總

至此,常規狀況下發布Vue項目就介紹完了,接下來介紹非域名根路徑下發布以及history路由模式發佈方法。

3、非域名根路徑發佈

有時候同一臺服務器同一端口下可能會根據目錄劃分出多個不一樣的項目,好比咱們但願項目部署到http://a.com/test下,這樣訪問http://a.com/test訪問到的是項...,而非test前綴的地址會訪問到其它項目。此時須要修改nginx配置以及Vue打包配置。

1. nginx配置

只須要添加一條location規則,分配訪問路徑和指定訪問文件夾。咱們能夠把/test指向以前建立的/www文件夾,這裏由於文件夾名稱和訪問路徑不一致,須要用到alias這個配置:

Vue項目打包發佈問題彙總

若是文件夾名稱與訪問路徑一致都爲test,那這裏能夠用root來配置:

Vue項目打包發佈問題彙總

這裏要將/test配置放到/以前,意味着在路由進入的時候,會優先匹配/test。若是根路徑/下的項目有子路由/test,那http://xxxx/test只會訪問到/ww...,而不會訪問該子路由。

2. 項目配置

爲了解決打包後資源路徑不對的問題,須要在vue.config.js中配置publicPath,這裏有兩種配置方式,分別將publicPath配置爲./和/test:

Vue項目打包發佈問題彙總

更新nginx配置,發佈後便可正常訪問啦。這裏的兩種配置方式是有區別的,接下來會看一下它們的區別。
若是不進行項目配置,直接發佈訪問會出現JS、CSS等資源找不到致使頁面空白的問題:

Vue項目打包發佈問題彙總

該問題緣由是資源引用路徑不對,頁面審查元素能夠看到,頁面引用的js都是從根路徑下引用的:

Vue項目打包發佈問題彙總

查看打包後的文件結構,能夠看到js/css/img/static等資源文件是與index.html處於同級別的:

Vue項目打包發佈問題彙總

對於兩種配置方式,看看都是怎麼生效的:

  1. publicPath配置爲./, 打包後資源引用路徑爲相對路徑:
    Vue項目打包發佈問題彙總
  2. publicPath配置爲/test,打包後資源相對路徑爲從域名根目錄開始的絕對路徑:
    Vue項目打包發佈問題彙總

兩種配置均可以正確地找到JS、CSS等資源。不過還有個問題,那就是static中的靜態資源依舊會找不到。

3. 絕對路徑引用的靜態資源找不到的問題

由於在打包過程當中,public下的靜態資源都不會被webpack處理,咱們須要經過絕對路徑來引用它們。當項目部署到非域名根路徑上時,這點很是頭疼,你須要在每一個引用的URL前面加上process.env.BASE_URL(該值即對應上文配置的publicPath),以使得資源能被正常訪問到。咱們能夠在main.js把這個變量值綁定到Vue.prototype,這樣每一個Vue組件均可以使用它:

Vue.prototype.$pb = process.env.BASE_URL

在模板中使用:

<img :src="`${pb}static/logo.png`">

然而,更加頭疼而且沒有良好解決方案的問題是在組件style部分使用public文件夾下的靜態資源。

  • 若是須要使用圖片等做爲背景圖片等,儘可能使用內聯方式使用吧,像在模板中使用同樣。
  • 若是須要引入樣式文件,則在index.html中使用插值方式引入吧。

關於靜態資源的問題,vue-cli的推薦是儘可能將資源做爲你的模塊依賴圖的一部分導入(即放到assets中,使用相對路徑引用),避免該問題的同時也帶來其它好處:

4、history模式部署

默認狀況下,Vue項目使用的是hash路由模式,就是URL中會包含一個#號的這種形式。#號以及以後的內容是路由地址的hash部分。正常狀況下,當瀏覽器地址欄地址改變,瀏覽器會從新加載頁面,而若是是hash部分修改的話,則不會,這就是前端路由的原理,容許根據不一樣的路由頁面局部更新而不刷新整個頁面。H5新增了history的pushState接口,也容許前端操做改變路由地址可是不觸發頁面刷新,history模式即利用這一接口來實現。所以使用history模式能夠去掉路由中的#號。

1. 項目配置

在vue-router路由選項中配置mode選項和base選項,mode配置爲'history';若是部署到非域名根目錄,還須要配置base選項爲前文配置的publicPath值(注意:此狀況下,publicPath必須使用絕對路徑/test的配置形式,而不能用相對路徑./)
Vue項目打包發佈問題彙總

2. nginx配置

對於history模式,假設項目部署到域名下的/test目錄,訪問http://xxx/test/about的時候,服務器會去找/test指向的目錄下的about子目錄或文件,很顯然由於是單頁面應用,並不會存在a這個目錄或者文件,就會致使404錯誤:

Vue項目部署後頁面找不到

咱們要配置nginx讓這種狀況下,服務器可以返回單頁應用的index.html,而後剩下的路由解析的事情就交給前端來完成便可。

history模式nginx配置

這句配置的意思就是,拿到一個地址,先根據地址嘗試找對應文件,找不到再試探地址對應的文件夾,再找不到就返回/test/index.html。再次打開剛纔的about地址,刷新頁面也不會404啦:

Vue項目打包發佈問題彙總

3. history模式部署到非域名根路徑下

非域名根目錄下部署,首先確定要配置publicPath。須要注意的點前面其實已經提過了,就是這種狀況下不能使用相對路徑./或者空串配置publicPath。爲何呢?
緣由是它會致使router-link等的表現錯亂,使用測試項目分別使用兩種配置打包發佈,審查元素就能看出區別。在頁面上有兩個router-link,Home和About:

Vue項目打包發佈問題彙總

兩種配置打包後的結果以下。

  1. publicPath配置爲./或者空串:
  2. publicPath配置爲/test:
    Vue項目打包發佈問題彙總

publicPath配置爲相對路徑的router-link打包後地址變成了相對根域名下地址,很明顯是錯誤的,因此非域名根路徑部署應該將publicPath配置爲完整的前綴路徑。

5、結語

關於Vue項目發佈的相關問題就先總結這麼多,幾乎在每一步都踩過坑纔有所體會。 寫博客很累,不過收穫也不少,仍是要堅持;有時候別人轉載本身的原創文章也不標明出處,居然將寫文章日期改得比原創還早,有點心累。本文中使用到的圖片都加了個本身的水印,是前端實現的,原理也很簡單,以後寫一篇簡短的文章分享一下。(完)

相關文章
相關標籤/搜索