背景
由於在開發前端專案中,後臺管理端和使用者端存在多個模組和頁面邏輯可以複用,管理模組和使用者端渲染模組使用同一套狀態管理機制,只是在管理端和使用者端的入口和路由模組不同,為了能夠在開發時同時修改管理端和使用者端共用模組,不用多專案工程修改和釋出,我們基於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來區分不同的使用者訪問。