【VueCLI】「sass-loader」と「node-sass」のインストールで失敗してしまうのを解決した方法

## 問題点
VueCLIでSCSSを使用するために、「sass-loader」と「node-sass」をインストールしようとしたが、大量のエラー文が吐き出されたりしてインストールが成功しない。
## 試したコード(※nodeのバージョンは16.13.2)
```terminal
☆以下の２つ☆
npm install -D sass-loader@10.0.2 node-sass@4.14.1

npm install -D sass-loader node-sass

```

ちなみにsass-loader単体だけのインストールは上手くいく。ただnode-sassと一緒にインストールしようとすると成功しないし、node-sass単体だけのインストールはもってのほか。

## 吐き出されたエラー文

```terminal
npm WARN deprecated tar@2.2.2: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.
npm ERR! code 1
npm ERR! path /Users/xxxxx/Desktop/vue_js_udemy/section6/test/node_modules/node-sass
npm ERR! command failed
npm ERR! command sh -c node scripts/build.js
npm ERR! Building: /usr/local/bin/node /Users/xxxxx/Desktop/vue_js_udemy/section6/test/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
npm ERR!   c++ '-DNODE_GYP_MODULE_NAME=libsass' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DLIBSASS_VERSION="3.5.5"' -I/Users/xxxxx/.node-gyp/16.13.2/include/node -I/Users/xxxxx/.node-gyp/16.13.2/src -I/Users/xxxxx/.node-gyp/16.13.2/deps/openssl/config -I/Users/xxxxx/.node-gyp/16.13.2/deps/openssl/openssl/include -I/Users/xxxxx/.node-gyp/16.13.2/deps/uv/include -I/Users/xxxxx/.node-gyp/16.13.2/deps/zlib -I/Users/xxxxx/.node-gyp/16.13.2/deps/v8/include -I../src/libsass/include  -O3 -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=c++11 -stdlib=libc++ -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/libsass/src/libsass/src/ast.o.d.raw   -c -o Release/obj.target/libsass/src/libsass/src/ast.o ../src/libsass/src/ast.cpp
 
 
 
 
<とにかく長すぎたので省略>
 
 
 
 
npm ERR! ../src/libsass/src/ast.hpp:1614:14: note: use reference type 'const std::string &' to prevent copying
npm ERR!         for (const auto numerator : numerators)
npm ERR!              ^~~~~~~~~~~~~~~~~~~~~~
npm ERR!                         &
npm ERR! ../src/libsass/src/ast.hpp:1616:25: warning: loop variable 'denominator' creates a copy from type 'const std::string' [-Wrange-loop-construct]
npm ERR!         for (const auto denominator : denominators)
npm ERR!                         ^
npm ERR! ../src/libsass/src/ast.hpp:1616:14: note: use reference type 'const std::string &' to prevent copying
npm ERR!         for (const auto denominator : denominators)
npm ERR!              ^~~~~~~~~~~~~~~~~~~~~~~~
npm ERR!                         &
npm ERR! 2 warnings generated.
npm ERR! In file included from ../src/binding.cpp:1:
npm ERR! In file included from ../../nan/nan.h:58:
npm ERR! In file included from /Users/xxxxx/.node-gyp/16.13.2/include/node/node.h:63:
npm ERR! In file included from /Users/xxxxx/.node-gyp/16.13.2/include/node/v8.h:30:
npm ERR! /Users/xxxxx/.node-gyp/16.13.2/include/node/v8-internal.h:492:38: error: no template named 'remove_cv_t' in namespace 'std'; did you mean 'remove_cv'?
npm ERR!             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
npm ERR!                                 ~~~~~^~~~~~~~~~~
npm ERR!                                      remove_cv
npm ERR! /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/type_traits:710:50: note: 'remove_cv' declared here
npm ERR! template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
npm ERR!                                                  ^
npm ERR! 1 error generated.
npm ERR! make: *** [Release/obj.target/binding/src/binding.o] Error 1
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: `make` failed with exit code: 2
npm ERR! gyp ERR! stack     at ChildProcess.onExit (/Users/xxxxx/Desktop/vue_js_udemy/section6/test/node_modules/node-gyp/lib/build.js:262:23)
npm ERR! gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
npm ERR! gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
npm ERR! gyp ERR! System Darwin 20.6.0
npm ERR! gyp ERR! command "/usr/local/bin/node" "/Users/xxxxx/Desktop/vue_js_udemy/section6/test/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
npm ERR! gyp ERR! cwd /Users/xxxxx/Desktop/vue_js_udemy/section6/test/node_modules/node-sass
npm ERR! gyp ERR! node -v v16.13.2
npm ERR! gyp ERR! node-gyp -v v3.8.0
npm ERR! gyp ERR! not ok
npm ERR! Build failed with error code: 1
 
npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/xxxxx/.npm/_logs/2022-02-07T17_58_55_700Z-debug.log
```

