κΈ°λ³Έ ECMAScript λͺ¨λμ μ μλ λ¨κ³ μ μλ‘ Cucumber.jsλ₯Ό μ€ννλ €κ³ νλ©΄( μ¬κΈ° μ μ€λͺ
λ λλ‘) ES λͺ¨λμμ CommonJSμ require()
λ₯Ό μ¬μ©νκ³ μλ€λ κ²½κ³ μ ν¨κ» μλκ° μ€ν¨ν©λλ€.
Cucumber.js λ²μ : 6.0.5
λ
Έλ λ²μ : 13.8.0
npm init
λ° npm i cucumber
μ¬μ©νμ¬ κΈ°λ³Έ NPM ν¨ν€μ§ λλ ν 리 μ€μ package.json
νμΌμ "type": "module"
λ₯Ό μ€μ νμ¬ JS νμΌμ΄ κΈ°λ³Έ λͺ¨λλ‘ μ²λ¦¬λλλ‘ ν©λλ€.κΈ°λ³Έ κΈ°λ₯ νμΌ features/mjs.feature
:
Feature: Native JS Modules
Scenario: Load a native JS module step definition
Given I have 42 cucumbers in my belly
κΈ°λ³Έ λ¨κ³ μ μ νμΌ features/step_definitions.js
:
import { Given } from "cucumber";
Given("I have {int} cucumbers in my belly", function (cucumberCount) {
console.log("Step parsed.");
});
Cucumber μ€ν μλ:
$ ./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λ‘ μμ±λ λ¨κ³ μ μ λ° μ§μ μ½λλ§ μ¬μ©νλ κ²μ 꺼립λλ€.
μ΄ μμ μ μννλ €κ³ μλν λ€λ₯Έ κ²λ€μ΄ ν¬ν¨λμμ΅λλ€ ...
.mjs
νμ₯μλ₯Ό μ 곡ν©λλ€(μ΄λ‘ μΈν΄ Cucumberμ μλ λ‘λ λ
Όλ¦¬μμ κ°κ³Όλκ³ --require
λ₯Ό μ¬μ©νμ¬ λ¨κ³ μ μ λͺ¨λμ λͺ
μμ μΌλ‘ λ‘λνλ©΄ Error [ERR_REQUIRE_ESM]: Must use import to load ES Module
import()
ν¨μλ₯Ό μ¬μ©νλ CJS λͺ¨λμ κΈ°λ³Έ λͺ¨λ λν; λ¬Έμ λ μ΄ μ κ·Ό λ°©μμ΄ λΉλκΈ°μμ΄λ©° CJS λͺ¨λμμ κ°μ Έμ€κΈ° μ½μμ λ΄λ³΄λΈ κ²½μ°μλ Cucumberλ ν΄λΉ λ¨κ³κ° μ μλμ§ μμ κ²μΌλ‘ νμλκΈ° λλ¬Έμ κ³μ μ§ννκΈ° μ μ ν΄λΉ μ½μμ΄ ν΄κ²°λ λκΉμ§ κΈ°λ€λ¦¬μ§ μλ κ²μΌλ‘ 보μ
λλ€(λ¨κ³ μ μκ° λ€μ΄ν°λΈ λͺ¨λμ μμ§ λ±λ‘λμ§ μμμ΅λλ€).μ λ₯λ ₯ λ²μ λ΄μμ μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ° λμμ΄ λλλ‘ PRμ μ μΆνκ³ μΆμ§λ§ Cucumber.jsμ λ΄λΆ μλμ μ΅μνμ§ μμΌλ―λ‘ λκ΅°κ° μ λ₯Ό μ¬λ°λ₯Έ λ°©ν₯μΌλ‘ μλ΄ν΄ μ£Όμλ©΄ κ°μ¬νκ² μ΅λλ€.
μ€μ΄-jsκ° ESMκ³Ό ν¨κ» μλνλλ‘ νκ³ μΆμ΅λλ€. μ°λ¦¬λ μ΄λ―Έ κ·Έκ²μ λν΄ λͺ κ°μ§ λ€λ₯Έ λ¬Έμ λ₯Ό μ΄μμ΅λλ€.
μ€μ΄-jsκ° λ°νλ μ½μμ μꡬνκ³ κΈ°λ€λ¦¬μ§ μκ³ import
λ₯Ό μ¬μ©νλλ‘ νλ CLI μ΅μ
μ λ§λ€ μ μμ΅λλ€.
μΆκ°ν μμ κ° μ£Όμ΄μ§λ©΄ μ΄μ λν ν μ€νΈ μΌμ΄μ€λ₯Ό μΆκ°νκ³ ν΅κ³Όν μ μλλ‘ μμ ν μ μμ΅λλ€. μ νμ μ€ννλ €λ©΄ μ½μμ κ°μ Έμμ κΈ°λ€λ €μΌ νκ³ λ€λ₯Έ μ€λ₯κ° λ°μνμ΅λλ€.
β> ~/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(...);
μ₯κΈ°μ μΌλ‘ μ€μ΄μ μ¬κΈ°μ νμλ κ²μ²λΌ import λ° requireμ λν λ³λμ μ§μ μ μ΄ μμΌλ©΄ μ’μ κ²μ λλ€.
λ΄μ£Όμ μ κ°μ¬ν©λλ€. κ·Έλ§ν κ°μΉκ° μκΈ° λλ¬Έμ Cucumberμκ² μꡬνλ λμ κ°μ Έ μ€λλ‘ μ§μνλ CLI μ΅μ μ΄ μ μκ² μ ν©ν©λλ€. Cucumberκ° νμ₯μκ° .cjs λ° .mjsμΈ μ§μ νμΌμ μ°Ύκ³ μ΄λ₯Ό κ°κ° CommonJS λ° κΈ°λ³Έ λͺ¨λλ‘ μλ μ²λ¦¬νλ κ²½μ°μλ μ’μ κ²μ λλ€.
νΈμ§: ν μλ§ μλ€λ©΄ κΈ°κΊΌμ΄ λμλ릴 μ μλ€λ μ μ λ€μ ν λ² λ§μλλ¦¬κ³ μΆμ΅λλ€. μ¬λ°λ₯Έ λ°©ν₯μΌλ‘ λλ₯Ό κ°λ¦¬μΌ μ£Όμμμ€.
λλ μλ§λ λͺ¨λ κΈ°λ³Έκ°μ κ°μ Έμ¨ λ€μ κ·Έλ‘λΆν° Given/When/Then λ©μλμ μ‘μΈμ€ν κ²μ λλ€.
"μ€μ΄"μμ μ€μ΄ μμ ;
μ€μ΄.μ£Όμ΄μ§(...);
μλνμ§ μμ΅λλ€. κ°μ λ©μμ§κ° λνλ©λλ€.
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
μ _either_ 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λ₯Ό λͺ¨λ μ§μνλ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ§λλ κ²μ΄ μΌλ§λ μ±κ°μ μΌμΈμ§ μλλ€.
κ°λ₯ν μ루μ
:
λ λ²μ§Έ dist νμΌμ μμ±νλ©΄ CJS λ° ES6 λΉλλ₯Ό λμμ κ²μν μ μμ΅λλ€.
dist/cucumber.js
dist/cucumber.module.js
κ·Έλ° λ€μ package.jsonμ λ€μ μ€μ μΆκ°ν©λλ€.
"λͺ¨λ": "dist/cucumber.module.js"
μ΄λ κ² νλ©΄ λ Έλκ° ES6 κ°μ Έμ€κΈ°λ₯Ό ν΄κ²°ν μ μμ΅λλ€.
μ΄ μμ
μ μννλ λ λμ λ°©λ²μ΄ μμ΄μΌ ν©λλ€. λλ κ·Έ λ¬Έμ κ° μκ³ importsλ commonJSμ ν¨κ» μ¬μ©ν μ μκΈ° λλ¬Έμ μ¬μ©ν΄μΌ ν κ²μ
λλ€.
https://nodejs.org/api/esm.html#esm_import_expressions
μ΄λμλ...
Cucumberκ° ESλ₯Ό μ¬μ©νλ λ° λμμ΄ λλ νλκ·Έλ₯Ό κ°μ§ μ μλ λ°©λ²μ΄ μμ΅λκΉ?
μ΄μ κ΄μ¬μ΄ μλ μ¬λλ€μ μν λΉ λ₯Έ μ 보: μ€μ΄κ° μλ νλ‘μ νΈμμ ESMμ μ¬μ©ν λ λ€μμ μννμκ² μ΅λκΉ?
.js
νμ₯ λ° "type":"module"
.mjs
νμ₯ μ¬μ©κ°μ¬ ν΄μ!
λͺ¨νΈμ±μ νΌνκΈ° μν΄ λͺ¨λ JavaScript νμΌμ .mjs λ° .cjs νμ₯μλ₯Ό μ¬μ©νλ κ·μΉμ λ°λ₯΄λ κ²½ν₯μ΄ μμΌλ©° μ΄ κ²½μ°μλ κ·Έλ κ² νλ κ²μ΄ μ’μ΅λλ€. κ·Έλ¬λ νλ‘μ νΈ μμ€μμ "type": "module"μ μ€μ νκ³ λ λ§μ μ¬μ©μμκ² λ λμ μ루μ μΈ κ²½μ° .js νμΌλ‘ λ¨κ²¨λλ κ²μ ν° λΆνΈμ΄ μμ κ²μ λλ€.
λλ μ΄κ²μ΄ μ₯κΈ°μ μΌλ‘ νμ€μ΄ λ κ²μΌλ‘ μμνκΈ° λλ¬Έμ .js
νμ₯κ³Ό "type":"module"
μ¬μ©ν©λλ€.
νΌλλ°±μ κ°μ¬λ립λλ€ @adamlacoste @looeee
@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
ν κ³³μμ μ΄κΈ° νΌλλ°±μ λ°κΈ° μν΄ μ΄ λ¬Έμ λ₯Ό μ μ μ΄μ΄ λκ² λμ΄ κΈ°μ©λλ€.
λ°λΌμ μ΄ λ³κ²½μΌλ‘ μΈν΄ νΉμ νλͺ©μ μ§μ require
νλ νμ¬ νλ μμν¬ λ° ν¬λ§·ν°μ λ¬Έμ κ° λ°μνμ΅λλ€(μ§μ
μ§μ κ³Ό λ°λ). κΈ°λ³Έμ μΌλ‘ 7.1.0μΌλ‘ λλ리λ 7.2.1μ μΆμνμ¬ ν΄λΉ μ¬μ©μμ μ°¨λ¨μ ν΄μ νμ΅λλ€. μμΈμ νκ³ λ€μ΄ 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
λ‘ μμ
ν κ²μΌλ‘ μμλλ λ‘λλ₯Ό μ μνλ λ°©λ²μ΄ μμ΅λκΉ?
κ°μ₯ μ μ©ν λκΈ
λλ μ΄κ²μ΄ μ₯κΈ°μ μΌλ‘ νμ€μ΄ λ κ²μΌλ‘ μμνκΈ° λλ¬Έμ
.js
νμ₯κ³Ό"type":"module"
μ¬μ©ν©λλ€.