Vue router is not working when new route added - laravel

My app is working fine in localhost with this configuration, I use XAMMP in localhost. but when I deployed my app in a VPS with Linux (ubunto) OS, I got this problem. In the first days they worked fine too, but recently when I added the last route (categories) and did 'npm run production' my routes suddenly stopped working.
When I click on a router-link the URL doesn't even change.
I changed my webserver from nginx to apache, but it doesn't make any difference.
my routes are like this:
const Index = resolve => {
require.ensure(['./frontend-components/main-content/index'], () => {
resolve(require('./frontend-components/main-content/index'));
});
};
const news = resolve => {
require.ensure(['./frontend-components/single/news'], () => {
resolve(require('./frontend-components/single/news'));
});
};
const lists = resolve => {
require.ensure(['./frontend-components/single/lists'], () => {
resolve(require('./frontend-components/single/lists'));
});
};
const categories = resolve => {
require.ensure(['./frontend-components/single/categories'], () => {
resolve(require('./frontend-components/single/categories'));
});
};
export const routes = [
{path: '/', component: Index},
{path: '/articles/:article_id/:slug',component: news,name: 'articles'},
{path: '/lists/:article_id/:slug',component: lists,name: 'lists'},
{path: '/categories/:cat_id/:slug', component: categories},
]
and my webpack configuration is :
const { mix } = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js')
.js('resources/assets/js/fr-app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css')
.sass('resources/assets/sass/fr-app.scss', 'public/css')
.sass('resources/assets/sass/admin.scss', 'public/css')
.options({processCssUrls: false})
.webpackConfig({ output: { filename: '[name].js', chunkFilename:
'js/[name].app.js', publicPath: '/' } });
I have this error when I click on a router-link:
Uncaught (in promise) TypeError: Cannot read property 'call' of undefined
and it refers to this line to source code:
// Execute the module function
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

require.ensure is the legacy Webpack syntax, which is superceded by import. And as #Phil pointed out, resolve => {/*...*/} itself does not create a Promise, which is needed for lazy loading routes. You probably meant something like this:
const foo = new Promise(resolve => {
require.ensure( './path/to/foo', () => resolve(require('./path/to/foo')) );
});
const routes = [
{
path: '/foo',
component: foo
}
];
However, the vue-router docs recommends the import syntax for lazy loading routes:
const routes = [
{
path: '/foo',
component: () => import('./path/to/foo')
}
];
demo

Related

Keep getting 'TypeError: Cannot call a class as a function' using Ziggy for Vue in Laravel

I have searched and searched and can't seem to find a solution to my problem.
I have taken the following steps:
\\Webpack.mix.js
const mix = require('laravel-mix');
const path = require('path');
mix.webpackConfig({
resolve: {
alias: {
ziggy: path.resolve('vendor/tightenco/ziggy/src/js/route.js'),
},
},
});
mix.js('resources/js/app.js', 'public/js').vue()
.postCss('resources/css/app.css', 'public/css', [
//
]);
mix.browserSync('127.0.0.1:8008');
And then in my app.js I have
\\app.js
require('./bootstrap');
import Vue from 'vue'
// Ziggy start here
import route from 'ziggy';
import { Ziggy } from './ziggy';
Vue.mixin({
methods: {
route: (name, params, absolute, config = Ziggy) => route(name, params, absolute, config),
},
});
// ziggy end here
import VendorLoginForm from './vue/components/vendors/auth/VendorLoginForm'
import VendorRegisterForm from './vue/components/vendors/auth/VendorRegisterForm'
import EditVendorProfile from './vue/components/vendors/profile/EditVendorProfile'
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate/dist/vee-validate.full.esm';
extend("password", {
message: "{_field_} must be at least 10 characters long, contain one uppercase, one lowercase, and one number.",
validate: value => {
const strong_password = new RegExp(
"^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{10,})"
); // regex to check our strong password
return strong_password.test(value); //Test the regex. Test function returns a true or false value.
}
});
import './scripts/validators'
Vue.component('ValidationProvider', ValidationProvider);
Vue.component('ValidationObserver', ValidationObserver);
Vue.component('extend', extend);
const app = new Vue({
el: '#vue-app',
components: { VendorLoginForm, VendorRegisterForm, EditVendorProfile }
});
I have ran the php artisan command to generate the ziggy.js and it seems to be working fine when I Ctrl+click it.
However when I got into my component to try to use route as below
mounted() {
console.log(this.route('home.page'))
},
I get the error:
app.js:51783 TypeError: Cannot call a class as a function
at _classCallCheck (app.js:3612)
at Route (app.js:3630)
at VueComponent.route (app.js:3345)
at VueComponent.mounted (app.cbfbd1ac1b8410f1ce58.hot-update.js:172)
at invokeWithErrorHandling (app.js:51749)
at callHook (app.js:54109)
at Object.insert (app.js:53032)
at invokeInsertHook (app.js:56234)
at VueComponent.patch [as __patch__] (app.js:56453)
at VueComponent.Vue._update (app.js:53838)
this was a nightmare when I was working with Ziggy at first time but I resolved my issue by
after creating ziggy.js in resources folder php artisan ziggy:generate
edit my webpack.mix.js file
const mix = require('laravel-mix');
const path = require('path');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/js/app.js', 'public/js')
.vue()
.sass('resources/sass/app.scss', 'public/css');
mix.webpackConfig({
resolve: {
alias: {
ziggy: path.resolve('vendor/tightenco/ziggy/dist'),//Note we point to dist folder
},
},
});
then in App.js
import route from 'ziggy';
import {
Ziggy
} from './ziggy';
Vue.mixin({
methods: {
route: (name, params, absolute) => route(name, params, absolute, Ziggy)
}
});
then you can use route in your components
console.log(route("home"));

