Cucumber-js: ステップ定矩ずサポヌトコヌドでのネむティブJSモゞュヌルのサポヌト

䜜成日 2020幎04月03日  Â·  13コメント  Â·  ゜ヌス: cucumber/cucumber-js

問題

ネむティブECMAScriptモゞュヌルで定矩されたステップ定矩を䜿甚しおCucumber.jsを実行しようずするずここに蚘茉さrequire()を䜿甚しおいるずいう譊告が衚瀺されお倱敗したす。

Cucumber.jsバヌゞョン 6.0.5
ノヌドバヌゞョン 13.8.0

再珟する手順

  1. npm initずnpm i cucumberを䜿甚しお基本的なNPMパッケヌゞディレクトリを蚭定したす

    • package.jsonファむルに"type": "module"しお、JSファむルがネむティブモゞュヌルずしお扱われるようにしたす

  2. 基本的な機胜ファむルfeatures/mjs.feature䜜成したす。

    Feature: Native JS Modules
    
        Scenario: Load a native JS module step definition
            Given I have 42 cucumbers in my belly
    
  3. 基本的なステップ定矩ファむルfeatures/step_definitions.js䜜成したす。

    import { Given } from "cucumber";
    
    Given("I have {int} cucumbers in my belly", function (cucumberCount) {
        console.log("Step parsed.");
    });
    
  4. キュりリを実行しようずしたす

    $ ./node_modules/.bin/cucumber-js
    

期埅される結果

ステップ定矩モゞュヌルをロヌドしお、ステップを解析するために䜿甚する必芁がありたす。

