V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
pilishen
V2EX  ›  2018

Laravel 5.4 Mix 执行 npm run dev 时报错,提示 cross-env 找不到(not found)的原因及解决办法

  •  
  •   pilishen · 2018-02-08 09:01:56 +08:00 · 2047 次点击
    这是一个创建于 2510 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本文来自 pilishen.com----原文链接

    《 Npm Debug Series 》是我们课程laravel 实战实战系列课程的扩展阅读篇,虽然视频中我们已经将 npm install 过程中的常见问题及解决方案都说了,但是鉴于 npm 的问题相对频繁,有随时查阅之需,故有此系列文章。

    最近很多小伙伴在使用最新的 laravel5.4 来学习我们的laravel 实战优雅入门:任务管理系统(一),在进行到第 14 节前端资源的管理与调用( elixir )时,当执行了npm run dev命令来编译前端资源时,经常会遇到一个报错,类似这样:

    > [email protected] dev /home/vagrant/Code
    > cross-env NODE_ENV=development webpack --progress --hide-modules
    
    sh: 1: cross-env: not found
    
    npm ERR! Linux 4.4.0-51-generic
    npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "dev"
    npm ERR! node v7.8.0
    npm ERR! npm  v4.2.0
    npm ERR! file sh
    npm ERR! code ELIFECYCLE
    npm ERR! errno ENOENT
    npm ERR! syscall spawn
    npm ERR! [email protected] dev: `cross-env NODE_ENV=development webpack --progress --hide-modules`
    npm ERR! spawn ENOENT
    

    或者说:

    npm ERR! Failed at the @ dev script 'cross-env NODE_ENV=development webpack --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js'.
    

    可能你具体的错误提示还稍有差异,不过这里先不管它,重点在于问题是出在cross-env这个组件上。

    这个cross-env是个什么鬼?有什么用?

    Most Windows command prompts will choke when you set environment variables with NODE_ENV=production like that. (The exception is Bash on Windows, which uses native Bash.) Similarly, there's a difference in how windows and POSIX commands utilize environment variables. With POSIX, you use: $ENV_VAR and on windows you use %ENV_VAR%.
    

    好吧,又是微软 Windows 的锅~也即是我们在 windows 系统上使用NODE_ENV=production这样的方式来设置node环境时,因为 windows 的系统变量是%ENV_VAR%这种格式,而“行业标准”是$ENV_VAR这样的,当然 windows 上的 bash 例外。

    那么为了解决这个跨平台环境变量的问题,就有了cross-env这个组件。知道这些个有啥用呢?

    用处是,**cross-env只是用在 windows 系统上的,在 Mac 和 Linux 系统上没用**,不需要装,装了反而会坏事儿~

    所以从这一点上,你的问题其实有两种可能:

    1. 你的项目环境是 Windows 系统,你没有装cross-env,或者说因为路径等其他原因调用不到它。
    2. 你的项目环境是 Linux 或 Mac,这个时候你没必要装cross-env,但是你却装了,或者说 laravel 默认带了,而且装就装吧,路径调用往往还有错
    3. 这里特别的是,如果你是用的 Homestead 开发环境,因为你虚拟机里是 Linux,所以如果你在 Host 主机上去操作,那你就是 Windows 环境,如果你vagrant ssh进了虚拟机操作,那么就是 Linux 环境;

    所以解决办法也要基于你的项目开发环境:

    一、Linux ( Homestead )或 Mac 环境下:

    你要做的,只是将你的package.json文件中的cross-env删掉即可:

    "dev": "node  NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "node NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch-poll": "node NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --watch-poll --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "hot": "node 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_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    

    二、Windows 系统下( WAMP、MAMP )

    1. 首先你需要装一下cross-env,执行:
    npm install --save-dev cross-env  --no-bin-links
    

    或者你也可以全局安装一下cross-env,以防止以后在其他项目也出现类似错误:

    npm install -g cross-env  --no-bin-links
    
    1. package.json文件中的cross-env调用换成具体路径node_modules/cross-env/dist/bin/cross-env.js,最终类似这样:
    "dev": "node node_modules/cross-env/dist/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/dist/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",
    "watch-poll": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --watch-poll --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "hot": "node node_modules/cross-env/dist/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/dist/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"
    
    1. 保险起见,再执行一下npm install --no-bin-links
    2. 然后再去执行npm run dev来试试

    为什么会出来这么多梗?甚至很多人因此诟病 laravel 5.4 不友好——直接下载全新安装都跑不起来

    因为一直到 laravel 5.4.15 ,laravel 的package.json是这样的:

    {
      "private": true,
      "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",
        "watch-poll": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --watch-poll --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"
      },
      "devDependencies": {
        "axios": "^0.15.3",
        "bootstrap-sass": "^3.3.7",
        "jquery": "^3.1.1",
        "laravel-mix": "^0.8.1",
        "lodash": "^4.17.4",
        "vue": "^2.1.10"
      }
    }
    

    可以看到它的devDependencies里没有依赖cross-env,但是在上方声明了cross-env的路径:node_modules/cross-env/bin/cross-env.js,因为laravel-mix这个组件里用到了cross-env。但是没多久,cross-env的作者对组件路径做了更改,将cross-env/bin换成了cross-env/dist,于是在这个laravel commit里,package.json 文件里更改了cross-env的路径,同时"devDependencies"里加上了"cross-env": "^3.2.3",然后没几天,作者们意识到既然依赖了 cross-env,就没必要上面写具体路径了,所以在这个laravel commit里,package.json 文件变成这样:

    {
      "private": true,
      "scripts": {
        "dev": "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": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --watch-poll --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "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",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
      },
      "devDependencies": {
        "axios": "^0.15.3",
        "bootstrap-sass": "^3.3.7",
        "cross-env": "^3.2.3",
        "jquery": "^3.1.1",
        "laravel-mix": "^0.8.1",
        "lodash": "^4.17.4",
        "vue": "^2.1.10"
      }
    }
    

    这期间呢,laravel-mix 的作者 Jeffway 看到 laravel 里依赖了 cross-env,所以他就在 laravel-mix 里直接取消了对 cross-env 的依赖,因为没必要重复安装,这直接导致了一系列问题的发生。而且这期间,laravel 里对 cross-env 的依赖一直停留在"cross-env": "^3.2.3",直到 5.4.30 ,才突然变成"cross-env": "^5.0.1". 所以呢,取决于你所使用的 laravel 和 laravel-mix 的版本,可能是你 package.json 里没有 cross-env 而报错,也可能是路径变了以后没更新,也可能是 laravel 调用的版本一直太低,因为这期间你可能执行了composer updatenpm update这些命令而导致两者的小版本都发生变化,所以说不清道不明的问题就发生了。

    最后,向依然在 Windows 上裸奔的 laravel 开发者致以凝重的深望~

    viko16
        1
    viko16  
       2018-02-08 10:38:49 +08:00
    Mac / Linux 下也没必要把 cross-env 去掉,本来就是跨平台用的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5497 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 09:00 · PVG 17:00 · LAX 01:00 · JFK 04:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.