20200318
基于@vue-cli3的多页面应用改造及nignx配置
参考资料:https://www.jianshu.com/p/a7a742724e14
需求
一个项目型的工程。由于初期欠考虑的设计。做成了单页应用。现在项目越做越大.项目中多了许多原设计无法很好兼容的内容。这个工程原来的定位是预约审批系统
的PC端,但是现在,这个工程包含着
1、预约审批功能PC端
2、审批功能钉钉H5页面
3、移动端问卷调查
4、访客账号的子账号管理功能
所以,打算将工程改造为多页应用。
修改步骤
修改目录结构
我们首先把多个模块独立出来。
原单页应用目录
实际上用@vue/cli3生成的目录都长得一个样。
项目
|
|__public
|
|__src
| |
| |__api
| |
| |__assets
| |
| |__components
| |
| |__dictionary
| |
| |__router
| |
| |__store
| |
| |__style
| |
| |__utils
| |
| |__views
| |
| |__App.vue
| |
| |__config.js
|
|__vue.config.js
多页应用目录
项目
|
|__public
|
|__src
| |
| |__appointModule // 原来的预约功能模块全部放到了appointModule目录内
| | |
| | |
| | |
| | |__api
| | |
| | |__assets
| | |
| | |__components
| | |
| | |__dictionary
| | |
| | |__router
| | |
| | |__store
| | |
| | |__style
| | |
| | |__utils
| | |
| | |__views
| | |
| | |__App.vue
| | |
| | |__config.js
| | |
| | |__main.js // 预约审批模块入口文件
| |
| |__systemModule // 新增的子账号管理功能当成系统模块,全部放到systemModule内
| | |
| | |__api
| | |
| | |__compoinents
| | |
| | |__dictionary
| | |
| | |__router
| | |
| | |__store
| | |
| | |__views
| | |
| | |__App.vue
| | |
| | |__config.js
| | |
| | |__systemEntry.js // 系统模块的入口文件
|
|__vue.config.js
我将原先的预约相关功能,放入了appointModule目录下,并新建了systemModule目录,用来放系统管理相关的功能。
systemModule中的入口文件,路由,组件等都是独立的。方便将来系统模块扩展。
修改组件引用路径
因为项目结构变了,所以引用组件的路径也要跟着修改。这个没啥好说的,不然组件引用不到肯定是运行不起来的。
修改路由
原单页应用
// router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
// 静态路由
const routes = [
{
name: '',
path:'',
components: ''
},
....
];
// 动态路由
const asyncRoutes = [
{
name: '',
path: '',
compoents: ''
},
...
]
const router = new VueRouter({
mode: 'history',
routes
});
// 路由守卫
router.beforeEach((from, to, next) => {
...
next();
});
router.onError((error) => {
...
});
export router
多页应用路由
// 预约模块 appointModule/router.js
// 静态路由
...
// 动态路由
...
// 路由守卫
...
const router = new VueRouter({
mode: 'history',
routers,
base: '/appointModule/' // 注意这一行
});
export router;
// 系统模块 systemModule/router.js
// 静态路由
...
// 动态路由
...
// 路由守卫
...
const router = new VueRouter({
mode: 'history',
routers,
base: '/systemModule/' // 注意这一行
});
给路由添加 base
基础路径.用于区分两个模块的两个路由
路由修改后,我们访问项目所要输入的url也将发生变化。访问方式从原来的 contextPath/路由path
改为了contextPath/module/路由path
所以,项目中原来路由跳转的写法也要跟着改变。
// 原写法:
this.$router.push('/login');
// 改造后写法
this.$router.push({name: 'Login'});
// 或者改成这种也行
this.$router.push('/appointModule/login');
改造路由跳转的时候,我发现,
this.$router.push({name: 'xxx'}));
这种用name的写法比直接用’/appointModule/'这种用路径的写法好用,至少我以后修改路由的base路径时候,name的写法不用我再做一次修改了。
进入预约审批模块的页面时,我们需要输入http://localhost:8080/appointModule/路由path
进入系统模块的页面时,我们需要输入http://localhost:8080/systemModule/路由path
修改vue.config.js
原单页应用
// vue.config.js
module.exports = {
publicPath: '/',
outputDir: `${outputDir}`,
lintOnSave: false,
produc tionSourceMap: false ,
//下面是代理表,作用是用来,建一个虚拟api服务器用来代理本机的请求,只能用于开发模式
//一般解决跨域请求api
devServer: {
port: 8090 ,
proxy: {
'/api': {
target: 'http://ip:port',
pathRewrite: {
'^/api': ' /api'
},
//指示是否跨域
changeorigin: true,
//如果是https接口, 需要配置这个参数
secure: false
}
}
hot: true ,
inline: true,
disableHostCheck: true
},
configurewebpack: {
resolve: {
alias : {
@': resolve('src' )
}
},
output: {
filename:'js/ [name].${stamp}.js',
chunkFilename: 'js/ [name]${stamp}.js'
},
plugins: [
// new BundleAnalyzerPlugin()
]
}
};
修改为多页应用
// vue.config.js
module.exports = {
pages: {
//预约模块
appointModule: {
entry:'src/ appointModule/main.js',
template: 'public/ index . html',
// filename: 'appointModule.html', //为了在nginx更容易配置,采用下面这种filename配置
// filename: appointModule/index.html'
filename: 'index.html' // 打包后的html文件会放到 rootPath/index.html中
// chunks: [ ' chunk -verdors',' chunk - common', ' index']
},
//系统管理模块
systemModule: {
entry: 'src/systemModule/ systemEntry.js',
template: 'public/index. html',
// filename:systemModule.html', //为了在nginx更容易配置,采用下面这种filename配置
filename: 'systemModule/index.html' // 打包后的html文件会放到 rootPath/systemModule/index.html中
}
}
};
其它都不变,新增pages
配置,如上所示。
到现在,我们的项目已经可以通过npm run server
启用了。
进入预约审批模块的页面时,我们需要输入http://localhost:8080/appointModule/路由path
进入系统模块的页面时,我们需要输入http://localhost:8080/systemModule/路由path
我们还需要关心打包后的目录变化,因为这涉及到nginx的配置。我在配置nginx的过程中走了不少弯路。
这样打包后的工程目录就会变成这样子。
// 打包后的工程
项目
|
|__fonts
|
|__img
|
|__js
| |
| |__appointModule.hash.js
| |
| |__chunk-verdors.hash.js
| |
| |__systemModule.hash.js
|
|__systemModule // 系统模块打包后的index.html放到这里
| |
| |__index.html
|
|__index.html // 预约模块打包后的index.htlm仍然放在根目录下,因为这样可以让nginx做最小的改动。
修改nginx配置
原nginx配置
单页应用
server {
listen 8900;
server_ name 项目名;
location / {
root 项目目录;
index index . html index . htm;
try_ files Suri $uri/ /index . html;
}
location /api {
proxy_ pass http://ip:port/api/;
}
}
修改后的nginx配置
多页应用
server {
listen 8094;
server_name 项目名 ;
root 项目目录;
location / {
# rewrite / /appointModu1e/ permanent;
index index. html;
try_ files $uri $uri/ / index .html;
}
location /systemModule {
index index. html;
try_ files $uri $uri/ / systemModule/ index .html;
}
location /api {
proxy_ _pass http://ip:port/api/;
}
}
nginx我们并不需要多大的改动,原来的预约模块的nginx配置我们不需要修改。我们只需要将新增的系统模块的路径加入nginx配置中即可。
Q&A
Q1、为什么当初要把不合适的功能写到同一个项目里?
主要原因有两个:
1、新功能不够复杂
以钉钉H5页面为例,实际上这个功能只有一个页面。为了写一个页面开一个新工程,意味着为了一个页面就得新部署一个工程。
2、网络环境
子账号管理功能本应该放到管理端的那个工程更合适 ,但是管理端的工程在外网无法访问。而子账号需要让甲方爸爸访问到
3、时间来不及
时间非常紧急(9点上班,23点下班,都来不及的需求和变化)。开一个新工程,意味着,登录,权限控制等功能需要重复开发。而我们没有时间这么做,当时也想不到更好的解决方法
Q2、为什么选择改造为多页面应用?
1、难度不大
一是代码改造难度不大,二是部署时不需要重新部署新的工程
2、时间问题
这个项目从开始到现在,时间一直是大问题。再加上,之前的代码耦合严重,要分离成一个新项目也是需要时间的。分离出来后还要重新测试。时间完全不够用,