大体この手のエラーで試すであろう、package-lock.jsonとnode_modulesの削除をして、バージョンをnode-sassのバージョンを変えるなどして実行するが上手くいかず。

いろんな記事を読んでいると、node-sassは現在非推奨になっているらしく、かわりに「sass(Dart Sass)」の使用が推奨しているらしく、試しにインストールしてみたところこっちは成功。

参考記事：「[node-sassがDeprecatedになるとのことでNuxt.jsのsassをアップデートした](https://qiita.com/n0bisuke/items/123a69ba5940f11404aa)」

参考記事：「[まだ間に合う！node-sass（LibSass）から sass（Dart Sass）への移行](https://buildersbox.corp-sansan.com/entry/2021/03/10/110000)」

ただ、どうしてもnode-sassのインストールを成功してみたいという謎のプライドが邪魔したので、解決策を探す旅に出かける。

## 解決方法
解決策を探す旅に出かけるも、なかなか見つからず、Vueに深い知見をお持ちの方に聞いてみると以下のようなご回答をいただけた。

>Nodeのバージョンが古かったので最新安定バージョンv16.14.0にアップしたところ、

>同じようなエラーが確認できました。Nodeのバージョンとsassがバッティングしていたようなので、

>node_modulesとpackage.jsonのsass関連行と package-lock.json を削除いただき、

>npm install -D sass-loader@12.4.0 node-sass@7.0.1を実行していただけますでしょうか。

上記の通り実行したところ、無事解決しました！！

## その後に問題が発生！
node-sassおよびsass-loaderのインストールはできたものの、「npm run serve」でサーバーを立ち上げると以下のエラーが発生。

```terminal
> test@0.1.0 serve
> vue-cli-service serve

 INFO  Starting development server...
 ERROR  Error: Rule can only have one resource source (provided resource and test + include + exclude) in {
  "type": "javascript/auto",
  "include": [
    {}
  ],
  "use": []
}
Error: Rule can only have one resource source (provided resource and test + include + exclude) in {
  "type": "javascript/auto",
  "include": [
    {}
  ],
  "use": []
}
    at checkResourceSource (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/RuleSet.js:167:11)
    at Function.normalizeRule (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/RuleSet.js:198:4)
    at /Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/RuleSet.js:110:20
    at Array.map (<anonymous>)
    at Function.normalizeRules (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/RuleSet.js:109:17)
    at new RuleSet (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/RuleSet.js:104:24)
    at new NormalModuleFactory (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/NormalModuleFactory.js:115:18)
    at Compiler.createNormalModuleFactory (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/Compiler.js:636:31)
    at Compiler.newCompilationParams (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/Compiler.js:653:30)
    at Compiler.compile (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/Compiler.js:661:23)
    at /Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/Watching.js:77:18
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:24:1)
    at AsyncSeriesHook.lazyCompileHook (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/tapable/lib/Hook.js:154:20)
    at Watching._go (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/Watching.js:41:32)
    at /Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/Watching.js:33:9
    at Compiler.readRecords (/Users/xxxx/Desktop/vue_js_udemy/section6/test/node_modules/@vue/cli-service/node_modules/webpack/lib/Compiler.js:529:11)
```

上記のエラー文の一部である、「Error: Rule can only have one resource source」で検索をかけたところ、webpackのバージョンについて触れている外国語記事を多数見つけました。

試しに以下の手順で実行したところ、

```terminal
npm uninstall webpack
npm install webpack@^4.0.0
npm run serve
```

今度は以下のエラー文が確認できました。

```terminal
> test@0.1.0 serve
> vue-cli-service serve
 
 INFO  Starting development server...
98% after emitting CopyPlugin
 
 ERROR  Failed to compile with 2 errors                                                                                                                                                              1:59:05
 
 error  in ./src/modules/TestComponent.vue?vue&type=style&index=0&id=157c145a&scoped=true&lang=scss&
 
Syntax Error: TypeError: this.getOptions is not a function

<以下省略>
```

次に上記の「Syntax Error: TypeError: this.getOptions is not a function」で検索してみると、こちらの記事「[Nuxt.jsでSassを使用した際に「TypeError: this.getOptions is not a function」とエラーが出る](https://cly7796.net/blog/javascript/error-when-using-sass-with-nuxt-js/)」が見つかり、”**sass-loaderのv11.0.0以降はwebpackのバージョン5以上しか対応していない**”ことがわかりました。

sass-loaderのバージョンを10に指定することでいったんは解消できるようだったので、webpackのアンインストールをする前のコミットの状態に戻し、以下を実行したところ「node-sass」「sass-loader」のインストールも、「npm run serve」も全てうまく行きました！泣

```terminal
npm install --save-dev node-sass sass-loader@10
npm run serve
```