Laravel-mix: Error when running Laravel Mix as a global package

Created on 14 Jan 2018  路  11Comments  路  Source: JeffreyWay/laravel-mix

  • Laravel Mix Version (npm list --depth=0): v1.7.2
  • Node Version (node -v): v9.3.0
  • NPM Version (npm -v): v5.5.1
  • OS: Windows 10 v10.0.16299.192

Description:

I am attempting to run Laravel Mix as a Global Package with NodeJS. However, I am receiving the following error:

@ production E:\webserver\apache\htdocs\service_framework\resources
cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js

cross-env is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ 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
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ production script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     E:\webserver\nodejs\_logs\2018-01-14T21_30_56_445Z-debug.log

No issues when I install Laravel Mix in the local directory using npm install. Just easier and uses less disk space by having this as a global package.

Steps To Reproduce:

1) Open Command Prompt.
2) Run npm install -g laravel-mix.
3) CD to the directory where Laravel Mix is required.
4) Run npm link laravel-mix.
5) Run npm run production.

stale

Most helpful comment

Wow, @matalina's suggestion works for me, thanks!

Here is my webpack.config.js version (copied from [email protected]):

/**
 * As our first step, we'll pull in the user's webpack.mix.js
 * file. Based on what the user requests in that file,
 * a generic config object will be constructed for us.
 */
let laravelMixPath = process.env.NODE_PATH + '/laravel-mix/';
let mix = require(laravelMixPath + 'src/index');

let ComponentFactory = require(laravelMixPath + 'src/components/ComponentFactory');

new ComponentFactory().installAll();

require('./webpack.mix');

/**
 * Just in case the user needs to hook into this point
 * in the build process, we'll make an announcement.
 */

Mix.dispatch('init', Mix);

/**
 * Now that we know which build tasks are required by the
 * user, we can dynamically create a configuration object
 * for Webpack. And that's all there is to it. Simple!
 */

let WebpackConfig = require(laravelMixPath + 'src/builder/WebpackConfig');

module.exports = new WebpackConfig().build();

Note: in my case NODE_PATH is refer to global packages, see https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders

All 11 comments

You may want to install cross-env package globally too.

@ankurk91 Thank you for your response.

I have linked cross-env, axios and lodash as global packages now.

Now I receive the following error:

> @ prod E:\webserver\apache\htdocs\service_framework\resources
> npm run production


> @ production E:\webserver\apache\htdocs\service_framework\resources
> 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 system cannot find the path specified.
events.js:136
      throw er; // Unhandled 'error' event
      ^

