npm run build 之后將dist放到Nginx目錄就行?
再多幾個需求就不簡單了:
- 支持VueRouter History模式
- 多頁面入口
- 部署在子目錄, 如
www.example.com/app/
提示: 此文檔基于的環(huán)境是: vue-cli 3.0 與 vue 2.6.
一步一步來
將多個頁面部署在域名根目錄
假如 我們項目有兩個入口: pc 與 mobile, 我們需要修改 這幾個地方:
- vue.config.js: 配置多頁面
- router.js: 配置base
- nginx.conf: 配置支持RouterHistory模式
vue.config.js
按照vue-cli的官方文檔配置多入口并不難:
module.exports = {
pages: {
'index': {
entry: 'src/pages/pc/index.js',
template: 'src/pages/pc/index.html',
filename: 'index.html',
},
'mobile': {
entry: 'src/pages/mobile/index.js',
template: 'src/pages/mobile/mobile.html',
filename: 'mobile/index.html',
}
},
頁面入口名字 即mobile只會影響在開發(fā)環(huán)境的入口: 現(xiàn)在需要使用 'localhost:3000/index' 和或者 'localhost:3000' 來進(jìn)入index頁面, 使用 'localhost:3000/mobile' 來進(jìn)入 mobile 頁面.
filename會影響在生產(chǎn)環(huán)境中打包出來的入口文件(.html文件)路徑. 值得注意的是 mobile.filename 字段: 我設(shè)置的是 mobile/index.html, 而不是 mobile.html, 這是有原因的, 在下面配置nginx時會說到.
router.js
配置好vue.config.js之后打開 'localhost:3000/mobile' 卻發(fā)現(xiàn)空白, 進(jìn)入不了mobile的路由.
查文檔 VueRouterApi-base, 發(fā)現(xiàn)需要配置 base.
base: 應(yīng)用的基路徑。例如,如果整個單頁應(yīng)用服務(wù)在 /app/ 下,然后 base 就應(yīng)該設(shè)為 "/app/"。
官方文檔只是舉了一個例子說部署在/app/下可以設(shè)置base, 但多頁面也需要如此配置.
如下:
mobile.router.js
export default new Router({
mode: 'history',
base: '/mobile/',
routes: [
{
path: '/',
name: 'index',
component: Home
},
]
})
現(xiàn)在訪問 localhost:3000/mobile 就能正常進(jìn)入.
至此, 開發(fā)環(huán)境沒問題了. 接下來是部署.
nginx.conf
我使用nginx作為web容器部署前端項目, 其他服務(wù)器大同小異.
我們需要將npm run build打包出來的dist文件夾下的所有文件放置到nginx所在服務(wù)器的/usr/share/nginx/html目錄下. (目錄可以自定義)
nginx.conf
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
# vue router mode 為 history 時美化url
try_files $uri $uri/ /index.html;
}
}
其中為了支持VueRouter的History模式, 我們需要按照官方文檔配置: HTML5 History 模式.
又得益于我們將mobile入口的輸出文件地址修改為了 mobile/index.html, 正好訪問 /mobile/ 時讓Nginx打開mobile/index.html文件, 所以它足夠簡單.
如果你只有需求將項目部署在根目錄, 那么現(xiàn)在便完成了.
將多個頁面部署在子目錄
假如需要將項目放入 www.example.com/app/ 下, 訪問www.example.com/app/進(jìn)入index入口, 訪問www.example.com/app/mobile進(jìn)入mobile入口. 則在上述 ‘部署到根目錄’ 基礎(chǔ)之上還需要修改以下幾項文件:
- vue.config.js: 配置多頁面入口, 打包出來的文件路徑.
- router.js: 配置base
vue.config.js
module.exports = {
publicPath: '/app/', // modified
outputDir: 'dist/app', // modified
pages: {
'app/index': { // modified
entry: 'src/pages/pc/index.js',
template: 'src/pages/pc/index.html',
filename: 'index.html',
},
'app/mobile': { // modified
entry: 'src/pages/mobile/index.js',
template: 'src/pages/mobile/mobile.html',
filename: 'mobile/index.html',
}
}
pages中需要修改的是 兩個入口名字, 修改為: app/index與 app/mobile.
在上面說了, 頁面入口名字 即app/mobile只會影響到開發(fā)環(huán)境訪問入口: 現(xiàn)在在開發(fā)環(huán)境訪問localhost/app/mobile才能進(jìn)入mobile頁面.
如果我們需要在生產(chǎn)模式也使用domain/app/mobile路徑訪問項目, 還需要修改: publicPath和outputDir
- publicPath: 指定在html模板中注入的打包出來的靜態(tài)文件路徑, 亦可實現(xiàn)將打包出的靜態(tài)文件上傳到CDN.
- outputDir: 打包出的文件地址, 默認(rèn)是
dist, 我們需要修改為dist/app, 表示所有文件都存放在dist/app文件夾下.
更多請查閱文檔: publicpath, outputdir.
router.js
修改base, 如下:
mobile.router.js
export default new Router({
mode: 'history',
base: '/app/mobile/', // modified
routes: [
{
path: '/',
name: 'index',
component: Home
},
]
})
QA
Q: 為什么不用 Nginx 的alias指令來實現(xiàn)子目錄, 而是通過修改outputDir參數(shù)?
A: 修改outputDir是為了不修改nginx配置. 不修改outputDir也是可行的, 那么需要修改nginx配置如下:
location /app {
alias /usr/share/nginx/html;
...
}
少改一個文件是一個, 所以我推薦修改 outputDir .