Laravel-mix: How to make a separate npm command to run mix with different config?

Created on 25 Oct 2019  路  4Comments  路  Source: JeffreyWay/laravel-mix

My webpack.mix.js looks so:

let mix = require('laravel-mix')
mix.react('resources/assets/js/app.js', 'public/js')
    .sass('resources/assets/sass/app.scss', 'public/css');

The npm scripts are default:

"scripts": {
  "dev": "npm run development",
  "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
  "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
  "watch-poll": "npm run watch -- --watch-poll",
  "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
  "prod": "npm run production",
  "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},

The issue is that production script compiles both js and sass and runs very long. Most of time I need to compile only sass which should be very quick, but I'm struggling how to make a command to compile sass without js?

I tried this command:

"css": "node-sass --include-path resources/assets/sass --output-style compressed --precision=8 resources/assets/sass/app.scss public/css/app.css"

But it doesn't properly include files from node_modules. And after half hour googling I decided that it's not worth teaching this command to include things from node_modules properly, better stick to laravel-mix.

Then I tried to run mix with custom config parameters (note the --only-sass):

"css": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --only-sass --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"

and process it in webpack.mix.js:

if (process.argv.includes('--only-sass')) {
    mix.sass('resources/assets/sass/app.scss', 'public/css');
} else {
    mix.react('resources/assets/js/app.js', 'public/js')
        .sass('resources/assets/sass/app.scss', 'public/css');
}

But this also didn't work because webpack fails when meets unknown parameters 馃槴

Then I tried to pass the parameter as env variable (notice the ONLY_SASS):

"css": "cross-env NODE_ENV=production ONLY_SASS=true node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"

this also didn't work because cross-env seems to set only first parameter.

Now I'm giving up. Any ideas how to achieve what I need? The task looks so simple at glance and so complicated in reality.

Most helpful comment

Okay maybe a few snippets from our config help:
script:
```
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"prod-css": "MODE=copy npm run prod",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},

In the webpack.mix.js

let mix = require('laravel-mix');

const arg = process.env.MODE;
console.log('MODE Env: '+arg);

....
```

the when I run npm run prod-css I get

MODE Env: copy

In the console.

All 4 comments

Hey Stalinko,

we use process.env for that.
We use different "modes" so one "all" and another two "css" and "js".
So for your example: process.env.ONLY_SASS

@SudoGetBeer but I tried that and it didn't work. This is my latest example:

"css": "cross-env NODE_ENV=production ONLY_SASS=true node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"

ONLY_SASS looks to be undefined because cross-env accepts just one variable.

Okay maybe a few snippets from our config help:
script:
```
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"prod-css": "MODE=copy npm run prod",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},

In the webpack.mix.js

let mix = require('laravel-mix');

const arg = process.env.MODE;
console.log('MODE Env: '+arg);

....
```

the when I run npm run prod-css I get

MODE Env: copy

In the console.

@SudoGetBeer thanks a lot! It didn't work right how you wrote it, but pushed me onto the right way.

In windows env variables don't set up without cross-env.
So finally I've got 2 new scripts:

  "scripts": {
      ...
      "css": "cross-env MODE=css npm run prod",
      "js": "cross-env MODE=js npm run prod"
  },

And this is the updated webpack.mix.js:

let mix = require('laravel-mix')

const mode = process.env.MODE;

if (mode === 'css') {
    console.log('Compiling CSS')
    mix.sass('resources/assets/sass/app.scss', 'public/css');
} else if (mode === 'js') {
    console.log('Compiling JS')
    mix.react('resources/assets/js/app.js', 'public/js');
} else {
    mix.react('resources/assets/js/app.js', 'public/js')
        .sass('resources/assets/sass/app.scss', 'public/css');
}

Now all 3 commands work like a charm:

npm run prod
npm run css
npm run js
Was this page helpful?
0 / 5 - 0 ratings

Related issues

rderimay picture rderimay  路  3Comments

nezaboravi picture nezaboravi  路  3Comments

Cheddam picture Cheddam  路  3Comments

terion-name picture terion-name  路  3Comments

Bomavi picture Bomavi  路  3Comments