How to use npm packages in Laravel with Vite frontend build tool

Vite is a Next Generation Frontend Tooling and Vite is now the default Laravel module bundler.

this method will help you to configure any npm package. just import the package in /resources/js/app.js and add <script type="module"></script> where you want to use that npm package.

Checkout Laracast threads on this topic for more in-depth details with my comment [link]

https://laracasts.com/discuss/channels/vite/laravel-vite-jquery?page=1&replyId=825471

How to use any NPM Package in Laravel with Vite

  • install npm package (like jquery, dropzone, select2, etc…)
  • import that package in `/resources/js/app.js`
    • import $ from ‘jquery’
    • import select2 from “select2”
    • import dropzone from “dropzone”
    • window.jQuery = window.$ = $
  • add attribute type=”module” in <script> tag where you want to use that npm package.

How to use any NPM Package in Laravel with Vite

2 2 minutes

install npm package

install npm package (like jquery, dropzone, select2, etc…)

import that package in /resources/js/app.js

import $ from ‘jquery’
import select2 from “select2”
import dropzone from “dropzone”
window.jQuery = window.$ = $

add attribute type=”module” in </p>

<script type=”module”></script>

Usage

<script type=”module”> $(“button”).click(function() { $(“p”).hide(); }); $(“.select2”).select2(); </script>

How to fix Uncaught ReferenceError: $ is not defined issue with vitejs

- First your route URL request load
- then app.css
- then app.js
- then all other imports (like fonts, svg, css, js)
- (means jquery, select2, dropzone etc will load after app.js)
-- and due to this you got the Uncaught ReferenceError: $ is not defined


Goto: (check the sequence of your project)
-- Inspect element
-- Network
-- and you can see the request sequence

Suppose you import jQuery, select2, dropzonejs, and other packages in  resources/js/app.js like
-------------------------------
import $ from 'jquery'
import select2 from "select2"
import dropzone from "dropzone"
window.jQuery = window.$ = $
-------------------------------

/**
then above all imports didn't work properly reason you need to add module in <script> attribute.
Using module on your inline <script> tag solves this issue by loading the JavaScript in the correct order, making app.js load in before your inline <script> tags and populating the window object with jQuery.
**/


Example:
<script type="module">
    $("button").click(function() {
        $("p").hide();
    });

    $(".select2").select2();
</script>


and maybe you use @stack, @push then the code will be

@push('js_after')
<script type="module">
    $("button").click(function() {
        $("p").hide();
    });

    $(".select2").select2();
</script>
@endpush

Below is the complete details step by step.

Complete details step by step.

install npm the package you want.

npm i jquery
npm i select2  // maybe
npm install --save dropzone // maybe

2nd: add Jquery alias in vite.config.js [you can skip this step, if you don’t want alias and jump to 3rd-step]

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
    ],
    resolve: {
        alias: {
            '$':  'jQuery',
        },
    },
});

3rd: add the below code at end of the resources/js/app.js

import $ from 'jquery'
import select2 from "select2"
import dropzone from "dropzone"

window.jQuery = window.$ = $

4th: make sure you added @vite([‘resources/css/app.css’, ‘resources/js/app.js’]) in <head>

<head>
    <meta charset="utf-8">
    <title>Dashboard</title>
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>

    @yield('content')

    @stack('js_after')
</body>

5th: try to add type=”module” in </p>

<script type="module">
    $("button").click(function() {
        $("p").hide();
    });

    $(".select2").select2();
</script>



// with child blade

@extends('layouts.dashboard')
@section('content')
    <!-- your blade code -->

    @push('js_after')
        <script type="module">
                $("button").click(function() {
                $("p").hide();
                });

                $(".select2").select2();
        </script>
    @endpush

@endsection

Also read:

56 / 100
Hassam
Hassam

I am passionate about open-source software, privacy, best practices, standards, user experience, and developer experience. My favorite stack these days are Laravel, Vue, and Tailwind. And focusing on Solid Principles, Data Structures, and Design Patterns.

Articles: 26

Leave a Reply

Your email address will not be published. Required fields are marked *