laravel-modules icon indicating copy to clipboard operation
laravel-modules copied to clipboard

Hi, any setup guide for Vite ?

Open pkd2989 opened this issue 2 years ago • 14 comments

Hi,

How to get module level control, separate css,scss,js control with Vite compilation.

Thanks

pkd2989 avatar Jul 14 '22 06:07 pkd2989

Also interested in the answer to this.

Sophist-UK avatar Jul 16 '22 15:07 Sophist-UK

You can follow this guide: https://docs.laravelmodules.com/v9/custom-module-generator. It's not exactly setup guide for vite but it's a way you can customize base module for module generator.

thoeunsopheara avatar Jul 17 '22 10:07 thoeunsopheara

I need to read up on vite I haven't tried it yet.

dcblogdev avatar Jul 19 '22 07:07 dcblogdev

Hi, this is a good guide for setting up vite on core laravel https://christoph-rumpel.com/2022/6/moving-a-laravel-webpack-project-to-vite

I've tried creating a vite config in a module but it doesnt appear to be getting picked up or its being overwritten by vite. Looking at how Mix words the manifests we're merged so vite may need something similar setting up.

dcblogdev avatar Jul 23 '22 22:07 dcblogdev

Hi all

I'm pretty comfortable with what I did in regards to this, but I have a problem that I don't see how to fix.

Each module comes with Resources/assets/js/app.js and Resources/assets/sass/app.scss files which are not updated in the manifest, because the keys in the manifest are that path to the file and it's the same every time, for example:

manifest.json

{
  "resources/js/app.js": {
    "file": "assets/app.d81e8d40.js",
    "src": "resources/js/app.js",
    "isEntry": true
  },
  "resources/css\\app.css": {
    "file": "assets/app.4ee680d5.css",
    "src": "resources/css\\app.css"
  },
  "Resources/assets/js/app.ts": {
    "file": "assets/app.a27edff8.js",
    "src": "Resources/assets/js/app.ts",
    "isEntry": true
  },
  "Resources/assets/sass/app.scss": {
    "file": "assets/app.4c41e8b9.css",
    "src": "Resources/assets/sass/app.scss",
    "isEntry": true
  }
}

only inserted the files of the first built module

Manually renaming these files and updating the vite.config file in each module, works perfectly

manifest.json with custom names

{
  "resources/js/app.js": {
    "file": "assets/app.d81e8d40.js",
    "src": "resources/js/app.js",
    "isEntry": true
  },
  "resources/css\\app.css": {
    "file": "assets/app.4ee680d5.css",
    "src": "resources/css\\app.css"
  },
  "Resources/assets/js/blog.ts": {
    "file": "assets/blog.ac3b5650.js",
    "src": "Resources/assets/js/blog.ts",
    "isEntry": true
  },
  "Resources/assets/sass/blog.scss": {
    "file": "assets/blog.abc5ca10.css",
    "src": "Resources/assets/sass/blog.scss",
    "isEntry": true
  },
  {
  "Resources/assets/js/test.ts": {
    "file": "assets/test.e5198d1b.js",
    "src": "Resources/assets/js/test.ts",
    "isEntry": true
  }
}

inserted the files of the modules Blog and Test

Is there a way to name these files dynamically (with the name of the module maybe? ) when creating the module?

arthvrian avatar Jul 28 '22 16:07 arthvrian

Following :)

tdrabikdev avatar Aug 04 '22 10:08 tdrabikdev

Following :)

MammutAlex avatar Aug 06 '22 18:08 MammutAlex

so adding a modules assets paths to vite.config.js file allows them to be compiled using npm run build

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css', 'resources/js/app.js',
                'Modules/Contacts/Resources/assets/js/app.js',
                'Modules/Contacts/Resources/assets/sass/app.scss',
            ],
            refresh: true,
        }),
    ],
});

This then builds this manifest:

{
  "resources/css/app.css": {
    "file": "assets/app.7c3c19f8.js",
    "src": "resources/css/app.css",
    "isEntry": true
  },
  "resources/js/app.js": {
    "file": "assets/app.334e7359.js",
    "src": "resources/js/app.js",
    "isEntry": true
  },
  "Modules/Contacts/Resources/assets/js/app.js": {
    "file": "assets/app.e5198d1b.js",
    "src": "Modules/Contacts/Resources/assets/js/app.js",
    "isEntry": true
  },
  "Modules/Contacts/Resources/assets/sass/app.scss": {
    "file": "assets/app.7c3c19f82.js",
    "src": "Modules/Contacts/Resources/assets/sass/app.scss",
    "isEntry": true
  }
}

Then to add to loading inside the

tags place @vite and pass in the files to load.

Normally you would use:

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

But say you want to also load in assets from a contacts module:

@vite([
    'resources/css/app.css',
    'resources/js/app.js',
     'Modules/Contacts/Resources/assets/js/app.js',
     'Modules/Contacts/Resources/assets/sass/app.scss',
 ])

