Is there a way to remove some routes with their linked components from production build of Vue app?
In my app I have manager interface that only I use so there is no need to have it's logic in the production build. I want to avoid having any of manager's code actually used in the production build as I can use the manager page only during development on localhost.
Here is simple example what I have now. The managerCheck tests if user is manager to allow user to enter or to redirect him back to the homepage. This is probably enough as it is also combined with check in MongoDB but I still would love to not includes manager's components logic inside production build as ManagerView includes pretty powerful functions and it is better to be safe than sorry.
// router.js
// ... some imports
const userCheck = (to, from, next) => store.getters['user/user'] ? next() : next({path: '/login'})
const managerCheck = (to, from, next) => store.getters['user/manager'] ? next() : next({path: '/'})
export default new Router({
mode: 'hash',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'App Name',
component: MainView,
},
{
path: '/user',
name: 'User',
component: UserView,
beforeEnter: userCheck
},
{
path: '/manager',
name: 'Manager',
component: ManagerView,
beforeEnter: managerCheck
}
})
In production, unnecessary routes can be filtered out.
Routes can be defined with productionAvailable flag.
routes: [
{
path: '/',
name: 'App Name',
component: MainView,
productionAvailable: true,
},
{
path: '/user',
name: 'User',
component: UserView,
beforeEnter: userCheck,
productionAvailable: true,
},
{
path: '/manager',
name: 'Manager',
component: ManagerView,
beforeEnter: managerCheck,
productionAvailable: false,
}
}]
Then filter it when exporting if the node env is set to production.
export default new Router({
mode: 'hash',
base: process.env.BASE_URL,
routes: process.env.NODE_ENV === 'production' ? routes.filter((route) => route.productionAvailable) : routes,
})
I would do something like this:
// router.js
// ... some imports
const userCheck = (to, from, next) => store.getters['user/user'] ? next() : next({path: '/login'})
const managerCheck = (to, from, next) => store.getters['user/manager'] ? next() : next({path: '/'})
const clientRoutes = [
{
path: '/',
name: 'App Name',
component: MainView,
},
{
path: '/user',
name: 'User',
component: UserView,
beforeEnter: userCheck
}
]
const managerRoutes = []
// you may have to look into process.env to set this condition correctly
if (process.env.NODE_ENV !== 'production') {
managerRoutes.push({
path: '/manager',
name: 'Manager',
component: ManagerView,
beforeEnter: managerCheck
})
}
export default new Router({
mode: 'hash',
base: process.env.BASE_URL,
routes: [...clientRoutes, ...managerRoutes]
})
process.env: https://cli.vuejs.org/guide/mode-and-env.html#modes
Related
I have a stupid simple question that I basically failed to find a good answer for.
I have a nuxt2 project that has a #nuxtjs/router module on it. I have added the module on the buildModules on nuxt.config.js and created router.js on the src folder.
this is my nuxt.config.js file :
ssr: true, // tauri
target: 'static', // tauri
server : {
host:"127.0.0.1",
port: 8001
},
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
...
},
env:{
MEDIA_API:process.env.VUE_APP_MEDIA_API,
API_URL: process.env.API_URL
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
...
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
'#nuxtjs/router'
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
...
'#nuxtjs/router',
...
],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
extractCSS: true,
plugins: [ // to import jQuery :"
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',
}),
],
standalone: true
},
router: {
middleware: ['auth']
},
auth: {
...
}
and here is my router.js file :
import { parseHTML } from 'jquery';
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
// this is just a function to help me not writing the full path of each page
const page = (path) => () => import(`~/pages/${path}`).then(m => m.default || m)
const routes = [
{path: '/', name: 'home', component: page('index.vue')},
{path: '/login', name: 'login', component: page('login.vue')},
{path: '/players', name: 'allPlayers', component: page('players/index.vue')},
{path: '/players/:id', name: 'singlePlayer', component: page('players/view.vue')},
{path: '/plans', name: 'allPlans', component: page('plans/index.vue')},
{path: '/plans/new', name: 'newPlan', component: page('plans/new.vue')},
{path: '/activities', name : 'allActs', component: page ('activities/index.vue')},
{path: '/activities/new', name: 'newAct', component: page('activities/new.vue')},
{path: '/activityPlayer/:id', name: 'viewActivityPlayer', component: page('activities/viewActivityPlayer')},
{path: '/auth/login', name: 'auth.login', component: page('auth/login')},
{path: '/superAdmin/', name: 'superAdmin', component: page('superAdmin/index.vue')},
{path: '/superAdmin/viewAll', name: 'viewAdmins', component: page('superAdmin/viewAdmins.vue')},
];
export function createRouter() {
return new Router({
routes,
mode: 'history'
})
}
I want to generate full static build to deploy my nuxt app on a tauri build. I was able to successfully deploy a nuxt app that does NOT has that router.js file. The build generate just generate all routes by default in the dist folder.
How can I generate the routes ?
I've tried with the /login path and it's working great as shown in this commit, there was a typo in the path tho (I did tried only for that one since it was an obvious one for me).
I also removed the useless package-lock.json since you use yarn in your project (could be vice-versa of course) and since you should not use both at the same time. Added a few explicit keys in the nuxt.config.js file too.
Commented #nuxtjs/auth-next, ran yarn generate && yarn start and I have successfully access to the given path.
The generated route files are maybe not that friendly (because of their hash) but they are still available in the dist directory. There is a way to make them prettier, you could search for that on Stackoverflow/Google.
Update: it works with the auth middleware too actually.
I have a Vue locally, the main /index.html is the webroot but when I deploy, I want the subfolder /stats to be the root (and all my routes to still work).
Can I do this without manually changing my router/index.js?
vue.config.js
// this doesn't seem to work
module.exports = {
publicPath: process.env.NODE_ENV === "production" ? "/stats/" : "/",
};
router.js
const routes = [
{
path: "/",
name: "HomeView",
component: HomeView,
},
{
path: "/grid",
name: "GridView",
component: GridView,
},
...
]
The only recommendation I'd make sure you set router base property to match your publicPath
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL, // 👈 set the "base" property here
routes
})
i am developing a multipage web application using Laravel and VueJs.
resources are compiled using Laravel-mix (webpack wrapper)
i am lazy loading components in vuejs route
{
path: "/auth",
component: () => import(/* webpackChunkName: "site" */'./components/Site'),
children: [
{
name: "login",
path: "login",
component: () => import(/* webpackChunkName: "login" */'./components/auth/Login'),
meta: {
title: "Login to your account",
breadcrumbs: [{ name: "Login", active: true }]
}
},
{
name: "register",
path: "register",
component: () => import(/* webpackChunkName: "register" */'./components/auth/Register'),
meta: {
title: "Register",
breadcrumbs: [{ name: "Register", active: true }]
}
}
]
},
my webpack.mix.js is as follows,
mix.webpackConfig({
output: {
publicPath: "public/",
chunkFilename: mix.inProduction() ? "js/chunks/[name].[chunkhash].js" : "js/chunks/[name].js"
},
});
i am getting the chunks in my projectfolder/public/js/chunks/ which is right.
but my problem is, after loading home/root page,
i go to http://projecturl/auth/login that works fine. because the login.js chunk is loading from http://projecturl/public/js/chunks/login.js
but then when i go to http://projecturl/auth/register it doesnt work !
because the register.js chunk is loading from http://projecturl/auth/public/js/chunks/login.js
it seems the chunk loading url changes every time i go to a any subpage. and that subpage url becomes the chunk public path.
Please help.
I have the following routing-modules:
app-routing.modules.ts
...
const routes: Routes = [
{
path: '',
loadChildren: () => import('./startpage/startpage.module').then(m => m.StartpageModule)
},
{
path: 'user',
loadChildren: () => import('./user/user.module').then(m => m.UserModule),
canActivate: [AuthGuard]
},
{
path: 'shop',
loadChildren: () => import('./shop/shop.module').then(m => m.ShopModule),
canActivate: [AuthGuard]
},
{
path: '**',
redirectTo: '',
pathMatch: 'full'
}
];
...
and shop-routing.modules.ts
const routes: Routes = [
{
path: '',
redirectTo: 'user',
pathMatch: 'full',
},
{
path: ':id',
component: ShopPageComponent
}
];
The problem is, since I'm starting the child route of 'shop' with ':id', it acts as a 'catch-everything' route. If i call 'localhost:4200/user' now, it loads the shopcomponent. Why is that like that? I thought 'shop' was the main route and the ':id' child is only called, when the link has 'shop/' as prefix. If I put 'shop/:id' before, it works fine, but then the route is also callable via 'localhost:4200/shop/shop/something' which is ugly and also my authGuard isn't working anymore.
App-routing.module.ts
const routes: Routes = [
{
path: '',
loadChildren: () => import('./startpage/startpage.module').then(m => m.StartpageModule),
pathMatch: 'prefix'
},
{
path: 'user',
loadChildren: () => import('./user/user.module').then(m => m.UserModule),
canActivate: [AuthGuard],
pathMatch: 'prefix'
},
{
path: 'shop',
loadChildren: () => import('./shop/shop.module').then(m => m.ShopModule),
canActivate: [AuthGuard],
pathMatch: 'prefix'
},
{
path: '**',
redirectTo: '',
pathMatch: 'full'
}
pathMatch: 'prefix' will check for prefix path only and checks for child path for the rest of the path.
I am trying to create a route structure that would allow me to do the following.
Home.vue has one router view
/home/clients should load the Clients component
home/campaigns should load the Campaigns component
home/clients/:id should redirect to /home/clients/:id/campaigns and load the same Campaigns component.
I do not want to introduce another router view inside Clients component to handle the campaigns part. I was trying to get it done with following routes but really can't get it to work.
These are children routes to /home.
UPDATE: I got it working literally writing down every path that I may encounter. Is there a way I can elegantly solve this?
{
path: '/home',
name: 'Home',
component: Home,
beforeEnter(to, from, next) {
if (!store.getters.isLoggedIn) {
next({
path: '/login',
query: {
redirect: to.fullPath
}
});
} else {
next();
}
},
children: [
{
path: 'clients',
component: Clients
},
{
path: 'clients/:clientId',
redirect: 'clients/:clientId/campaigns'
},
{
path: 'clients/:clientId/campaigns',
component: Campaigns
},
{
path: 'clients/:clientId/campaigns/:campaignId',
redirect: 'clients/:clientId/campaigns/:campaignId/ads'
},
{
path: 'clients/:clientId/campaigns/:campaignId/ads',
component: Ads
},
{
path: 'clients/:clientId/campaigns/:campaignId/ads/:adId',
redirect: 'clients/:clientId/campaigns/:campaignId/ads/:adId/postings'
},
{
path: 'clients/:clientId/campaigns/:campaignId/ads/:adId/postings',
component: Postings
},
{
path: 'campaigns',
component: Campaigns
},
{
path: 'campaigns/:campaignId',
redirect: 'campaigns/:campaignId/ads'
},
{
path: 'campaigns/:campaignId/ads',
component: Ads
},
{
path: 'campaigns/:campaignId/ads/:adId',
redirect: 'campaigns/:campaignId/ads/:adId/postings'
},
{
path: 'campaigns/:campaignId/ads/:adId/postings',
component: Postings
},
{
path: 'ads',
component: Ads
},
{
path: 'ads/:adId',
redirect: 'ads/:adId/postings'
},
{
path: 'ads/:adId/postings',
component: Postings
},
{
path: 'postings',
component: Postings
}
]
}