Why does "vite build --watch" see changes on .vue files? - laravel

i have created a new Laravel 9, Inertia, Vue3 project.
From the "old" laravel i know the "npm run hot"-script ("hot": "mix watch --hot").
Due to Laravel 9 runs with Vite, you should use the "vite build --watch" script to continuously compiling your code.
This works pretty fine except the .vue files. I have created a "Demo.vue"-Site and when i making changes there, nothing "recompiles" or is changing in the browser. Only when I change other files, the browser view changes to new vue-file.
I already have tried to change the "watch" settings in the vite.config.js, without further success.
Now I have rollback these changes and my vite.config.js looks like this
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
import FullReload from 'vite-plugin-full-reload';
export default defineConfig({
plugins: [
FullReload(),
vue(),
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
],
});
Do i have to configure anything else in the vite config or somewhere else?

Related

Vite: Can't resolve Vue imports

I'm building a Laravel app with Vite bundling. Inside the Laravel app, I'm using a package with Vue components in it.
My vite.config.js:
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: [
'packages/canvas/resources/sass/app.scss',
'packages/canvas/resources/js/app.js'
],
refresh: true,
}),
vue()
],
});
And here's router.js - the JS file with the Vue imports:
import AllStats from '../views/AllStats';
import EditPost from '../views/EditPost';
import EditSettings from '../views/EditSettings';
Directory structure:
(Laravel app root)
packages
|----canvas
|----resources
|----js
|----router
|----router.js // Vue imports are here
|----views
|----AllStats.vue
|----EditPost.vue
|----...
When I run npm run build, I get this error:
Could not resolve '../views/AllStats' from packages/canvas/resources/js/router/routes.js
error during build:
Error: Could not resolve '../views/AllStats' from packages/canvas/resources/js/router/routes.js
at error (file:///Users/rago/workspace/krolestwo/mycanvas/node_modules/rollup/dist/es/shared/rollup.js:1858:30)
at ModuleLoader.handleResolveId (file:///Users/rago/workspace/krolestwo/mycanvas/node_modules/rollup/dist/es/shared/rollup.js:22156:24)
at file:///Users/rago/workspace/krolestwo/mycanvas/node_modules/rollup/dist/es/shared/rollup.js:22119:26
If I comment the first import out, the next one is called out, and so on. Also, the relative path to the views directory and the file names are correct.
I work on a Mac and I'm running the Laravel app in Docker.
Anyone has an idea what might be causing this?
Error says:
Could not resolve '../views/AllStats' from packages/canvas/resources/js/router/routes.js
So the problem is probably inside packages/canvas/resources/js/router/routes.js file.
Also, you may set up an alias with the absolute path which you can then use for quick reference, more here:
https://laravel.com/docs/9.x/vite#aliases

How to fix the error "You may need an appropriate loader to handle this file type"

I have a fresh Laravel installation. On compiling files using npm run dev VUE I get a file error
"You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file"
Laravel Verion: "^8.12"
Package.json
"devDependencies": {
"axios": "^0.21",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"vue": "^2.5.17",
"vue-loader": "^15.9.6",
"vue-template-compiler": "^2.6.10"
}
blade file
<div id="app">
<hello></hello>
</div>
<script src="{{mix('js/app.js')}}"></script>
app.js
require('./bootstrap');
import Vue from 'vue'
Vue.component('hello', require('./hello.vue').default);
const app = new Vue({
el: '#app'
});
Hello.vue
<template>
<div>
Hello World!
</div>
</template>
<script>
export default {
}
</script>
npm run dev
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <template>
| <div>
| Hello World!
as your using laravel-mix 6 it have different config for webpack.mix.js
webpack.mix.js
use .vue()
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel applications. By default, we are compiling the CSS
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/js/app.js', 'public/js').vue()
.postCss('resources/css/app.css', 'public/css', [
//
]);
ref link https://laravel-mix.com/docs/6.0/upgrade
If anyone still encounters this issue, here how I figure out the cause in my case and it's actually a Laravel mix 6 configuration issue for Vue support.
You can check the documentation for more details : Laravel mix 6 upgrade documentation
But let me explain it in short here...
I was using Laravel mix 6 (you may probably use the same if you created a fresh Laravel 8 project) and according to its official documentation "Laravel Mix 6 ships with support for the latest versions of numerous dependencies, including webpack 5, PostCSS 8, Vue Loader 16, and more". So no need for you to add vue loader although the error states it.
You rather need to tell explicitly Laravel mix 6 to support vue, here what they say "Laravel Mix was originally built to be quite opinionated. One of these opinions was that Vue support should be provided out of the box. Any call to mix.js() would instantly come with the benefit of Vue single-file components.
Though we're not removing Vue support by any stretch, we have extracted Vue to its own "featured flag": mix.vue().
Here what I did.
First option
// You can simply use this
mix.js('resources/js/app.js', 'public/js')
.vue()
.postCss('resources/css/app.css', 'public/css', [
//
]);
Second option
// Or this if you want to extract styles as well
// Feel free to check the documentation for more customisations
mix.js('resources/js/app.js', 'public/js')
.vue({
extractStyles: true,
globalStyles: false
})
.postCss('resources/css/app.css', 'public/css', [
//
]);
First of all, thanks to Paul for this clarification which saved my evening :)
After that the compilation worked for me, but an error appeared in the console when I reloaded the page:
Vue.use is not a function
For those who would be in the same case, in your app.js file, you must replace the line :
window.Vue = require('vue');
With :
window.Vue = require('vue').default;
here i do with the some problem
mix.js('resources/js/app.js', 'public/js').vue()
.sass('resources/sass/app.scss', 'public/css')
.sourceMaps();
mix.js('resources/js/app.js', 'public/js').vue() .postCss('resources/css/app.css', 'public/css', [ // ]);
Or
npm install vue-template-compiler vue-loader#^15.9.7 --save-dev --legacy-peer-deps
try both..

Laravel Mix: Configure Babel for IE11 compatibility (transformations and polyfills)

In a Laravel 6 application with Laravel-Mix 4, and using the Vue preset, I need to compile my JavaScript code to be compatible for IE11. This means adding any polyfills for missing functions, compiling out arrow functions, and so on. Out of the box, this is not done.
My test code in resources/js/app.js:
//require('./bootstrap');
let test = [1, 2, [3, 4]];
console.log(
test.flat().map((x) => 2*x)
);
With default config, laravel mix does not appear to compile JavaScript code, but only do some formatting. Comments are preserved in the compiled output.
The result of npm run dev is:
Asset Size Chunks Chunk Names
/css/app.css 0 bytes /js/app [emitted] /js/app
/js/app.js 4.95 KiB /js/app [emitted] /js/app
How do I get Laravel-Mix to use Babel to create IE11-compatible source code?
Enable Babel compilation with Laravel Mix, and use polyfills for internet explorer
Step 1: Install Corejs to get polyfills
Following the Babeljs docs for babel-preset-env 2, we first need to install core-js (which contains the polyfills):
$ npm install core-js#3 --save
Step 2: Configure .babelrc
create a .babelrc file in the project root:
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": {
"version": 3,
"proposals": false
},
"targets": {
"ie": "11"
}
}
]
]
}
Now run npm run dev and you will find polyfills inserted, arrow functions compiled out etc. - your code may just run on IE11!
Laravel-Mix, Babel, IE: Some gotchas
node_modules are not processed through babel
With the default configuration, only source code in the project itself - not its dependencies - runs through the babel compilation step. This means that any let or similar in the dependencies will trip up legacy browsers 3.
using `mix.babel' risks compiling a file twice
The laravel mix docs suggest using the mix.babel function in the Vanilla JS section 1. What this appears to do:
if no .babelrc is present, the specified file is run through babel.
if a .babelrc is present, the normal mix compilation step already uses babel. Using mix.babel causes the compilation step to be run twice.
Interestingly, the twice-compiled code does not run on IE. One problem is that it will contain require() calls for polyfills that cannot be handled:
SCRIPT5009: 'require' is undefined
This is how I managed to get our webpage to work on IE11.
I'm listing all of the packages related to Babel, though some of them are only needed to make Jest work.
package.json
"devDependencies": {
"#babel/core": "^7.10.5",
"#babel/plugin-transform-runtime": "^7.10.5",
"#babel/preset-env": "^7.10.4",
"#babel/runtime-corejs3": "^7.10.5",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^24.9.0",
},
.babelrc
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "entry",
"bugfixes": true,
"targets": ">0.25%",
"corejs": {
"version": 3,
"proposals": false
}
}
]
],
"plugins": [
["#babel/plugin-transform-runtime", { "corejs": 3 }]
]
}
And finally
app.js
import './bootstrap';
import "core-js";
import Vue from 'vue';
// ...
I must say that I'm confused about the useBuiltIns property because different articles point toward different directions. It looks like if you use "useBuiltIns": "usage" you don't need to import core-js in app.js, anyway I have tried different combinations and this one is working fine.
According to the readme of core-js you need to import it, but I'm not 100% sure. Other resources that pointed me to the right directions were those two articles: https://www.valentinog.com/blog/preset-env/ and https://web.dev/serve-modern-code-to-modern-browsers/.
After this setup we only needed to update some CSS and the app was running fine. The only downside is that the vendor.js file is very heavy. I'd like to create a different bundle for browsers that support modules, but that's a different story...
Seems some use mix.babel(), but I believe that is better compatible with react. I had similar issue and I use babel-loader, #babel/preset-env and #babel/polyfill. Had to resort to polyfill cos I couldn't get core-js 3 to work following their docs. So if anyone is able to figure out how to make it work with core-js 3. I'd be glad to learn. And only install only what I seem to need for my project
Install:
npm install babel-loader #babel/preset-env #babel/polyfill --save
Webpack.mix.js
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
}
Finally, import at the begining of main/js or app/js
import '#babel/polyfill';
This has been tested on Laravel 7.x | vue 2.6
Dependencies:
"#babel/polyfill": "^7.10.4",
"#babel/preset-env": "^7.10.4",
"babel-loader": "^8.1.0",
Note: I decided to remove .babelrc from the root app completely, may seem like no effect but incase I need it, I prefer adding it to config.js

VueJS - Module not found: Error: Can't resolve '#babel/runtime/regenerator'

I have this error
Module not found: Error: Can't resolve '#babel/runtime/regenerator' in 'C:\wamp64\www\project-dev\modules\Gallery\Resources\Assets\Backend\Views\Album'
when I execute this command npm run dev.
So to explain my laravel project directory:
app
modules
auth
backend
gallery
themes
admin
node_modules
resources
js
components
router
index.js
store
app.js
sass
views
package.json
webpack.mix.js
So in my router/index.js of vuejs app, I will includes routes from a module.
I make this:
import GalleryRoutes from "../../../../../modules/Gallery/Resources/Assets/Backend/routes";
// Vue Router
const router = new VueRouter({
base: '/admin',
mode: 'history',
routes: [
...constantRoutes,
...GalleryRoutes,
],
linkActiveClass: "active",
linkExactActiveClass: "active",
});
routes.js file from Gallery module:
// Views
import AlbumIndex from './Views/Album/Index.vue'
// Routes
export default [
// AlbumIndex
{
path: 'gallery/albums',
component: AlbumIndex,
name: 'backend.gallery.album.index',
meta: {
heading: 'Gallery',
title: 'Albums',
icon: 'fas fa-images',
showed: true
}
}
];
But I get the error above.
I think this is a bug related to the node_modules folder, I'm not sure.
It's possible to achieve what I want to do? (include .Vue or .js files from outside my root app directory).
PS: I try to make this to try to answer this question: Backend (VueJS) of laravel application with modules approach
Thank you to helping me :)
It's looking for a dependency that is not installed. In your case you can do npm i babel-runtime --save to install that dependency you're missing.
Installing whatwg-fetch fixed the issue for me

How do you integrate a Vue.js package (like vodal) into Laravel?

I have an empty Laravel project and have been trying to install vodal
(https://github.com/chenjiahan/vodal) into it, with no luck.
I know the basics of vue.js but am still a beginner and have never used a Vue.js package in my Laravel app before.
Note: I was able to download https://github.com/chenjiahan/vodal and get it running as a standalone. The challenge is getting it integrated into a new Laravel 5.8 project.
After running:
npm i -S vodal
Where does this code go in my laravel app? What should go in:
app.js
a blade.php view file
a new Vue component
any other location?
How do I get this Vodal (or for that matter, any vue.js) package to work with Laravel? I've been struggling for hours on end, and ANY help would be appreciated.
<vodal :show="show" animation="rotate" #hide="show = false">
<div>A vue modal with animations.</div>
</vodal>
import Vue from 'vue';
import Vodal from 'vodal';
Vue.component(Vodal.name, Vodal);
export default {
name: 'app',
data() {
return {
show: false
}
}
}
// include animation styles
#import "vodal/common.css";
#import "vodal/rotate.css";
In laravel first open terminal and install npm with the command npm install after that you can see a new folder in your project named as node_modules. all your packages code is inside this folder.
Now simply run your command for vodal like npm i -S vodal
now you can simply import this package into your app.js file as you did.
Run npm run watch for development mode which will import all vodal code from node_modules folder into your app.js file which is inside your public directory.
Update
I saw your repository and I downloaded it and edit some of your files. you were doing totally wrong.
I suggest you to learn vuejs first rather than getting deep into it.
the problem was you calling it in vue, not in the vue component so why you give the following code.
export default {
components: {
Vodal
},
data() {
return {
show: false
}
}
}
we do this in vue component, not in vue.
in data, we return only in vue component and the official documentation of vodal, they also give an example of using it in vue component.
and you not using it in vue component so simply did this in vue like below
const app = new Vue({
el: '#app',
data:{
show: false
}
});
So Now Your CSS.
so for including css. i simply import this in app.scss file like below.
#import "~vodal/common.css";
#import "~vodal/rotate.css";
now the final part and your biggest mistake is.
why you don't include app.js file in welcome.blade file. All your code is written in app.js file and you are not including it. so i simply include it in welcome.blade file like below
<script src="{{ asset('js/app.js') }}" defer></script>
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
after all, just run npm run watch
so now the main part you need to show:true for show modal. by default is false so it will not show you.
am making a click event for the show , so you understand how it's all going to work. and ill share files with the link in the comment.

Resources