Laravel-mix: Ability to set a custom webpack.mix.js

Created on 23 Mar 2017  ยท  11Comments  ยท  Source: JeffreyWay/laravel-mix

  • Laravel Mix Version: 0.9.0
  • Node Version 6.10.0
  • NPM Version 4.2.0
  • OS: Mac OS

Description:

This is a request to be able to specify a custom webpack.mix.js file at runtime. for example

It's important to note that this change is transparent and has no BC breaks. if you don't explicitly use it, it won't make any difference.

// this will load the webpack.mix.js
npm run dev

// the following will look for a custom.mix.js file instead of the webpack.mix.js file
// if not found it wont error just like webpack.mix.js works
npm run dev -- --env.mixfile=custom.mix

This allows cases where there are more than one site to compile assets for.

For example, in our case we have 4 sites, each has it's own compile process and code, we have everything in webpack.mix.js file, however, it most cases when we release we only want to compile one site not all of them. This change will allow us to split webpack.mix.js into multiple files and call the one we need at the time.

PR is being submitted.

Most helpful comment

For your specific use case, you could already do this if you want. Use webpack.mix.js as a single point of entry for Mix, but then pass an env flag as you mentioned.

Given that you have multiple webpack.mix.js files that each correspond to different sites, e.g.,

โ”œโ”€โ”€ webpack.mix.js        # โ†’ Mix entrypoint
โ”œโ”€โ”€ webpack.mix.site1.js  # โ†’ Mix for site1
โ”œโ”€โ”€ webpack.mix.site2.js  # โ†’ Mix for site2
โ”œโ”€โ”€ webpack.mix.site3.js  # โ†’ Mix for site3
โ””โ”€โ”€ webpack.mix.site4.js  # โ†’ Mix for site4

And you can pass an environment variable to node, e.g.,

npm run dev -- --env.site=site1

Then webpack.mix.js could have something like:

const { mix } = require('laravel-mix');
const { env } = require('minimist')(process.argv.slice(2));

/* do stuff with mix that's common to all sites, like maybe mix.options() */

// load site-specific config
if (env && env.site) {
    require(`${__dirname}/webpack.mix.${env.site}.js`);
}

And webpack.mix.site1.js, site2, site3, etc. could be normal mix config files:

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

mix.js('resources/assets/js/app.js', 'public/site1/js')
   .sass('resources/assets/sass/app.scss', 'public/site1/css');

I'm using minimist and sniffing out the --env argument, but as an alternative, you could use cross-env combined with process.env. (Another way of doing it would be to use your own webpack.config.js and export it as a function, but it would require a number of extra steps that make it not worth the effort.)

All 11 comments

For your specific use case, you could already do this if you want. Use webpack.mix.js as a single point of entry for Mix, but then pass an env flag as you mentioned.

Given that you have multiple webpack.mix.js files that each correspond to different sites, e.g.,

โ”œโ”€โ”€ webpack.mix.js        # โ†’ Mix entrypoint
โ”œโ”€โ”€ webpack.mix.site1.js  # โ†’ Mix for site1
โ”œโ”€โ”€ webpack.mix.site2.js  # โ†’ Mix for site2
โ”œโ”€โ”€ webpack.mix.site3.js  # โ†’ Mix for site3
โ””โ”€โ”€ webpack.mix.site4.js  # โ†’ Mix for site4

And you can pass an environment variable to node, e.g.,

npm run dev -- --env.site=site1

Then webpack.mix.js could have something like:

const { mix } = require('laravel-mix');
const { env } = require('minimist')(process.argv.slice(2));

/* do stuff with mix that's common to all sites, like maybe mix.options() */

// load site-specific config
if (env && env.site) {
    require(`${__dirname}/webpack.mix.${env.site}.js`);
}

And webpack.mix.site1.js, site2, site3, etc. could be normal mix config files:

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

mix.js('resources/assets/js/app.js', 'public/site1/js')
   .sass('resources/assets/sass/app.scss', 'public/site1/css');

I'm using minimist and sniffing out the --env argument, but as an alternative, you could use cross-env combined with process.env. (Another way of doing it would be to use your own webpack.config.js and export it as a function, but it would require a number of extra steps that make it not worth the effort.)

Closing this since we have a PR now. Thx.

@QWp6t Even though it's closed i wanted to address the items in your comment.

Yes, we can go that route and we already are doing something like this. But the bigger issue is that we can't run more than one .js().extract() at a time, it just wont work since the manifest.js file will only get generated once at the last call to extract().

The second problem is that the mix-manifest.json file is being overwritten completely with each call to version(), the PR also addresses that, so i can run webpack.mix.js, it'll write to mix-manifest.json and then run custom.mix.js it'll _Add_ to the file rather than overwriting it completely, it'll, however overwrite exiting entries if matched and deleted the old build/versioned file.

Not to mention that it makes everything clearer, allows us to only build on site at a time without worrying about everything else breaking due to build failures (something we are dealing with right now).

Thank You.

@VinceG Really good work!

However I don't understand how you achieve to be able to "add" to the mix-manifest.json file, in my case, it is always completely overwritten with/without version().

I am using laravel-mix version 1.1.0.

Found workaround here #946.

@tsunamilx Are you asking regarding the PR itself or is this not working for you? the idea behind it merging the changes to the existing mix-manifest was the fact that instead of starting with a new object {} it loaded the current mix manifest and then altered the records. i can link to the exact line that it does that.

I understand the concept, but it didnโ€™t work for me, the mix-manifest.json
is always completely overwritten.
This issue #946 also reports that and gave the workaround.

Just a guess: there were a lot of changes since your PR, especially the
official version 1.0 was released, this mechanism is not working anymore?

Is it working for you with version 1.0+?

On 10 July 2017 at 06:47:33, Vincent Gabriel ([email protected])
wrote:

@tsunamilx https://github.com/tsunamilx Are you asking regarding the PR
itself or is this not working for you? the idea behind it merging the
changes to the existing mix-manifest was the fact that instead of starting
with a new object {} it loaded the current mix manifest and then altered
the records. i can link to the exact line that it does that.

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/JeffreyWay/laravel-mix/issues/608#issuecomment-313970705,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AF_7obwFfDkfcC9Vb7abYo-qf4SqGBS3ks5sMViEgaJpZM4Ml_PW
.

@tsunamilx i am not using the latest version since i have other changes involved in our fork. But i'll try on a fresh install using laravel-mix 1.0 and see what comes out.

@tsunamilx @JeffreyWay i can confirm this no longer works in Mix latest version 1.2.0

Any workaround to solve this with Mix 1.*?

@heruputra see the workaround here #946.

@QWp6t your solution does not work when using mix.version()

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kpilard picture kpilard  ยท  3Comments

mstralka picture mstralka  ยท  3Comments

sdebacker picture sdebacker  ยท  3Comments

dtheb picture dtheb  ยท  3Comments

amin101 picture amin101  ยท  3Comments