Error: spawn node_modules\webpack\bin\webpack.js ENOENT
    at notFoundError (E:\webserver\nodejs\node_modules\cross-env\node_modules\cross-spawn\lib\enoent.js:11:11)
    at verifyENOENT (E:\webserver\nodejs\node_modules\cross-env\node_modules\cross-spawn\lib\enoent.js:46:16)
    at ChildProcess.cp.emit (E:\webserver\nodejs\node_modules\cross-env\node_modules\cross-spawn\lib\enoent.js:33:19)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:209:12)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ 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`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ production script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     E:\webserver\nodejs\_logs\2018-01-15T20_32_16_689Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ prod: `npm run production`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ prod script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     E:\webserver\nodejs\_logs\2018-01-15T20_32_16_738Z-debug.log

Are there any other packages that I am missing? Those are the standard 4 packages that are listed in package.json during a standard Laravel install.

You can see we are calling webpack in this command

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 path node_modules/webpack/bin/webpack.js does not exists.
I don't think we can use Laravel-mix as a global package.

Why would someone install laravel-mix as a global package?

There are multiple reasons why we would like to run it as a global package:

  1. As laravel-mix is a pre-compiler, there is no need to deploy it to a production server.
  2. We use it for all our projects including non-Laravel frameworks.
  3. It is a mission to update 30+ projects which contain laravel-mix.
  4. It would save space when using cloud backups as we would not have to sync 150MB per project. 30 projects = 4.5GB.

This morning, I came across this post which unfortunately did not have a satisfying solution. After a day searching, I still don't have the solution, but perhaps a bit more information that might be useful.

I agree with the above given reasons, to which I can add one (don't hate me): I store the projects in a Dropbox folder, and don't have 10GB to store the exact same node_modules in each project... (yes I use git as well 馃憤)

node.js looks for folders higher in the tree that have a child with the name "node_modules". Furthermore it checks the location of PATH (enviromental variable in windows). So, in theory it should be possible to just move node_modules to any parent folder, and all should still work... but no...

I've seen the above error allot today:

Error: spawn node_modules\webpack\bin\webpack.js ENOENT

which basically means that it cannot find webpack...

What I did (for now) is simple: I created a new package.json in a parent folder of my project. (Project: c:/Dropbox/webserver/projects/laravel/projectname/, the package was created at c:/)

cd /
npm init

Install all packages that are shared among the projects, the most important one is ofcourse laravel-mix

npm install laravel-mix cross-env axios vue vue-i18n vue-loader bootstrap bootstrap-vue

and any other package you like to be shared.
Now copy the folders cross-env, laravel-mix and webpack to the node_modules of your project. Or, I guess a symlink should work as well. Also make sure to copy /.bin/cross-env and /.bin/cross-env.cmd to your local project node_modules.

When running npm run watch from your local project, it will/should work.

Notes:

  • In my test i actually made the "shared" node_modules in the parent of the project folder, but that should not matter
  • I guess you can install the packages as global as well (I cleared out my global folder %appdata%/npm/node_modules)
  • If any of the 3 folders does not exist, it wont work...

My thoughts: somehow the configuration passed to cross-env, laravel-mix and webpack, influence the way node.js searches for those folders. It prevents searching in parents or global (=PATH) folder...

--- EDIT ---
Symlink does not work... This is because the root path will be the true path, not the symlink path. Meaning that it will search for the config files at the wrong location.
Copying the folders does work however....

npminstall.bat file

@echo off

REM #Set the path to the shared node_modules folder. It needs to have a package.json file.
SET source=Z:\

echo Source folder is: %source%
echo Installing shared folder packages
REM #Update the shared folder
cd %source%
call npm install
echo Updating shared folder packages
call npm update

REM #Go to the local folder
pushd %~dp0

REM #Make the node_modules folder, if it does not exist
if not exist node_modules mkdir node_modules

echo Copying required folders for Laravel-mix
REM #Copy the required folders, to make laravel-mix run
xcopy %source%"\node_modules\cross-env" .\node_modules\cross-env /E /I /Y
xcopy %source%"\node_modules\laravel-mix" .\node_modules\laravel-mix /E /I /Y
xcopy %source%"\node_modules\webpack" .\node_modules\webpack /E /I /Y
xcopy %source%"\node_modules\.bin" .\node_modules\.bin /E /I /Y

echo Installing local packages
REM #update local dependencies (not the dev(!))
call npm install --production
echo Updating local packages
call npm update --production
echo ...Done...

In my situation, I can add all "commonly" used packages (i.e. cross-dev, laravel-mix, vue, vuex) in the devDependencies list of my package.json, and all project specific packages in the dependencies list.
Using the --production flag will only install the dependencies, and thus keeping my node_modules folder up to date, yet clean. Furthermore the script keeps the shared folder up-to-date, I just need to make sure to add additional shared packages to the package.json on the Z: location...

Even though this does not solve the problem that somehow the path in the config becomes absolute to the calling location, it might help someone...

Why can't you rewrite your npm script?

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

node_modules/webpack/bin/webpack.js should be the path to webpack bin which I'm assuming was installed globally as well

Then copy the webpack.config.js to your project file as per the 'working not in laravel instruction'

and change the --config=node_modules/laravel-mix/setup/webpack.config.js to just --config=webpack.config.js

Wow, @matalina's suggestion works for me, thanks!

Here is my webpack.config.js version (copied from [email protected]):

/**
 * As our first step, we'll pull in the user's webpack.mix.js
 * file. Based on what the user requests in that file,
 * a generic config object will be constructed for us.
 */
let laravelMixPath = process.env.NODE_PATH + '/laravel-mix/';
let mix = require(laravelMixPath + 'src/index');

let ComponentFactory = require(laravelMixPath + 'src/components/ComponentFactory');

new ComponentFactory().installAll();

require('./webpack.mix');

/**
 * Just in case the user needs to hook into this point
 * in the build process, we'll make an announcement.
 */

Mix.dispatch('init', Mix);

/**
 * Now that we know which build tasks are required by the
 * user, we can dynamically create a configuration object
 * for Webpack. And that's all there is to it. Simple!
 */

let WebpackConfig = require(laravelMixPath + 'src/builder/WebpackConfig');

module.exports = new WebpackConfig().build();

Note: in my case NODE_PATH is refer to global packages, see https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders

This works for me:

  1. Install node_modules on test laravel project:
    npm install

  2. move node_modules directory to a global path on your computer, save this global path on a global environment variable (run command with administrator previllege):
    setx NODE_PATH "your/path"

  3. Close cmd and open again to reload new env var created in last point.

  4. Install cross-env and jquery globally:
    npm install -g cross-env jquery

  5. Copy laravel-mix from %NODE_PATH%/laravel-mix to myLaravelProject/node_modules

cd myLaravelProject
xcopy "%NODE_PATH%/laravel-mix" ./node_modules/laravel-mix /e /i /h
  1. Update scripts in your laravel project myLaravelProject/package.json to:
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development %NODE_PATH%/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development %NODE_PATH%/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_PATH%/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
  1. After that you can do:
npm run watch
npm run dev
npm run prod

Hi All,

Thank you for your suggestions.

I have replaced the website name with <website name> due to a confidentiality agreement.

I have managed to compile JavaScript files but the SASS compiler throws the following error:

This dependency was not found:
* E:\webserver\apache\htdocs\<website name>\resources\assets\scss\app.scss in multi E:/webserver/nodejs/node_modules/laravel-mix/src/builder/mock-entry.js ./resources/assets/scss/app.scss
To install it, you can run: npm install --save E:\webserver\apache\htdocs\<website name>\resources\assets\scss\app.scss
ERROR in Entry module not found: Error: Can't resolve 'webpack.config.js' in 'E:\webserver\nodejs'
ERROR in multi ./node_modules/laravel-mix/src/builder/mock-entry.js ../apache/htdocs/<website name>/resources/assets/scss/app.scss
Module not found: Error: Can't resolve 'style-loader' in 'E:\webserver\nodejs'
 @ multi ./node_modules/laravel-mix/src/builder/mock-entry.js ../apache/htdocs/<website name>/resources/assets/scss/app.scss

My package.json file:

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

My webpack.config.js file:

let laravelMixPath = process.env.NODE_PATH + '/laravel-mix/';
let mix = require(laravelMixPath + 'src/index');
let ComponentFactory = require(laravelMixPath + 'src/components/ComponentFactory');
new ComponentFactory().installAll();
require('./webpack.mix');
Mix.dispatch('init', Mix);
let WebpackConfig = require(laravelMixPath + 'src/builder/WebpackConfig');
module.exports = new WebpackConfig().build();

Any further assistance would be appreciated. Thank you.

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.

it show let mix = require('../src/index'); "File is a CommonJS module; it may be converted to an ES6"

Was this page helpful?
0 / 5 - 0 ratings