laravel-mix / laravel-mix

The power of webpack, distilled for the rest of us.
MIT License
5.27k stars 807 forks source link

Multiple vendors from extract #488

Closed pprins closed 5 years ago

pprins commented 7 years ago

I have a problem with extracting to multiple vendors, which is possible since roughly a month? For example I want to extract to frontend/vendors.js and backend/vendors.js because they have different libraries and do not share everything.

I do something like:

mix...
.extract([
        'jquery',
        'vue',
        'axios'
    ], 'backend/vendors')
.extract([
        'jquery'        
    ], 'frontend/vendors')
...

The problem is that it creates 1 manifest.js file, I guess based on the last extract operation. Because of this my frontend does work but the backend fails completely. I would expect that there would be a backend/manifest.js and a frontend/manifest.js ?

I do include the files in the recommended order, but the backend fails on a bunch of webpack errors like Uncaught TypeError: Cannot read property 'call' of undefined

mix: 0.8.8 npm: 3.10.10 node: 6.9.4 OS: Ubuntu 16.04

JeffreyWay commented 7 years ago

I was under the impression that you only ever need a single manifest.js file.

That said, I can reproduce your issue, so we'll try to figure this out.

colincrick commented 7 years ago

Yes please, I need this as well

tegola commented 7 years ago

+1. Just encountered this issue while building separate files for an app and its administration back end.

Is there a workaround, in the meantime?

lohiaad commented 7 years ago

Yes Need multiple manifest.js files

arcanedev-maroc commented 7 years ago

I want this feature too soooo bad but with this setup:

mix.extract([
    'jquery', 'vue', 'axios', 'bootstrap-sass', '...' // Common dependencies (Back + Front)
], '/assets/js/vendors.js');

mix.extract([
    'chart.js', 'dropzone', '...' // Back dependencies
], '/assets/js/back-vendors.js');

mix.extract([
    'simplemde', '...' // Front dependencies
], '/assets/js/front-vendors.js');
<!-- Backoffice template -->
{{ Html::script(mix('assets/js/vendors.js')) }}
{{ Html::script(mix('assets/js/back-vendors.js')) }}
{{ Html::script(mix('assets/js/back.js')) }}
<!-- Frontoffice template -->
{{ Html::script(mix('assets/js/vendors.js')) }}
{{ Html::script(mix('assets/js/front-vendors.js')) }}
{{ Html::script(mix('assets/js/front.js')) }}

I'm using laravel-mix@0.11.3 on Windows (8.1), somebody notify me if it's possible 👍

mrcsmcln commented 7 years ago

+1

tsunamilx commented 7 years ago

+1

joshmanders commented 7 years ago

It would also be cool to be able to pass a callback to the extract method, that will be passed down, as in my own non-laravel-mix projects I pass a callback and do some checks on the file path to automatically put anything in node_modules into vendor folder. That way anytime I add a dependency to my project I don't need to add it there too.

Edit: Example

new CommonsChunk({
        name: 'vendors',
        filename: 'vendors.js',
        minChunks: (m) => m.resource && !!~m.resource.indexOf('node_modules')
      })
nejtr0n commented 7 years ago

+1

d3radicated commented 7 years ago

+1

omnichronous commented 7 years ago

+1

joshmanders commented 7 years ago

There are reaction features of github, there's no need to spam everyone with +1 replies.

chrisbbreuer commented 7 years ago

I have a similar issue as well;

// Mix frontend resources.
mix.js('resources/assets/js/app.js', 'public/js')
    .extract([
        'jquery', 'bootstrap', 'aos', 'lity',
    ]);

...

// Mix app resources.
mix.js('resources/assets/app/js/app.js', 'public/app/js');

I have three entry points in my Mix file. One for frontend, backend and my "public app" file. The code above stores my frontend vendor.js and manifest.js file inside public/app/js when it should be inside public/js.

Somewhat annoying, but it seems if you specify the vendor extract location, I can at least store the vendor file in the correct folder, but still not the manifest.js file.

When I then try to reference

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

it throws webpack errors.

@JeffreyWay any idea on a workaround for this?

markRosenvinge commented 6 years ago

+1

jayaregalinada commented 6 years ago

+1

benface commented 6 years ago

Any update on this?

dolbex commented 6 years ago

You can now do this with the new component based system

https://github.com/JeffreyWay/laravel-mix/blob/master/docs/extending-mix.md

san-kumar commented 6 years ago

@dolbex Can you please give an example on how you can do this with the component based system?

mix...
.extract([
        'jquery',
        'vue',
        'axios'
    ], 'backend/vendors')
.extract([
        'jquery'        
    ], 'frontend/vendors')
...
dolbex commented 6 years ago

@san-kumar, unfortunately I'm not well versed to build you an exact example without trying, failing, trying again. Our needs are different from yours but I believe if you can build it in a regular webpack configuration (maybe with the vue cli) you could port it pretty easily. https://github.com/devisephp/cms/blob/v2-dev/mix/DeviseMix.js

Edit I should point out that's our extension class for a project we are working on.

Edit 2: https://codepen.io/anon/pen/BxNZoN

ststaynov commented 6 years ago

@dolbex The example link you have provided is private and it can't be viewed by external users (not in your organization), could you put it in somewhere where the permissions are public?

dolbex commented 6 years ago

@ststaynov - try this: https://codepen.io/anon/pen/BxNZoN

charlesBochet commented 5 years ago

Hi! I hope this will help!

http://www.compulsivecoders.com/tech/how-to-build-multiple-vendors-using-laravel-mix/

Basically, the idea is to build your assets using different webpack.mix.js files to get more flexibility :)

garbinmarcelo commented 4 years ago

Hi! I hope this will help!

http://www.compulsivecoders.com/tech/how-to-build-multiple-vendors-using-laravel-mix/

Basically, the idea is to build your assets using different webpack.mix.js files to get more flexibility :)

I just came across this (I need style for admin and website), is this still valid or is there any other way to do it? some images that have this link are not opening...

chrisbbreuer commented 4 years ago

@marcelogarbin this is the approach I used: https://stackoverflow.com/questions/45046696/laravel-mix-multiple-entry-points-generates-one-manifest-js/45134898#45134898

garbinmarcelo commented 4 years ago

@Chris1904 And is it working well? Is there any harm in using this approach (as it seems unofficial, does it?)?

I was researching and found this package: https://github.com/KABBOUCHI/laravel-mix-merge-manifest

I would just like to make the best of this separation.

Thanks for answering

garbinmarcelo commented 4 years ago

Another question, does BrowserSync work with this file separation? how to make?

garbinmarcelo commented 4 years ago

answering my own questions:

I used what @Chris1904 suggested, ok it worked, but the mix-manifest.json file is subscribed every time losing some settings. So I used the suggested package laravel-mix-merge-manifest also on the other link suggested by @charlesBochet . It worked very well!

About BrowserSync, it worked perfectly!

Fantastic, now I can organize the assets into different files. Very happy for it :laughing: :beers:

Thank you all

crankycyclops commented 4 years ago

@charlesBochet, thank you! Your solution works really well for me :)

solicomo commented 4 years ago

@charlesBochet and @Chris1904 's way works very well.

There is a simpler way. We can use --env.mixfile in package.json to specify which mix file we want to use. For example:

cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --env.mixfile=webpack.mix.admin --config=node_modules/laravel-mix/setup/webpack.config.js

See --env.mixfile=webpack.mix.admin in the above line. It indicates we're going to use webpack.mix.admin.js.

Package laravel-mix-merge-manifest is still needed.