背景
由於在開發前端項目中,後臺管理端和用戶端存在多個模塊和頁面邏輯可以複用,管理模塊和用戶端渲染模塊使用同一套狀態管理機制,只是在管理端和用戶端的入口和路由模塊不同,爲了能夠在開發時同時修改管理端和用戶端共用模塊,不用多項目工程修改和發佈,我們基於vite多頁面的基礎上實現了多端同構開發和部署。
多端同構實現流程
具體配置流程
1,多頁面入口配置
首先我們可以在工程目錄下創建多頁面文件,不同頁面配置的入口entry不同來建立多入口,
以下我們以管理端和用戶端兩個端爲例來說明實現流程
比如:
管理端入口配置
admin/index.html
<body>
<div id="app"></div>
<script type="module" src="/src/admin.js"></script>
</body>
admin.js
import { createApp } from 'vue'
import App from './admin.vue'
import router from './adminRouter';
import store from './store'
const app = createApp(App)
app.use(store).use(router)
app.mount('#app')
用戶端:public/index.html
<body>
<div id="app"></div>
<script type="module" src="/src/public.js"></script>
</body>
public.js
import { createApp } from 'vue'
import App from './public.vue'
import router from './publicRouter';
const app = createApp(App)
app.use(store).use(router)
app.mount('#app')
2,用戶訪問權限判斷
不同的用戶有不同的角色身份,我們需要根據用戶登錄後的角色來判斷是否可以訪問該入口,如果該用戶不具備該入口的訪問權限,我們需要在入口處攔截進行提示或者讓頁面重定向到擁有權限的入口處, 這塊可以通過前端請求處理也可以,通過服務端配置角色和白名單類型處理。
下邊以前端調用後端接口實現
以public.js爲例
import { createApp } from 'vue'
import App from './public.vue'
import router from './publicRouter';
fetch(/xxx/).then((res)=> {
if(res) {
const app = createApp(App)
app.use(store).use(router)
app.mount('#app')
} else {
/** 跳轉到其他有權限頁面 或者進行無權限提示**/
}
})
3,路由模式匹配
每個端應用建議配置自己的路由,用於和其他端模塊資源劃分
常用的路由分爲hash模式和history模式,不同模式下的配置路由略有差異,一般history模式需要通過服務端支持實現,否則會出現刷新頁面出現404的情況。
hash模式實現
管理端:adminRouter
import { createRouter, createWebHashHistory } from 'vue-router';
const router = createRouter({
history: createWebHashHistory('/pageadmin/'),
routes:[{
path: '/page1',
name: 'page1',
component:() => import('@/page1.vue')
}]
});
export default router;
用戶端:publicRouter
import { createRouter, createWebHashHistory } from 'vue-router';
const router = createRouter({
history: createWebHashHistory('/pagepublic/'),
routes:[{
path: '/page1',
name: 'page1',
component:() => import('@/page1.vue')
}],
});
export default router;
history模式實現
history模式的實現管理端和用戶端同hash模式,將createWebHashHistory改爲createWebHistory即可:
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory('/xxx/'),
routes:[{
path: '/page1',
name: 'page1',
component:() => import('@/page1.vue')
}],
});
export default router;
history本地開發刷新404解決
history模式,由於hash模式時url帶的#號後面是哈希值不會作爲url的一部分發送給服務器,而history模式下當刷新頁面之後瀏覽器會直接去請求服務器,而服務器沒有這個路由,於是就出現404, 爲了解決該問題,我們可以採用如下方案
通過配置代理,將訪問的路由指向我們本地開發服務器目錄文件
proxy: {
'/pageadmin/': {
target: 'http://easy-page.local.jdl.com:8089',
changeOrigin: true,
rewrite: (path) =>'/admin/index.html'
},
'/pagepublic/': {
target: 'http://easy-page.local.jdl.com:8089/',
changeOrigin: true,
rewrite: (path) => '/public/index.html'
}
}
4,vite.config.js入口配置
build: {
rollupOptions: {
input: {
admin: resolve(__dirname, 'admin/index.html'),
public: resolve(__dirname, 'public/index.html'),
},
},
}
打包後的目錄結構
打包後,我們可以看到生成了兩個入口文件 admin/index.html 和 public/index.html
assets是兩個入口共用的資源內容包括 js,css,png等等
生產配置
生產環境我們也需要根據url路由區分訪問入口, 我們可以根據資源的訪問路徑,將其指定到不同的應用入口來實現不同端訪問的資源內容不同,同時可以在服務端配置檢測客戶端的userAgent來現在各個端訪問設備,可以給各個端配置白名單來限制用戶訪問
location /pageadmin {
add_header Cache-Control no-store;
try_files $uri $uri/ /admin/index.html;
}
location /pagepublic {
add_header Cache-Control no-store;
try_files $uri $uri/ /public/index.html;
}
總結
以上是我們基於vite多頁面同構方案來實現多個端一套代碼開發構建部署,實現工程模塊中相同模塊和資源的共享複用,減少多個應用的創建和多域名申請,以及多個應用之間相互關聯交互,通過path來區分不同的用戶訪問。