This then created script and link tags for each asset passed.

dcblogdev avatar Aug 08 '22 11:08 dcblogdev

vite example in "admin" module ( last version laravel-vite-plugin):

you add import.meta.glob([ '../images/**', ]); into Modules/Admin/Resources/assets/js/app.js

and also make sure you have facade alias defined:

'Vite' => \Illuminate\Support\Facades\Vite::class,

in your config/app.php

Modules/Admin/vite.config.js:


import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

const domain = 'mydomain.test';
export default defineConfig({
    envDir: '../../',
    build: {
        manifest: true,
        emptyOutDir: true,
        assetsDir:'',
    },
    server: {
        https: {
            key: "../../.docker/nginx/certs/app.key",
            cert: "../../.docker/nginx/certs/app.crt",
        },
        host: domain,
        hmr: {
            host: domain,
        },
    },
    plugins: [
        laravel({
            hotFile: '../../storage/admin.hot',
            publicDirectory: '../../public',
            buildDirectory: "static/admin",
            input: [
                'Resources/assets/css/app.css',
                'Resources/assets/js/app.js',
            ],
            refresh: [
                'Resources/views/**/*.php',
            ],
        }),
    ],
});

in ViewServiceProvider:

    public function boot()
    {
        ...
        View::composer('admin:*', function ($view){
            Vite::useHotFile(storage_path('admin.hot'))->useBuildDirectory('static/admin');
        });
    }

use in view:

    {{
        Vite::withEntryPoints(['Resources/assets/css/app.css', 'Resources/assets/js/app.js'])
    }}

{{ Vite::asset('Resources/assets/images/logo.png') }}

jjanampa avatar Sep 03 '22 06:09 jjanampa

so adding a modules assets paths to vite.config.js file allows them to be compiled using npm run build

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css', 'resources/js/app.js',
                'Modules/Contacts/Resources/assets/js/app.js',
                'Modules/Contacts/Resources/assets/sass/app.scss',
            ],
            refresh: true,
        }),
    ],
});

This then builds this manifest:

{
  "resources/css/app.css": {
    "file": "assets/app.7c3c19f8.js",
    "src": "resources/css/app.css",
    "isEntry": true
  },
  "resources/js/app.js": {
    "file": "assets/app.334e7359.js",
    "src": "resources/js/app.js",
    "isEntry": true
  },
  "Modules/Contacts/Resources/assets/js/app.js": {
    "file": "assets/app.e5198d1b.js",
    "src": "Modules/Contacts/Resources/assets/js/app.js",
    "isEntry": true
  },
  "Modules/Contacts/Resources/assets/sass/app.scss": {
    "file": "assets/app.7c3c19f82.js",
    "src": "Modules/Contacts/Resources/assets/sass/app.scss",
    "isEntry": true
  }
}

Then to add to loading inside the tags place @vite and pass in the files to load.

Normally you would use:

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

But say you want to also load in assets from a contacts module:

@vite([
    'resources/css/app.css',
    'resources/js/app.js',
     'Modules/Contacts/Resources/assets/js/app.js',
     'Modules/Contacts/Resources/assets/sass/app.scss',
 ])

This then created script and link tags for each asset passed.

Hi, this is working well, but unfortunately when importing packages in node_modules or just a normal import from "Modules/Contacts/Resources/assets/js/app.js" is not working.

example: In Modules/Contacts/Resources/assets/js/app.js

import _ from 'lodash'
import './bootstrap';

got an error showing: "Uncaught TypeError: Failed to resolve module specifier "lodash". Relative references must start with either "/", "./", or "../"."

can you please help with this issue?

suarezph avatar Sep 06 '22 07:09 suarezph

Hi, everyone!!

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/admin.css',
                'resources/js/admin.js',
                'modules/*/Resources/assets/css/app.css',
                'modules/*/Resources/assets/js/app.js'
            ],
            refresh: true,
        }),
    ],
});

This is my vite config, when i run npm run dev it work but i can't npm run build it. Can you please help with this issue?

slym175 avatar Sep 19 '22 02:09 slym175

@slym175 What is your build script in package.json?

thoeunsopheara avatar Sep 21 '22 02:09 thoeunsopheara

@thoeunsopheara just vite build

slym175 avatar Sep 21 '22 02:09 slym175

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Oct 13 '22 05:10 stale[bot]

Any update on this guys?

anburocky3 avatar Oct 18 '22 07:10 anburocky3

I'm hoping https://github.com/nWidart/laravel-modules/pull/1455 will allow vite to be used from modules, I'll admit I know very little about vite.

dcblogdev avatar Oct 21 '22 16:10 dcblogdev

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 05 '22 20:11 stale[bot]

Also request this change. Following!

ap-coder avatar Nov 08 '22 19:11 ap-coder