Unexpected token error when using Vue-pdf

I'm creating an SPA with Laravel and Vue and am trying to use vue-pdf. I've successfully integrated several npm packages, but this one is giving me the error:
Uncaught SyntaxError: Unexpected token '<'
When I click on the file (worker.js) in my console, it looks like it's trying to perform a get request for a regular page on my site instead of grabbing the javascript so my hunch is that webpack isn't correctly transpiling vue-pdf. My current webpack config is:
const path = require('path')
const fs = require('fs-extra')
const mix = require('laravel-mix')
require('laravel-mix-versionhash')
// const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
mix
.js('resources/js/app.js', 'public/dist/js')
.sass('resources/sass/app.scss', 'public/dist/css')
.sass('resources/sass/flowy.scss', 'public/dist/css')
mix.babel([
'resources/js/helpers/Date.js',
'resources/js/helpers/LoginRedirect.js'
], 'public/assets/js/combined.js')
.disableNotifications()
if (mix.inProduction()) {
mix
// .extract()
// .version()
.versionHash()
} else {
mix.sourceMaps()
}
mix.webpackConfig({
plugins: [
// new BundleAnalyzerPlugin()
],
resolve: {
extensions: ['.js', '.json', '.vue'],
alias: {
'~': path.join(__dirname, './resources/js')
}
},
output: {
chunkFilename: 'dist/js/[chunkhash].js',
path: mix.config.hmr ? '/' : path.resolve(__dirname, './public/build')
}
})
mix.then(() => {
if (!mix.config.hmr) {
process.nextTick(() => publishAseets())
}
})
function publishAseets () {
const publicDir = path.resolve(__dirname, './public')
if (mix.inProduction()) {
fs.removeSync(path.join(publicDir, 'dist'))
}
fs.copySync(path.join(publicDir, 'build', 'dist'), path.join(publicDir, 'dist'))
fs.removeSync(path.join(publicDir, 'build'))
}
Any help would be appreciated.

how to run vue app in the same domain with laravel sanctum for SPA

I need help in running my Vue spa in the same domain as my laravel app , when running "npm run serve" in terminal I think it's working but when I go to the browser it's refusing connection. I haven't done the backend which I will use sanctum for handling API. Has anybody here have the same project working on like me? love to make conversations to solve this.
Thanks in advance
here is the vue.config.js file
const path = require('path')
const webpack = require('webpack')
const createThemeColorReplacerPlugin = require('./config/plugin.config')
function resolve (dir) {
return path.join(__dirname, dir)
}
/**
* check production or preview(pro.loacg.com only)
* #returns {boolean}
*/
function isProd () {
return process.env.NODE_ENV === 'production'
}
const assetsCDN = {
css: [],
// https://unpkg.com/browse/vue#2.6.10/
js: [
'//cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.min.js',
'//cdn.jsdelivr.net/npm/vue-router#3.1.3/dist/vue-router.min.js',
'//cdn.jsdelivr.net/npm/vuex#3.1.1/dist/vuex.min.js',
'//cdn.jsdelivr.net/npm/axios#0.19.0/dist/axios.min.js'
]
}
// webpack build externals
const prodExternals = {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios'
}
// vue.config.js
const vueConfig = {
configureWebpack: {
// webpack plugins
plugins: [
// Ignore all locale files of moment.js
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
],
// if prod is on, add externals
externals: isProd() ? prodExternals : {}
},
chainWebpack: (config) => {
config.resolve.alias
.set('#$', resolve('src'))
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule
.oneOf('inline')
.resourceQuery(/inline/)
.use('vue-svg-icon-loader')
.loader('vue-svg-icon-loader')
.end()
.end()
.oneOf('external')
.use('file-loader')
.loader('file-loader')
.options({
name: 'assets/[name].[hash:8].[ext]'
})
// if prod is on
// assets require on cdn
if (isProd()) {
config.plugin('html').tap(args => {
args[0].cdn = assetsCDN
return args
})
}
},
css: {
loaderOptions: {
less: {
modifyVars: {
// less vars,customize ant design theme
'primary-color': '#00B4E4',
// 'link-color': '#F5222D',
'border-radius-base': '4px'
},
javascriptEnabled: true
}
}
},
}
if (process.env.VUE_APP_PREVIEW === 'true') {
vueConfig.configureWebpack.plugins.push(createThemeColorReplacerPlugin())
}
module.exports = vueConfig
module.exports = {
devServer: {
host: 'app.paymate-ui.test'
}
}
If I understand you correctly, you want to use Laravel and Vue.js together in the same application folder?
Should be pretty easy then.
First off, build your application with Vue scaffolding for the frontend.
Then, make a route that redirects everything to a single controller method that returns a spa view. (Or use a closure)
In this view, include your app.js as an asset and include the main Vue component (something like <app></app>).
Then build your Vue app. All requests will now be forwarded to the spa view, which includes your app.js, which should bootstrap Vue.