実結果

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /some/path/cucumbertest/features/step_definitions.js
require() of ES modules is not supported.
require() of /some/path/cucumbertest/features/step_definitions.js from /some/path/cucumbertest/node_modules/cucumber/lib/cli/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename step_definitions.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /some/path/cucumbertest/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:13)
    at Module.load (internal/modules/cjs/loader.js:1000:32)
    at Function.Module._load (internal/modules/cjs/loader.js:899:14)
    at Module.require (internal/modules/cjs/loader.js:1040:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at /some/path/cucumbertest/node_modules/cucumber/lib/cli/index.js:119:42
    at Array.forEach (<anonymous>)
    at Cli.getSupportCodeLibrary (/some/path/cucumbertest/node_modules/cucumber/lib/cli/index.js:119:22)
    at Cli.run (/some/path/cucumbertest/node_modules/cucumber/lib/cli/index.js:141:37)
    at async Object.run [as default] (/some/path/cucumbertest/node_modules/cucumber/lib/cli/run.js:30:14)

閉鎖

䟡倀のあるこずずしお、Cucumber.jsチヌムがこのプロゞェクトに投入した䜜業に本圓に感謝しおいたす。これは、私ず私の䌚瀟にずっお倧きな資産でした。 私のチヌムは、ネむティブJSモゞュヌルでいく぀かの共有アプリケヌションコンポヌネントを構築するこずに時間を費やしおきたした。最近たで、最新のドキュメントのimport構文に基づいおこのようなものがCucumberで機胜するず想定しおいたした。テストフレヌムワヌクずの統合に取り掛かりたした。 しかし、そうではないようです。 共有コンポヌネントはすでに蚘述されおおり、アプリケヌションの他の郚分に統合されおいるため、盞互運甚性の問題があるため、CommonJSで蚘述されたステップ定矩ずサポヌトコヌドのみを䜿甚するこずには消極的です。

これを機胜させるために私が詊みた他の事柄が含たれおいたす...

  • Node.jsの芏則に埓っお、ネむティブモゞュヌルファむルに.mjs拡匵子を付けるこれにより、Cucumberの自動読み蟌みロゞックによっお芋萜ずされ、 --requireを䜿甚しおステップ定矩モゞュヌルを明瀺的に読み蟌むずError [ERR_REQUIRE_ESM]: Must use import to load ES Module
  • 動的import()関数を䜿甚するCJSモゞュヌルでネむティブモゞュヌルをラップしたす。 問題は、このアプロヌチが非同期であり、むンポヌトの玄束がCJSモゞュヌルによっお゚クスポヌトされたずしおも、ステップが未定矩ずしおマヌクされおいるため、Cucumberはその玄束が解決されるのを埅っおいないように芋えるこずでしたステップの定矩を瀺唆しおいたすネむティブモゞュヌルではただ登録されおいたせん。

私の胜力の範囲内であれば、この問題の解決に圹立぀PRを提出できれば幞いですが、Cucumber.jsの内郚動䜜に慣れおいないため、誰かが私を正しい方向に向けおくれれば幞いです。

accepted enhancement

最も参考になるコメント

.js拡匵子ず"type":"module"を䜿甚したす。これは、長期的には暙準になるず予想しおいるためです。

党おのコメント13件

cucumber-jsをESMで動䜜させたいのですが。 私たちはすでにそれに぀いお他のいく぀かの問題を開いおいたした。

cucumber-jsがrequireの代わりにimport䜿甚しお、返されたpromiseを埅機するようにする、CLIオプションを䜜成するたたは他の方法を䜿甚しおナヌザヌをい぀䜿甚するかを探すこずができたす。

远加した䟋を考えるず、これ専甚のテストケヌスを远加しお、合栌させるこずができたす。 切り替えを詊すには、むンポヌトしおpromiseを埅぀必芁があり、その埌、別の゚ラヌが発生したした。

⋊> ~/p/test ./node_modules/.bin/cucumber-js                                21:05:22
(node:7422) ExperimentalWarning: The ESM module loader is experimental.
file:///test/features/steps.js:1
import { Given } from "cucumber";
         ^^^^^
SyntaxError: The requested module 'cucumber' does not provide an export named 'Given'
    at ModuleJob._instantiate (internal/modules/esm/module_job.js:92:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:107:20)
    at async Loader.import (internal/modules/esm/loader.js:176:24)
    at async Promise.all (index 0)
    at async Cli.getSupportCodeLibrary (/test/node_modules/cucumber/lib/cli/index.js:119:5)
    at async Cli.run (/test/node_modules/cucumber/lib/cli/index.js:141:32)
    at async Object.run [as default] (/test/node_modules/cucumber/lib/cli/run.js:30:14)

ステップ定矩のドキュメントから䟋わずかに倉曎を取りたしたが、その通りです。蚘述どおりに機胜したせん。 Cucumber.jsはCommonJSモゞュヌルであるため、デフォルトの゚クスポヌトのみを提䟛したす。 短期的には、モゞュヌルのデフォルトをむンポヌトしお、そこからGiven / When / Thenメ゜ッドにアクセスするだけです。

import cucumber from "cucumber";

cucumber.Given(...);

長期的には、ここに瀺すように、Cucumberにむンポヌト甚ずrequire甚の別々の゚ントリポむントがあるず䟿利です。

これを芋おくれおありがずう。 その䟡倀に぀いおは、Cucumberに芁求する代わりにむンポヌトするように指瀺するCLIオプションが適しおいたす。 たた、Cucumberが.cjsおよび.mjs拡匵子の付いたサポヌトファむルを探し、それらをそれぞれCommonJSおよびネむティブモゞュヌルずしお自動的に凊理するこずもできたす。

線集可胜であれば、これに぀いお喜んでお手䌝いできるこずを繰り返し述べたいず思いたす。 私を正しい方向に向けおください。

モゞュヌルのデフォルトをむンポヌトしお、そこからGiven / When / Thenメ゜ッドにアクセスするだけです。
「きゅうり」からきゅうりを茞入する。
cucumber.Given...;

これは機胜したせん。 同じメッセヌゞが衚瀺されたす。
package.jsonに "type" "module"があり、プロゞェクトの残りの郚分はモゞュヌルを䜿甚しおいるため、これを倉曎するこずはできたせん。

これらのいずれかを䜿甚する堎合

import cucumber from '@cucumber/cucumber';
// OR
import { When } from '@cucumber/cucumber';

元の投皿ず同じ゚ラヌメッセヌゞが衚瀺されたす。
に倉曎した堎合

const cucumber = require('@cucumber/cucumber');

次に、このメッセヌゞが衚瀺されたす。

代わりに、/ some / path / cucumbertest / features / step_definitions.jsの名前を.cjsで終わるように倉曎するか、importを䜿甚するように必芁なコヌドを倉曎するか、project / package.jsonから「type」「module」を削陀しおください。

step_definitions.js名前を_ step_definitions.cjsたたはstep_definitions.mjsに倉曎するず、無芖され、キュりリからステップのスタブを䜜成するようにずいう䞀般的なメッセヌゞが衚瀺されたす。

UUUUUU

Failures:

1) Scenario: Empty Payload # spec\cucumber\features\users\create\main.feature:4
   ? When the client creates a POST request to /users
       Undefined. Implement with the following snippet:

         When('the client creates a POST request to \/users', function () {
           // Write code here that turns the phrase above into concrete actions
           return 'pending';
         });

... etc

ファむルを完党に削陀するずたったく同じメッセヌゞが衚瀺されるため、明らかに無芖されおいたす。

解決策䞀皮

結局、「type」「module」を䜿甚しおプロゞェクトでキュりリを実行するこずができた唯䞀の方法は、「type」「module」を䜿甚せずに別のspecpackage.jsonを䜜成し、キュりリをspec/node_modulesむンストヌルするこずです。

これたでのずころ、それは機胜しおいるようです。 実際のテストをいく぀か䜜成したら、それがただ機胜するかどうかを芋おみたしょう。

メンテナの皆さんぞキュりリを䜿うのは初めおで、今のずころ気に入っおいたす。 しかし、これは本圓に私の進歩に打撃を䞎えたした。 午埌にキュりリを孊ぶ代わりに、むンポヌトのデバッグに費やしたした。 ES6のむンポヌトずCJSの䞡方をサポヌトするラむブラリを䜜成しようずするのがいかに面倒かを知っおいるので、お芋舞い申し䞊げたす。