vite config files in modules' folders doesn't seem to run when running npm run build or even npm run dev

shaheenfawzy avatar Nov 14 '22 14:11 shaheenfawzy

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 29 '22 18:11 stale[bot]

@ap-coder @b1ackfa1c0n Note that the module configuration for vite does not include the default asset files (tailwind, bootstrap, etc).

I previously made the bootstrap 5 getting started guide. #1467

The reason I didn't include an asset, is for the developer to choose which one to work with.

wikigods avatar Dec 01 '22 22:12 wikigods

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Dec 16 '22 22:12 stale[bot]

Also request this change. Following!

MammutAlex avatar Dec 17 '22 01:12 MammutAlex

Re-opened the vite issues as I don't believe its fully solved yet, that's why I haven't updated the docs yet.

The current implementation appears to work for using inside a single module but really each module should be able to push their vite assets into a central vite so we can load a single vite assert and load all them from a module. Tagging you @wikigods since you've worked on this a lot so far.

dcblogdev avatar Jan 24 '23 19:01 dcblogdev

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Feb 09 '23 00:02 stale[bot]

any updates about this ?

TheAhmedGad avatar Apr 09 '23 03:04 TheAhmedGad

any updates ?

bakkaliYoussef avatar Oct 30 '23 11:10 bakkaliYoussef

this is still an issue, there is not currently a way to built asserts from the root Vite config in the project root that will use modules Vite files.

Ideally it should work similar to mix in that each module can use a Vite file and have this merged into the main Vite file. I don't want to manually configure each module manually to load its assets.

dcblogdev avatar Oct 30 '23 19:10 dcblogdev

I've tried to combine vite configs this loads all the configs together but I think the laravel js helper overrides each time resulting in a single entry being generated inside the manifest file

import { defineConfig } from 'vite';
import merge from 'deepmerge';
import fs from 'fs/promises';
import path from 'path';

// Create an array to hold all module-specific configurations
const moduleConfigs = [];

// Define the path to your Laravel-modules directory
const modulesPath = path.join(__dirname, 'Modules');

async function loadModuleConfig(moduleName) {
  try {
    // Skip any files or directories that you want to ignore
    if (moduleName === '.DS_Store') {
      return true;
    }

    const moduleDir = path.join(modulesPath, moduleName);
    const viteConfigPath = path.join(moduleDir, 'vite.config.js');
    const stat = await fs.stat(viteConfigPath);

    if (stat.isFile()) {
      const moduleConfig = await import(viteConfigPath);
      moduleConfigs.push(moduleConfig.default);
    }
  } catch (error) {
    console.error(`Error loading module configuration for ${moduleName}:`, error);
  }
}

async function configureVite() {
  const moduleDirectories = await fs.readdir(modulesPath);

  for (const moduleName of moduleDirectories) {
    await loadModuleConfig(moduleName);
  }

  // Load and merge the core configuration from your project root
  const coreConfigPath = path.join(__dirname, 'vite.config.core.js');
  const coreConfig = await import(coreConfigPath);

  // Merge the core configuration with the module-specific configurations
  const mergedConfig = merge.all([...moduleConfigs]);

  return defineConfig(mergedConfig);
}

export default configureVite();

it may be better to have an array of paths that can be passed to the root config something like

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default function createViteConfig(inputArray) {
  return defineConfig({
    plugins: [
      laravel({
        input: inputArray,
        refresh: true,
      }),
    ],
  });
};

dcblogdev avatar Nov 02 '23 06:11 dcblogdev

made some progress loading paths from modules. In a module vite.config.js containing:

export const paths = [
    'Modules/Pages/resources/css/app.css'
];

then in the main vite file

populate an array of paths and then merge with arrays from modules and build it all in one go

import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import collectModulePaths from './vite-loader.js';
import path from 'path';

const paths = [
    'resources/css/app.css'
];

const modulesPath = path.join(__dirname, 'Modules');
const allPaths = await collectModulePaths(paths, modulesPath);

export default defineConfig({
    plugins: [
        laravel({
            input:  allPaths,
            refresh: true,
        }),
    ],
});

this relies on having a new file called vite-loader.js it can be inside the vite.config.js but I'd prefer to keep the file as simple as I can.

this generates the following (used 2 modules)

{
  "Modules/Books/resources/assets/sass/app.scss": {
    "file": "assets/app-4ed993c7.js",
    "isEntry": true,
    "src": "Modules/Books/resources/assets/sass/app.scss"
  },
  "Modules/Pages/resources/css/app.css": {
    "file": "assets/app-5a5d3a39.css",
    "isEntry": true,
    "src": "Modules/Pages/resources/css/app.css"
  },
  "resources/css/app.css": {
    "file": "assets/app-3ebdfa1f.css",
    "isEntry": true,
    "src": "resources/css/app.css"
  }
}

dcblogdev avatar Nov 02 '23 08:11 dcblogdev