Vue项目使用Nginx部署并发布到子目录

默认Vue项目是以根目录来发布的,但是我们要有时候希望以子目录来做发布,那么就需要做一些修改,Vue项目本身的配置,包括Nginx也需要做一些配置修改。

对Vue项目源码的修改

以下路径以vue-cli常见项目的文件结构来说明。

  • 修改路由:router/index.js,添加base部分的代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function getAbsolutePath () {
    let path = location.pathname
    return path.substring(0, path.lastIndexOf('/') + 1)
    }

    export default new Router({
    mode: 'hash',
    base: getAbsolutePath(),
    routes: [...]
    })
  • 修改配置:config/index.js 文件,对于打包路径的定义,只处理build,将assetsPublicPath: '/'修改为assetsPublicPath: './'

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    module.exports = {
    build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: './',
    ...
    }
    }
  • 修改build/utils.js对静态文件的处理,添加publicPath: '../../'

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
    return ExtractTextPlugin.extract({
    use: loaders,
    fallback: 'vue-style-loader',
    publicPath: '../../'
    })
    } else {
    return ['vue-style-loader'].concat(loaders)
    }
    }

对Nginx配置的修改

当前项目结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
game
├── bxfr
│   ├── index.html
│   └── static
│   ├── css
│   ├── images
│   ├── img
│   ├── js
│   └── mock
└── fwjt
├── index.html
└── static
├── css
├── images
├── img
├── js
└── mock

而我们要实现的目的是:使用my.server.name/bxfr/my.server.name/fwjt/分别访问不同的项目。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
server {

server_name my.server.name;

access_log /var/log/nginx/game.access.log;
error_log /var/log/nginx/game.error.log;

# 这里root只能放在game这一层,因为下一层的子目录是不固定的
root /home/ubuntu/workspace/official-website/game/;

# json文件使用mock来返回静态资源,这个block对于实现本文的目的并非必要
location ~ \.json$ {
rewrite ^/([^/]+).*/api/(.*) /$1/static/mock/$2 break;
}

location @vue {
# 匹配不含/的首段,目的是拿出bxfr和fwjt
rewrite ^/([^/]+).* /$1/index.html last;
}

# 使用try files来fallback到vue
location / {
index index.html;
try_files $uri $uri/ @vue;
}

listen 80;
...

}