Jest: JestはCSSをインポートするJSXでは動作しません

作成日 2017年03月07日  ·  24コメント  ·  ソース: facebook/jest

機能をリクエストしますか、それともバグを報告しますか?
バグ

現在の動作は何ですか?
app.jsximport './app.css';があり、テストを実行できない場合、次のエラーが発生します。

yarn run:test v0.21.3
$ NODE_ENV=client jest -u
 FAIL  src/__tests__/app.test.js
  ● Test suite failed to run

    /home/svipben/Documents/react-boilerplate/src/client/app/app.css:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){body {
                                                                                                  ^
    SyntaxError: Unexpected token {

      at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:320:12)
      at Object.<anonymous> (src/client/app/app.jsx:7:1)
      at Object.<anonymous> (src/__tests__/app.test.js:2:12)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.693s
Ran all test suites.
error Command failed with exit code 1.

期待される動作は何ですか?
エラーなしでテストを実行するには...

正確なJest構成を提供し、Jest、ノード、yarn / npmバージョン、およびオペレーティングシステムについて言及してください。

OS:Linux Ubuntu 16.04
ジェスト:最新
糸:最新
ノード:最新
babel-jest :最新

.babelrc:

        "client": {
            "presets": [
                "latest", // All you need to compile what's in ES2015+
                "flow", // Flow support
                "react", // Strip flow types and transform JSX
                "stage-2" // Experimental syntax extensions
            ],
            "sourceMaps": true // Compile with Source Maps
        },

jest: NODE_ENV = client jest -u

PS import './app.css';にコメント/削除すると、すべてがうまく機能します

最も参考になるコメント

package.jsonファイルのjest構成でmoduleNameMapperキーを使用してこれを解決しました

{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

この後、以下に説明するように2つのファイルを作成する必要があります

  • __mocks__/styleMock.js
module.exports = {};
  • __mocks__/fileMock.js
module.exports = 'test-file-stub';

CSSモジュールを使用している場合は、プロキシをモックしてclassNameルックアップを有効にすることをお勧めします。
したがって、構成は次のように変更されます。

{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

ただし、開発依存関係としてidentity-obj-proxyパッケージをインストールする必要があります。

yarn add identity-obj-proxy -D

詳細については。 あなたはjestドキュメントを参照することができます

全てのコメント24件

@maximderbinありがとう!

@maximderbinありがとうございます! moduleNameMapperを追加することで、私の問題を解決します

@svipben @maximderbin @simonxlこのmoduleNameMapperをどこに追加する必要がありますか?
ドキュメントでpackag.jsonに追加することがわかりましたが、どれを追加しますか?
tnx

@sarahmarciano moduleNameMapperは構成の一部です。 デフォルトでは、次のように、package.json(依存関係にjestを備えているもの)の「jest」キーで構成を設定できます。

{
  "dependencies": {...}
  "jest": {
    "moduleNameMapper": {...}
  }
}

package.jsonファイルのjest構成でmoduleNameMapperキーを使用してこれを解決しました

{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

この後、以下に説明するように2つのファイルを作成する必要があります

  • __mocks__/styleMock.js
module.exports = {};
  • __mocks__/fileMock.js
module.exports = 'test-file-stub';

CSSモジュールを使用している場合は、プロキシをモックしてclassNameルックアップを有効にすることをお勧めします。
したがって、構成は次のように変更されます。

{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

ただし、開発依存関係としてidentity-obj-proxyパッケージをインストールする必要があります。

yarn add identity-obj-proxy -D

詳細については。 あなたはjestドキュメントを参照することができます

CSSモジュールがJSXファイルが依存する値をエクスポートする場合、ここで推奨されるアプローチは機能しないことに注意してください。 ほとんどのガイドは、クラス名をエクスポートするためにCSSモジュールのみを使用していることを前提としています。 CSSモジュールを適切にモックするためのガイドがあればいいのにと思います。

@ matthew-dean「CSSモジュールを適切にモックする」とはどういう意味ですか? ユースケースについてもう少し説明していただけますか? 私はidentity-obj-proxyを使った素晴らしい経験があります

:export {
  sizeMobile: $size-mobile / 1px;
  sizePhablet: $size-phablet / 1px;
  sizeSmallTablet: $size-small-tablet / 1px;
  sizeTablet: $size-tablet / 1px;
  sizeDesktop: $size-desktop / 1px;
  sizeLargeDesktop: $size-large-desktop / 1px;
}
import styles from './variables.scss'

const tileSize = parseFloat(styles.sizeTablet) / 3
//...
render() {
  return <Tile style={{width: tileSize}} />
}

これは不自然な例であり、CSSモジュールとJSの間で定数(値)を共有でき、値に基づいて条件付きレンダリングまたは動的プロップを割り当てることができることを示しています。

ただし、 identity-obj-proxyを使用すると、これらの値を整数にキャストすることはできません。実際に存在する値は言うまでもありません。 したがって、CSSモジュールで定義された定数に依存するJSXコードがある場合、CSSモジュールを適切にモックすることなくこれをテストすることはできません(テスト可能な整数として値を持つオブジェクトが返されます)。 identity-obj-proxyは、CSSモジュールにスコープ付きCSSクラス名以外のオブジェクトが含まれていないことのみを前提としています。 CSSモジュールの他の側面、つまりJS操作で使用される値/定数をエクスポートする機能はサポートされていません。

@SimenB

ちなみに、私は次のようにCSSモジュールを正常にモックすることができました。

const styles = require('styles/variables.scss')

jest.mock('styles/variables.scss', () => {
  return {
    sizePhablet: 500,
    sizeSmallTablet: 768,
    sizeTablet: 1024,
    sizeDesktop: 1440,
    sizeLargeDesktop: 1920
  }
})

うまくいけば、CSSモジュールのすべての機能を使用していて、私のように、デフォルトの「 identity-obj-proxyを使用するだけ」のアドバイスで髪を引き裂いていた他の人に役立つことを願っています。

'jest-transform-css'を使用してこの問題を解決しました。
インストール後、jest構成に以下を追加しました。

"transform": {
      "^.+\\.js$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss)$": "jest-transform-css"
    }

これで、cssファイルはjsファイルと同じようにトランスパイルされます。

@ matthew-deanどこでCSSモジュールのモックを作成し、それをどのようにjestに参照しますか?

私は外部パッケージを使用しており、以下を使用して独自のファイルを単一のファイルにインポートします。
<strong i="6">@import</strong> "progress-tracker/progress-tracker-variables.scss";

テストを開始するためにJestを実行するときはいつでも
image
上記のエラーが表示されます。 package.json内でcssモックアップをすでに指定しています
image

その問題について助けを得るのを楽しみにしています。 トリック、提案はありますか?

編集:私はbabel-jestパッケージとidentity-obj-proxyパッケージの両方を試しましたが、どれも機能しませんでした。 問題はまだ解決していません。

編集2:また、私はWebで出くわした解決策に従って、以下の構成を試しました。
image

私はBabel 7 、babel-jest ^24.5.0 、Jest ^24.1.0使用しています。

上記のアドバイスに従った後、ターゲットファイル(例: Post.js )のときに関数またはオブジェクトをJestテストファイル(例: Post.test.js )にimportしようとすると、まだこのエラーが発生しますPost.js )はCSSファイルをインポートします-例: ./postStyles.css

Jest encountered an unexpected token

SyntaxError: Unexpected token .

Details:

    /Users/ben/Desktop/Work/code/bengrunfeld/src/front-end/components/Post/postStyles.css:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.post h1, .post h2, .post h3 {

      3 |
      4 | import { PostText } from './styles'
    > 5 | import './postStyles.css'

上にリンクされた記事によると、これは私のpackage.jsonあります:

"jest": {
    "moduleFileExtensions": ["js", "jsx"],
    "moduleDirectories": ["node_modules", "bower_components", "shared"],

    "moduleNameMapper": {
      "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
      "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js",

      "^react(.*)$": "<rootDir>/vendor/react-master$1",
      "^config$": "<rootDir>/configs/app-config.js"
    }
  },

ルートディレクトリには、次のコードを持つ__mocks__/styleMock.jsがあります。

module.exports = {};

最後に、私のjest.config.js

module.exports = {
  setupFiles: ['<rootDir>/src/test/setup.js']
}

これにより、酵素が構成されます。

import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

Enzyme.configure({ adapter: new Adapter() })

import Error
scssファイルに@importステートメントが含まれているのとほぼ同じ問題を解決するのに苦労しています。 SyntaxError:無効または予期しないトークンを通知してテストが失敗します。 誰か助けてくれませんか?

私は上記の解決策に従いましたが、どれも私のために働いていないようです

@babel/polyfillを開発依存関係として追加することでこれを解決できました

ここも同じ@fthomas82

package.jsonファイルのjest構成でmoduleNameMapperキーを使用してこれを解決しました

{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

この後、以下に説明するように2つのファイルを作成する必要があります

  • __mocks__/styleMock.js
module.exports = {};
  • __mocks__/fileMock.js
module.exports = 'test-file-stub';

CSSモジュールを使用している場合は、プロキシをモックしてclassNameルックアップを有効にすることをお勧めします。
したがって、構成は次のように変更されます。

{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

ただし、開発依存関係としてidentity-obj-proxyパッケージをインストールする必要があります。

yarn add identity-obj-proxy -D

詳細については。 あなたはjestドキュメントを参照することができます

それは私のために働いた。 ありがとう!!!

'jest-transform-css'を使用してこの問題を解決しました。
インストール後、jest構成に以下を追加しました。

"transform": {
      "^.+\\.js$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss)$": "jest-transform-css"
    }

これで、cssファイルはjsファイルと同じようにトランスパイルされます。

ありがとう、仲間@krajasekhar
それは私のために働きます👍

提案された構成をpackages.jsonに追加しましたが、成功しませんでした。プロジェクトのルートディレクトリにjest.config.jsがあることに気付きました。Jestはその構成ファイルをpackages.jsonで使用しています。

参考までに、私のjest.config.jsファイルを次に示します。

module.exports = {
  setupFilesAfterEnv: ['<rootDir>/.setup-tests.js'],
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css',
  },
};

コードに生のCSSをインポートする必要があります

import "./cloud.css?raw"

jestconfigも変更しました
"jest":{ "moduleNameMapper": { "\\.(css|less|scss|sass|css?raw)$": "identity-obj-proxy" },

それでも、インポート行でテストエラーが発生します。 生のインポートをモックする方法はありますか?

@import Unexpected token=:)の解決策

パッケージのインストール:
npm i --save-dev identity-obj-proxy

jest.config.jsに追加します

module.exports = {
  "moduleNameMapper": {
    "\\.(css|less|scss)$": "identity-obj-proxy"
  }
}

誰かがここに到着した場合:
このモジュールは私が見た中で最も更新されています: https ://www.npmjs.com/package/jest-css-modules-transform

transform: { '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest', ".+\\.(css|styl|less|sass|scss)$": "jest-css-modules-transform" }, transformIgnorePatterns: [ '/node_modules/', '^.+\\.module\\.(css|sass|scss)$', ], moduleNameMapper: { '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy' },

提案された構成をpackages.jsonに追加しましたが、成功しませんでした。プロジェクトのルートディレクトリにjest.config.jsがあることに気付きました。Jestはその構成ファイルをpackages.jsonで使用しています。

参考までに、私のjest.config.jsファイルを次に示します。

module.exports = {
  setupFilesAfterEnv: ['<rootDir>/.setup-tests.js'],
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css',
  },
};

解決策を提示してくれたすべての人、特に@Shadoowに感謝します! それは一種の論理的なものでしたが、私はそれを見逃していました...configファイルがpackage.jsonの設定で使用されます

要するに、新参者にとって、私に役立ったのは、私たちのコミュニティドリームチームによって提示された複数のソリューションの結合でした。

1)jest.config.jsonファイルを作成します

touch jest.config.json open jest.config.json

2)jest-transform-cssをインストールします。

yarn add jest-transform-css -D

3)これはあなたのjest設定ファイルがどのように見えるべきかです:

module.exports = {
  preset: 'ts-jest/presets/js-with-babel',
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)$': './jest.mock.js',
  },
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/assets/'],
  transform: {
    '^.+\\.jsx?$': 'babel-jest',
    '\\.(css|less|scss|sass)$': 'jest-transform-css',
  },
};

4)package.jsonを更新します(最初に、すべてのJEST構成があれば、新しいjest構成ファイルに転送します)。次に、魔法がここにあります。

"test": "jest --config ./jest.config.js"

Tksみんな!

このページは役に立ちましたか?
0 / 5 - 0 評価