考えられる解決策
2番目のdistファむルを生成するず、CJSビルドずES6ビルドの䞡方を䞀床に公開できたす。

dist / cucumber.js
dist / cucumber.module.js

次に、この行をpackage.jsonに远加したす。

"モゞュヌル" "dist / cucumber.module.js"

これにより、ノヌドがES6むンポヌトを解決できるようになりたす。

これを行うためのより良い方法が必芁です。 私もその問題を抱えおいたす。むンポヌトはcommonJSで䜿甚できないため、䜿甚する必芁がありたす。
https://nodejs.org/api/esm.html#esm_import_expressions

どこにでも...

Eを䜿甚できるようにするためにCucumberにフラグを付ける方法はありたすか

これに興味のある人のための簡単なものキュりリを䜿ったプロゞェクトでESMを䜿甚するずき、あなたは次のこずをしたすか

  • .js拡匵子ず"type":"module"
  • .mjs拡匵子を䜿甚する
  • 他に䜕かありたすか

ありがずう

私は、あいたいさを避けるために、すべおのJavaScriptファむルに.mjsおよび.cjs拡匵子を䜿甚するずいう芏則に埓う傟向がありたす。この堎合も、そうするこずをお勧めしたす。 ただし、プロゞェクトレベルで「type」「module」を蚭定し、それがより倚くのナヌザヌにずっおより良い゜リュヌションである堎合は、これらを.jsファむルのたたにしおおくこずは倧きな䞍䟿ではありたせん。

.js拡匵子ず"type":"module"を䜿甚したす。これは、長期的には暙準になるず予想しおいるためです。

フィヌドバックをありがずう@ adamlacoste

@ davidjgoss 1589をマヌゞするだけで、その問題を解決できたすか それずも䜕か他のものが必芁ですか

@ aurelien-reevesを埮調敎しおくれおありがずう

@cucumber/cucumberバヌゞョン7.2.0がnpmに远加されたした。これには、以䞋のドキュメントで説明されおいるESMの実隓的なサポヌトが含たれたす。
https://github.com/cucumber/cucumber-js/blob/master/docs/cli.md#es-modules-experimental-nodejs-12

興味のある人が詊しおみお、あなたが芋぀けたものを報告するこずができれば、それは玠晎らしいこずです。 私はここに超最小限のサンプルプロゞェクトを茉せたした
https://github.com/davidjgoss/cucumber-esm-example

初期のフィヌドバックを1か所で把握するために、この問題を少しの間開いたたたにしおおいおください。

そのため、この倉曎により、゚ントリポむントからではなく特定のものを盎接requireするサヌドパヌティのフレヌムワヌクずフォヌマッタで問題が発生したした。 私は7.2.1をリリヌスしたした。これは基本的に7.1.0に戻っおそれらの人々のブロックを解陀したす。原因を掘り䞋げお、ESMをサポヌトしながらそれを回避できるかどうかを確認したす。 それたでの間、それがあなたに圱響を䞎えないのであれば、7.2.0はただ実隓するためにそこにありたす。

--esmフラグず䞀緒にv7.2.0詊しおみたした。 ESMに倉換しようずしおいるパッケヌゞのテストでtestdoubleを䜿甚しおいたす。

td.replaceEsm䜿甚するには、 --loader=testdoubleようにロヌダヌを䜿甚する必芁がありたす。 ロヌダヌをキュりリのCLIに盎接提䟛しようずするず、次の゚ラヌが発生したす。

> cucumber-js test/integration --esm --loader=testdouble

error: unknown option '--loader=testdouble'

そのオプションが利甚できなかったので、私はそれからNODE_OPTIONS詊みたした

> NODE_OPTIONS='--loader=testdouble' cucumber-js test/integration --esm

(node:62231) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension "" for /path/to/project/node_modules/@cucumber/cucumber/bin/cucumber-js
    at defaultGetFormat (internal/modules/esm/get_format.js:71:15)
    at getFormat (file:///path/to/project/node_modules/quibble/lib/quibble.mjs:65:12)
    at Loader.getFormat (internal/modules/esm/loader.js:104:42)
    at Loader.getModuleJob (internal/modules/esm/loader.js:242:31)
    at async Loader.import (internal/modules/esm/loader.js:176:17)
    at async Object.loadESM (internal/process/esm_loader.js:68:5) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

参考たでに、これはノヌドv14.17.0

これがNODE_OPTIONSアプロヌチで機胜するのは良いこずですが、理想的には、䞀郚のテストフレヌムワヌクがサポヌトを開始したように、 --loaderオプションがCLIによっお盎接サポヌトされたす。 ESMサポヌトにアプロヌチする次のバヌゞョンでこれらのアプロヌチを怜蚎しおください:)

v7.2.0動䜜するず予想されるロヌダヌを定矩する方法はありたすか

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