Laravel Mix is the fantastic Webpack-based asset compilation framework that ships by default with Laravel 5.4, replacing the Gulp-based Laravel Elixir. It has a ton of sensible defaults, and it's likely that you can use the default scripts in most cases to compile your assets.

In development:

$ npm run dev

Or, if you want to monitor your assets folder and automatically recompile when changes are detected:

$ npm run watch

Both of these commands will use Webpack with the NODE_ENV environment variable set to development, which means your assets will not be minified. When you're building for production, you use the following command:

$ npm run production

This will set NODE_ENV to production, which will result in the compiled assets being minified.

Out of the box, Mix doesn't provide a way to combine the production pipeline with a watch command. I find it useful sometimes to minify assets when I am trying to reduce the size of assets by removing unnecessary dependencies towards the end of a project - so I can see the final file size before I ship to production. Thankfully, it's really simple to add a new npm script to handle this scenario.

Open the package.json file in the root of your project. You should see a section scripts that looks as follows:

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

You can see exactly what is going on when you run one of these scripts - it's calling Webpack and passing in some flags to determine environment, progress reporting, watching and so on. We want to create something that's basically a hybrid of the watch and production scripts - I'll call it wp. Simply add it to the end of the scripts section:

"wp": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=production node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"

Save package.json and now run the command:

$ npm run wp

This time, it will compile and minify your assets, but also watch the folder for any changes for automatic recompilation.