4

I've created a new Laravel project with laravel new test. Then I've ran npm install and npm run dev. I changed the welcome.blade.php file to

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" href="{{ mix('js/app.js') }}"></script>
    </head>
    <body>
        <div id="app">
            <example-component></example-component>
        </div>
    </body>
</html>

and that's the only change I've made. However the page is blank, and the Vue devtools extensions on Chrome says "Vue.js not detected".

Since Laravel provides nearly out-of-the-box support for Vue, I can't see what's going wrong. The relevant files are below (untouched from Laravel's installation).

/resources/js/app.js (which compiles successfully with npm run dev to /public/js/app.js)

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * The following block of code may be used to automatically register your
 * Vue components. It will recursively scan this directory for the Vue
 * components and automatically register them with their "basename".
 *
 * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
 */

// const files = require.context('./', true, /\.vue$/i);
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default));

Vue.component('example-component', require('./components/ExampleComponent.vue'));

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

const app = new Vue({
    el: '#app',
});

/resources/js/components/ExampleComponent.vue:

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Example Component</div>

                    <div class="card-body">
                        I'm an example component.
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

webpack.mix.js:

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | 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')
    .sass('resources/sass/app.scss', 'public/css');

package.json:

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
    "devDependencies": {
        "axios": "^0.19",
        "bootstrap": "^4.1.0",
        "cross-env": "^5.1",
        "jquery": "^3.2",
        "laravel-mix": "^4.0.7",
        "lodash": "^4.17.5",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.1",
        "sass": "^1.15.2",
        "sass-loader": "^7.1.0",
        "vue": "^2.5.17",
        "vue-template-compiler": "^2.6.10"
    }
}

Again, these are all simply as they get installed.

Any ideas? The blank page is successfully loading the compiled app.js file, which looks as it should (e.g. there's mentions of Vue and example-component).

user11632242
  • 51
  • 1
  • 2

4 Answers4

2

You need to defer your script

<script src="{{ asset('js/app.js') }}" defer></script>

The reason is by doing this:

const app = new Vue({
    el: '#app',
});

Javascript will be loaded as soon as it can and the element #app may not have been loaded yet. By defering, the JS will be executed once the document is loaded.

Alternatively, you can use jQuery to wait for the document to be loaded with $(document).ready (but don't use jQuery if you don't need it elsewhere)

Without jQuery: https://stackoverflow.com/a/800010/8068675

Edit: And as @swonder reminded me, you can also move the script at the bottom of the body. In which case it will be executed after the DOM has been fully loaded.

Clément Baconnier
  • 3,828
  • 3
  • 19
  • 41
0

Try adding forward slash '/' while calling app.js file

<script src="{{ mix('/js/app.js') }}"></script>

The only reason is that the project is not getting proper app.js file's path. You can debug by pressing ctrl+u and check the path of the js file.

  • 1
    Sorry, your answer is not relevant. The **slash** is not mandatory since `mix` [handle that](https://github.com/laravel/framework/blob/5.8/src/Illuminate/Foundation/Mix.php#L24) and @user11632242 already said that the file was loaded by chrome but not executed – Clément Baconnier Jun 17 '19 at 12:36
0

Try <script href="{{ asset('js/app.js') }}" defer></script> in the head of the document (like in app.blade.php)

0

Check your setup in below sequence

You have defined your application URL in .env file. For example, if you have setup your Laravel in test folder,

APP_URL=http://test.local/test/public/

Important! Use src in script tag, not href

<script type="text/javascript" src="{{ asset('js/app.js') }}"></script>

Check Your app.js is getting loaded correct by looking at developer's console.

Abhishek
  • 26
  • 2
  • 1
    `APP_URL` purpose is to be used as fallback to let know Laravel what the domain name is when he can't E.g.: a `Job` or a `Command`. Laravel already know the current `APP_URL` from the super global `$_SERVER` So it's not that will make it work. – Clément Baconnier Aug 06 '19 at 09:33
  • The arguments of the ````asset```` function is relative to the ````APP_URL````. So, if you have installed Laravel in sub-folder and you are using ````asset```` function, you need to define ````APP_URL````. – Abhishek Aug 06 '19 at 11:17
  • Please, edit your answer that only concerns **sub folders**. This answer will not work for a proper laravel setup which is not the case for the original question. – Clément Baconnier Aug 06 '19 at 12:21
  • I find one possible problem in OP's code, he is using href instead of src in his ```` – Abhishek Aug 06 '19 at 13:18
  • Quote: *"The correct app.js file is being loaded by Chrome, just (seemingly) not executed. – user11632242 Jun 17 at 10:02"* It's not a problem relative to the path. It's a problem relative with **deferring** – Clément Baconnier Aug 06 '19 at 13:28