LoginSignup
5
1

More than 3 years have passed since last update.

【Vue.js】Jest+scss でユニットテスト時のスタイルのコンパイルを止めた件

Posted at

Vue CLI 環境で Jest によるユニットテスト環境を構築しようとしたところ、 scss や CSS Modules との兼ね合いでうまくテストを走らせられませんでした。
スタイルに関するユニットテストをしないなら、テスト時はスタイルのコンパイルを止められるのではないかと考え調べてみたところ、実現できることがわかったのでその設定を紹介します。

動作確認した環境

  • macOS Catalina
  • Chrome 83
  • Node.js 12.18.1
  • npm 6.14.5
  • Vue CLI v4.4.4
    • vue 2.6.11
    • sass (dart-sass) 1.26.5
    • sass-loader 8.0.2
    • @vue/test-utils 1.0.3
    • @vue/cli-plugin-unit-jest 4.4.0

テスト時のスタイルのコンパイルを止める方法

vue-jest の設定で experimentalCSSCompile 1false にします:

jest.config.js
module.exports = {
  preset: '@vue/cli-plugin-unit-jest/presets/typescript',
  globals: {
    'vue-jest': {
      experimentalCSSCompile: false
    }
  }
}

ユニットテスト時のスタイルのコンパイルを止めた理由

理由1: スタイルに関するユニットテストは難しい

デザインの変更が頻繁に発生する場合、「この状態のときは○○の色が赤である」といったテストは壊れやすいのではないかと思います。
(デザイナーがわずかに色を調整するとユニットテストが通らなくなる、といったケースなど)

スタイルに関するユニットテストはしないという選択をする場合、テスト時は vue ファイルのスタイルブロックを無視できるのではないかと考えました。

理由2: scss 変数を vue ファイルのスタイルブロックに自動挿入しているケースに対応できる

sass-loaderprependData という設定2で、 vue ファイルの各 <style lang="scss"> ブロック(scoped, module 付きを含む)の先頭部分に scss 変数等を自動挿入することができます。

Vue Loader のドキュメントでも紹介されている手法で、使われている方も多いかと思います。

vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      scss: {
        prependData: `$main-color: #333333;`
      }
    }
  }
}

テスト時のスタイルのコンパイルを止めない場合 jest.config.jsjest.globals['vue-jest'].resources.scssvue.config.jsprependData と近い設定ができるようですが、設定の重複管理は避けたいと思いました。

スタイルのコンパイルを止めることで、この問題を解決できました。

理由3: <style lang="scss" module> があると node-sass のインストールを求められる

テスト時のスタイルのコンパイルを止めない場合、 CSS Modules と scss を併用している vue ファイルのテストをしようとすると node-sass のインストールが必須となります:

sass(dart-sass)をインストールしている場合
 FAIL  tests/unit/example.spec.ts
  ● Test suite failed to run

    [vue-jest] Error: You are trying to use "scss". node-sass is missing.

    To install run:
    npm install --save-dev node-sass

上記のメッセージに従って node-sass をインストールすることでもこのエラーを回避できます。
しかし node-sass は OS 依存のバイナリを含んでいたり sass(dart-sass) と同じく scss をコンパイルする役割を持つパッケージのため、インストールは避けたいと思いました。

スタイルのコンパイルを止めることで、この問題を解決できました。

理由4: CSS Modules を使っていてもテンプレート上の $style.class_name で例外が発生しない

vue ファイルに <style module> ブロックがあると $style というオブジェクトが注入されテンプレート上で利用することになります。

単純に vue ファイルから <style module> ブロックを消すことを考えると、 $style のオブジェクトが注入されなくなってテンプレート上にある $style.class_name のようなプロパティへのアクセスで例外が発生しそうです。

ですが、紹介した設定ではテスト対象の vue ファイルに <style module> がある場合はブロック内の記述は無視しつつ $style = {} を注入してくれるため、上記のような例外は発生しないようになっています。


  1. vue-jestREADME.md のコミットログを追ったところ 2018/04/09 のコミットexperimentalCSSCompile に関する記述が追加されていました。2年以上経過していますが "experimental" は外れていないようです 

  2. sass-loader 7.x.x までは data で、 9.x.x からは additionalData となるようです。 additionalData は prepend だけでなく append もできるそうですが、 8.x.x の prependData と同じように使うことができました 

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1