如何配置nginx支持多级目录vue项目history模式?

摘要:本文详细说明了nginx部署vue项目配置细节,介绍了如何在nginx有上下文时,配置二级目录,甚至是多级路径后,vue项目的history模式也能正常使用。方便在项目开发后配合部署人员build要发布的项目。因为使用的项目使用的是cli
介绍 本文是篇详细的介绍vue项目在history模式下发布时build,项目如何配置,nginx如何配置,才能正常的使用历史模式。或者在二级目录下,多级路径下也能正常使用历史模式。 本文的例子中假设,nginx全部都是配置在 flytree.can 域名下。 且路由中配置有以下路径: const routes = [ { path: '/', redirect: "/index"}, { path: '/login', component: Login }, { path: '/welcome', component: Welcome } ] vite下配置 以下为vue3, vue-router4.x 基于vite构建下的配置 二级路径 url 对应打开路由 http://www.flytree.can/web/login /login http://www.flytree.can/web/welcom /welcom vue-router 中要配置base createWebHistory() 中有可选参数 base 支持配置:// router.js const router = createRouter({ history: createWebHistory("/web/"), routes: constantRoutes, }); vite 构建增配置 base// vite.config.js export default defineConfig(({ mode, command }) => { return { base:'/web/', } ... }) nginx 配置location /web { alias /home/foo/workspace/xpos/web/; try_files $uri $uri/ /web/index.html; } webpack下配置 以下为vue2, vue-router3.x 基于 webpack 下的配置,更新于2021-07-17 02:01 一级路径的配置 应用放在服务器根目录下。路由也就是域名后的第一级路径。如: url 对应打开路由 http://www.flytree.can/login /login http://www.flytree.can/welcom /welcom 路由配置 const router = new VueRouter({ mode: 'history', routes }) nginx配置 location / { try_files $uri $uri/ /index.html; } 二级路径的配置 应用不是放在服务器根目录下,而是location有上下文的。如配置了web上下文,则: url 对应打开路由 http://www.flytree.can/web/login /login http://www.flytree.can/web/welcom /welcom 路由配置 如果在ngnix代理的时候不是配置到根路径/的话,则要配置base,它指定的是应用的基路径。例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 "/app/"。 router/index.js配置: const vueRouter = new Router({ mode: "history", base: "/web", routes: routes }) 配置了base后,应用就会在base之后打开了,如,后面配置了个/login路由,则是在/web/login中打开此路由。 项目config配置 注:由于项目里使用的是老版本的vue-cli,新版本@vue/cli配置会在旁说明。 老版本的配置文件在config/index.js中,如果是cli 3.x后续版本,需在项目 (和 package.json 同级的) 根目录中创建vue.config.js文件进行配置。 const path = require('path'); module.exports = { module.exports = { build: { // 指定生成的 index.html 的输出路径 (相对于 配置文件所在路径)。也可以是一个绝对路径。 // 新版本使用:indexPath index: path.resolve(__dirname, '../web/index.html'), // 指定生成的 资源 的输出的目录 (相对于 配置文件所在路径)。此,build后到dist目录下。注意目标目录在构建之前会被清除。 // 新版本使用:outputDir assetsRoot: path.resolve(__dirname, '../web'), // 指定除了index.html外的静态资源的目录 // 新版本使用:assetsDir assetsSubDirectory: 'public', // 部署应用包时的基本 URL。指定打包后,index.html里面引用资源的的相对地址。 // 这个值也可以被设置为空字符串 ('') 或是相对路径 ('./'),这样所有的资源都会被链接为相对路径 // 如我在index.html中应用了张在pulblic下的图片flytree.jpg // 则引用是 src='./public/flytree.jpg' // 新版本:publicPath assetsPublicPath: '/web/', } } } 配置以后bulid后,部署的文件会在项目下web文件下。 外部文件应用配置 如配置了assetsPublicPath路径,如这里配置的是./相对路径,则在发布的时候要将引用的静态资源设置在,其路径里,如: <img src="./public/img/flytree.png"> <script> axios.get('./public/JSON/data.json') </script> 为了方便开发和发布时使用静态资源,可以: // main.js中配置 window.base_file_url = process.env.NODE_ENV === 'production' ? '.' : '' // 使用 axios.get(base_file_url + '/public/JSON/data.json') nginx的配置 location /web { alias F:/Program_D/work/demo/web/; try_files $uri $uri/ /web/index.html; } 如此,项目就部署在http://www.flytree.cam/web下了。 多级路径的配置 可能会有人说,谁TM竟然要这么麻烦,搞这么多级路径干啥。但事实就是还真能遇到就要配这么多级的路径。要不然就不会有本文了。😂 router配置 注:这里base可以配置多级路径,比如: const vueRouter = new Router({ mode: "history", base: "/app/web", routes }) 那么,当前应用将部署在/app/web下: url 对应打开路由 http://www.flytree.can/app/web/login /login http://www.flytree.can/app/web/welcom /welcom 若要配置多级路径,其它的配置也要作修改, 项目config配置 配置后,build后会生成一个有层级的文件夹。 const path = require('path'); module.exports = { module.exports = { build: { // 指定生成的 index.html 的输出路径 (相对于 配置文件所在路径)。也可以是一个绝对路径。 // 新版本使用:indexPath index: path.resolve(__dirname, '../app/web/index.html'), // 指定生成的 资源 的输出的目录 (相对于 配置文件所在路径)。此,build后到dist目录下。注意目标目录在构建之前会被清除。 // 新版本使用:outputDir assetsRoot: path.resolve(__dirname, '../app/web'), // 指定除了index.html外的静态资源的目录 // 新版本使用:assetsDir assetsSubDirectory: 'public', // 部署应用包时的基本 URL。指定打包后,index.html里面引用资源的的相对地址。 // 这个值也可以被设置为空字符串 ('') 或是相对路径 ('./'),这样所有的资源都会被链接为相对路径 // 如我在index.html中应用了张在pulblic下的图片flytree.jpg // 则引用是 src='./public/flytree.jpg' // 新版本:publicPath assetsPublicPath: '/app/web/', } } } nginx配置 location /app/web/ { # alias F:/Program_D/work/demo/app/web/; root F:/Program_D/work/demo/; try_files $uri $uri/ /app/web/index.html; } 原理分析 就拿这个多级的举例吧。 url 对应打开路由 http://www.flytree.can/app/web/login /login http://www.flytree.can/app/web/welcom /welcom 当访问 http://www.flytree.can/app/web/login 时, nginx 配置了上下文 /app/web/。所以$uri的值是/login。 try_files 会将此路径,响应为 root + /app/web/index.html。 浏览器打开了index.html也就是history模式的vue项目,此时vue-router匹配路由/login,将此路由内容插入到index.html中。 补充说明 nginx配置的一些说明 关于 try_files try_files $uri $uri/ /index.html; 这个命令可以将其后的参数,响应到最后一个参数的路径中去。在这里通俗来说,就是匹配到啥$uri我都给你响应index.html。前提是有index.html,否则会响应到别的location配置中去(有的话),或404。 root 和 alias 的区别 首先这两玩意都是指定服务器的响应文件路径的。 使用root配置时,则配置到 项目路径的上层路径。此时,nginx会去读取的文件路径是,root + location的上下文(其后面跟着的)拼成的路径。 alias 就配置到项目的完整的路径,配置到index这一级。nginx会去读取的文件路径时就会按照alias指定的路径读取。 参考内容 关于 try_files $uri $uri/ /index.html的说明: Niginx中Vue Router 历史(history)模式的配置 vue-router history模式在nginx二级目录下的配置