2022.12.17 추가

왜 그런지는 정확히 모르겠지만 yarn serve 등 yarn을 실행할 때 cmd 에서 실행하면 오류가 발생하고 bash (msys나 git에 포함된 bash) 에서 실행하면 오류가 나지 않는다.

개요

nodejs, vue/cli, yarn을 활용하여 vue 프로젝트를 만들고 yarn으로 로컬 실행시 “Error: The project seems to require yarn but it’s not installed” 오류가 발생한다. 그에 대응한 방법을 기술한다.

환경

  • Windows 10
  • node v18.12.1
  • npm v8.19.2
  • yarn v1.22.19
  • vue
  • vue/cli v5.0.8

오류 재현

일반적인 vue 프로젝트를 생성하는 vue create [project name] 을 따른다.

vue create project-sample
#프리셋 선택이 있다. 여기서는 Default [Vue 3] babel, eslint 를 선택하였으나 다른 것을 선택해도 동일한 오류가 발생한다.
cd project-sample
yarn serve

그럼 아래와 같은 오류 로그가 출력된다.

$ vue-cli-service serve
 INFO  Starting development server...


 DONE  Compiled successfully in 5644ms                                                                      오후 1:17:22


  App running at:
  - Local:   http://localhost:8080/
  - Network: http://10.100.22.62:8080/

 ERROR  Error: The project seems to require yarn but it's not installed.
Error: The project seems to require yarn but it's not installed.
    at checkYarn (C:\src\node-workspace\vue1\node_modules\@vue\cli-shared-utils\lib\env.js:46:43)
    at exports.hasProjectYarn (C:\src\node-workspace\vue1\node_modules\@vue\cli-shared-utils\lib\env.js:42:10)
    at C:\src\node-workspace\vue1\node_modules\@vue\cli-service\lib\commands\serve.js:330:34
    at Hook.eval [as callAsync] (eval at create (C:\src\node-workspace\vue1\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:44:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (C:\src\node-workspace\vue1\node_modules\tapable\lib\Hook.js:18:14)
    at Watching._done (C:\src\node-workspace\vue1\node_modules\webpack\lib\Watching.js:287:28)
    at C:\src\node-workspace\vue1\node_modules\webpack\lib\Watching.js:209:21
    at Compiler.emitRecords (C:\src\node-workspace\vue1\node_modules\webpack\lib\Compiler.js:919:5)
    at C:\src\node-workspace\vue1\node_modules\webpack\lib\Watching.js:187:22
    at C:\src\node-workspace\vue1\node_modules\webpack\lib\Compiler.js:885:14
    at Hook.eval [as callAsync] (eval at create (C:\src\node-workspace\vue1\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:12:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (C:\src\node-workspace\vue1\node_modules\tapable\lib\Hook.js:18:14)
    at C:\src\node-workspace\vue1\node_modules\webpack\lib\Compiler.js:882:27
    at C:\src\node-workspace\vue1\node_modules\neo-async\async.js:2818:7
    at done (C:\src\node-workspace\vue1\node_modules\neo-async\async.js:3522:9)
    at Hook.eval [as callAsync] (eval at create (C:\src\node-workspace\vue1\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
    at C:\src\node-workspace\vue1\node_modules\webpack\lib\Compiler.js:736:33
    at Immediate._onImmediate (C:\src\node-workspace\vue1\node_modules\memfs\lib\volume.js:701:13)
    at process.processImmediate (node:internal/timers:471:21)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

이는 vue의 cli-shared-utils 에서 yarn 버전을 확인하는 hasYarn 함수에서 오류가 나기 때문인데… 그 오류의 정확한 원인을 몰라 직접 해결할 수는 없었다.

실제로 yarn에 버그가 있었던 것도 아니고, 현재 환경에서 실행하는 것은 딱히 문제가 없었으므로 해당 함수를 수정하여 오류는 넘어갔다.

PROJECT_ROOT\node_modules\@vue\cli-shared-utils\lib\env.js 수정

// env detection
exports.hasYarn = () => {
  if (process.env.VUE_CLI_TEST) {
    return true
  }
  if (_hasYarn != null) {
    return _hasYarn
  }
  try {
    execSync('yarn --version', { stdio: 'ignore' })
    return (_hasYarn = true)
  } catch (e) {
    return (_hasYarn = false)
  }
}

위의 내용 중 catch하여 false를 리턴할 때 그냥 true를 리턴하도록 수정한다.

// env detection
exports.hasYarn = () => {
  if (process.env.VUE_CLI_TEST) {
    return true
  }
  if (_hasYarn != null) {
    return _hasYarn
  }
  try {
    execSync('yarn --version', { stdio: 'ignore' })
    return (_hasYarn = true)
  } catch (e) {
    return (_hasYarn = true) // 밑줄 쫙!
  }
}

이거 언제 수정되려나….