Laravel Vue VueRouter history mode

I'm building an e-commerce project with laravel, vue and vue router
I want to use vue router with history mode but it cause me trouble.
Here is my code
new Vue({
el: '#app',
router: new VueRouter({
mode: 'history',
routes
})
});
Here is my route in web.php which have locale middleware
Route::group(['prefix' => '{locale}', 'where' => ['locale' => '[a-zA-Z]{2}'], 'middleware' => 'setlocale'], function () {
Route::view('/{path?}', ('layouts.app'))->where('path', '.*');
});
Here is my route with vue router
export const routes = [
{
path: '/',
component: require('./components/Page/HomePage').default,
},
{
path: '/product',
component: require('./components/Page/Product/ProductPage').default,
},
];
I need my url to be
http://localhost/en
instead of (with the hashtag)
http://localhost/en#/
After using history mode, i successfully remove the hashtag. But, the router link of other will remove my locale in my url
http://localhost/product
I don't know what to do now with it.
Please help~ Thanks.
Update 19 Mar 2020
You need to set the base value to tell Vue Router what the base URL of your application is. In your case you can set it dynamically using the locale value.
For example, in your Blade template you could have the following script to set the locale value on the JavaScript window object:
<script>
window._locale = "{{ app()->getLocale() }}";
</script>
And then you can set the base value to the locale when creating your router:
router: new VueRouter({
mode: 'history',
base: `/${window._locale}/`,
routes
})
Very simple way is too Accept the locale in Vue router too. So your route would be like this:
export const routes = [
{
path: '/:locale',
children: [
{
path: '',
component: require('./components/Page/HomePage').default,
},
{
path: 'product',
component: require('./components/Page/Product/ProductPage').default,
},
]
}
];
just be sure for children route dont put '/' in begining because its remove locale

Nuxt.js app deployed to Heroku only has TailwindCSS's styles for < SM breakpoint

I deployed my 1st Nuxt.js app to Heroku...Everything went smooth but when I opened the app I realised that every .vue file/component has TailwindCSS styles up untill SM breakpoint. Mobile view is fine, but anything bigger than SM breakpoint is not apllied. I also used Purgecss to remove unused styles but not sure if that can cause the problems... Any ideas on how to fix this?
I fixed my problem just by finding this https://github.com/nuxt/nuxt.js/issues/2262
I created modules folder and added import-tailwind-config.js with the code:
module.exports = function () {
const tailwindConfig = require('#nuxtjs/tailwindcss')
this.options.env.tailwind = tailwindConfig
}
And inside nuxt.config.js, outside of module.exports I added
const PurgecssPlugin = require('purgecss-webpack-plugin')
const glob = require('glob-all')
const path = require('path')
class TailwindExtractor {
static extract (content) {
return content.match(/[A-z0-9-:/]+/g) || []
}
}
As well as this code inside of module.exports
build: {
extend (config, ctx) {
config.plugins.push(
new PurgecssPlugin({
whitelist: ['html', 'body'],
paths: glob.sync([
path.join(__dirname, 'components/**/*.vue'),
path.join(__dirname, 'layouts/**/*.vue'),
path.join(__dirname, 'pages/**/*.vue'),
path.join(__dirname, 'plugins/**/*.vue')
]),
extractors: [{
extractor: TailwindExtractor,
extensions: ['html', 'js', 'vue']
}]
})
)
}
}
modules: [
'~modules/import-tailwind-config'
]

Resources