Vue + Vue-cli 建置與部署
使用 Vue 撰寫網站是趟舒服的經驗,從基本範例到使用鷹架(scaffold)都可以快速上手。不過我發現,比較少的文章是關於 Vue 及 vue-cli 的部署。
Vue 怎麼可以部署?
Vue 的確沒有部署的問題,因為 Vue 是純前端架構。但因為我們在開發時,經常一同使用 vue-router 來打造一個 SPA 網站,很自然地會把許多以前交由後端處理的功搬到前端做,而這篇文章要談的,就是這些前端的功,要如何在整理好後,交由伺服器去 host。
為什麼要使用 Vue-cli?
要快速建立一個容易開發的 vue 專案,使用 vue-cli 是一個實用的捷徑,他提供套件打包、隨改隨更新、簡單架伺服器、自動語法抓錯等多種功能,讓快速開發不是問題,因此本文將會以此做範例使用。
建立專案
第一步,我們需要使用 vue-cli 建立一個 vue 專案, vue-cli 安裝方式如下:
$ npm install -g vue-cli
安裝完後,建立一個 vue 專案:
$ vue init <template-name> <project-name>
以大家最常用的 webpack 為例:
$ vue init webpack my-project
接著會被問到一些問題,例如是否要安裝 test 套件、語法檢查如何設定、套件管理使用 yarn 或 npm 等等問題,設定好後我們就完成了最基本的 vue 專案。
開發使用
建立完專案,我們先進入該專案
cd my-project
我們先讓套件管理器跑一遍,安裝所有專案所需的憑依套件,在此以 yarn 為例:
yarn install
Yarn 會讀取專案根目錄的 package.json
並安裝所有必須套件,產生一個 yarn.lock
檔以便之後的安裝更快速。
安裝完套件後,是時候在本地架起這個專案了。我們可以使用 package.json
檔中定義的指令:
yarn start
終端機顯示 Your application is running here: http://localhost:8080
,打開瀏覽器此連結,你應該會看到:
接著,若更改任何專案的 code,網頁會即時更新而不用 reload,這個技術叫做 Hot reload。
產生 Production 資源
部署 production 跟開發有些不一樣,從 package.json 可以看到,剛才的開發用指令其實是使用 webpack-dev-server
來 host,如果硬要在正式環境上使用的話,我們試著這樣編輯(但這樣不好):
NODE_ENV=production yarn start
雖然勉強可以跑,但只要連結遠端主機的 ssh 一斷掉,網站就停擺了,而大家所熟知的 pm2 也不傾向支援這種「開發環境服務」的套件。
Build
vue 說到底其實就是個前端框架,只是 Vue-cli 產生的模型用 Node 去讓他起起來,讓我們在 local 可以看到。因此在部署的時候,我們需要先把他 build 成一個 index.html
和一堆靜態資源,再用 HTTP 伺服器(e.g. Apache, Node, Nginx)去 host 這些資源。
我們需要這些專案變成靜態資源,使用:
yarn build
部署 production
既然靜態資源產生了,接下來就簡單,只剩把這包 host 起來。例如你可以用最基本的 SimpleHTTPServer
在本地試試:
python -m SimpleHTTPServer
連進去的首頁顯示一切正常,當你連到其他連結時,會有「非首頁 url 就找不到網頁」的問題,比如說 router 裡面設定的 /foo/bar
。
解決這個問題的核心在於:
要將所有進來的 request 導到同一個 html
在此我以個人較常用的 Node 和 Nginx 當作範例。
使用 Node
撰寫一個簡單的 js 腳本,給 Node + express 來跑:
// index.js
const fs = require('fs')
const path = require('path')
const express = require('express')
const app = express()app.use(express.static(path.resolve(__dirname, './dist')))app.get('*', function(req, res) {
const html = fs.readFileSync(path.resolve(__dirname, './dist/index.html'), 'utf-8')
res.send(html)
})
在這個範例中,執行伺服器功能的 index.js
和 dist 同層。主要功能是讓所有進來的 request 都導去剛剛 build 出來的 index.html
,vue-router 會管理、自動判斷進來的 url 該顯示什麼 view,包括 404。
這時候就可以使用 pm2
在背景跑伺服器了:
pm2 start index.js
使用 Nginx
更改 Nginx 設定檔,搞定!
server {
... # 設定 root 資料夾文件
root /var/www/dist; # 所有網站請求導向同一個頁面
location / {
...
try_files $uri $uri/ /index.html;
} ...
}
快問快答
Q: 不能夠直接用 pm2 開啟 webpack-dev-server 命令?
A: pm2 是用在 production 環境,如果想要本地開發時不中斷,建議開一個 tab 放置不理就好;若是想在 production 跑 webpack-dev-server
,則不建議如此做。
Q: 為什麼會出現 webpack-dev-server: command not found?
A: 如同報錯所言因為沒有安裝 webpack-dev-server
。如果在 local 發現這個問題的話,嘗試再安裝一次套件:
// yarn
yarn install// npm
npm install --only=dev