9

I am trying out Laravel 9 with Vite, but without(!) a frontend framework (like Vue or React). I am trying to make a reusable js module that I could use/load in different Blade templates.

So I created a file 'menu-btn-toggle.js' in 'resources/js/components/utilities'.

export class MenuBtnToggle
{
    constructor() {
        console.log('MenuBtnToggle');
    }
}

I then created a 'utilities.js' file in 'resources/js/components'.

import './utilities/menu-btn-toggle';

I then updated the 'app.js' file in 'resources/js'

import './bootstrap';
import './components/utilities';

import Alpine from 'alpinejs';

window.Alpine = Alpine;

Alpine.start();

So far, this seems to be working (?). Atleast, i think so. Vite is not giving me any errors so far (yay!)

But then I try to import the module in a blade template, but I can't get it to work. So at the bottom of my blade template, I added this:

<script type="module">
    import MenuBtnToggle from 'menu-btn-toggle';

    new MenuBtnToggle();
</script>

But this gives me the following error:

Uncaught TypeError: Error resolving module specifier “menu-btn-toggle”. Relative module specifiers must start with “./”, “../” or “/”.

But when I add one of the examples, the error changes to:

Loading module from “[local_dev_url]/menu-btn-toggle” was blocked because of a disallowed MIME type (“text/html”).

as it isn't be able to find the module. It returns a 404.

Is it even possible do to want I want without a frontend framework? Or am I not seeing something obvious? I have experience with php, unfortunately not (enough) with Laravel and Vite.

4 Answers 4

7

If you're using Laravel, this works:

import { helper_fn } from "{{ Vite::asset('resources/js/helpers.js') }}" 

but it prints out the whole URL, which seems a bit overkill. But I could not get it to work using aliases or relative paths. And then again.. this would not work with older browsers which do not support import.

Sign up to request clarification or add additional context in comments.

2 Comments

Importantly, this also works in development with npm run dev which the other answers do not.
Yet, this won't work once built (i.e. vite build && vite preview --host 0.0.0.0 --debug -- ./public;) and even with the Vite manifest generated, and an error may appear on the page: Unable to locate file in Vite manifest: resources/js/helpers.js.
1

I was stuck into almost same situation where we are not able to use import statement inside our blade files using Vite. We commonly get

Uncaught TypeError: Error resolving module specifier “menu-btn-toggle”. Relative module specifiers must start with “./”, “../” or “/”.

or We get 404 Blocked error nearly same as

Loading module from “[local_dev_url]/menu-btn-toggle” was blocked because of a disallowed MIME type (“text/html”).

When importing external npm packages or modules, we need to put them in windows object just like you did above for Alpine

window.Alpine = Alpine;

But for your specific case problem you must do following

1)Inside menu-btn-toggle.js

export class MenuBtnToggle
{
    constructor() {
        console.log('MenuBtnToggle');
    }
}

2)Inside utilities.js

import {MenuBtnToggle} from "./utilities/menu-btn-toggle";
window.MenuBtnToggle = MenuBtnToggle;
  1. And then finally inside your app.js

    import './components/utilities';

  2. Now inside your .blade file, there is no need to import the MenuBtnToggle instead just do it like

    new MenuBtnToggle();

No need to use import MenuBtnToggle from 'menu-btn-toggle'; in blade. Important thing is to import your app.js file properly inside .blade file through vite

@vite(['resources/css/app.css','resources/js/app.js'])

And it works. It has worked when reproducing same files/setup as yours.

2 Comments

but this way, you have to import all of your small modules in app.js, and they are imported for all pages, all of the time, which defeats the purpose of having small modules
and also defeats the purpose of not Taking anything randomly at window level as well.
1

If you have only a function :

in resources/js/components/utilities/menu-btn-toggle.js :

function MenuBtnToggle
{
    console.log('MenuBtnToggle');
}

window.MenuBtnToggle = MenuBtnToggle;

If you don't define window.MenuBtnToggle line, you can see in console error like :
Uncaught ReferenceError: MenuBtnToggle is not defined

in resources/view/myView.blade.php :

@section(…)

@vite('resources/js/components/utilies/menu-btn-toggle.js')
//… you can now call you js function

Comments

0

My problem was to call a object method from a script inside the blade file.

Solved in this way.

Inside app.js:

import {My_object} from "./My_object.js";
window.My_object = My_object;

Inside the object:

export var My_object = {
    /**
    * Something
    **/
}

Thanks to everybody.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.