SyntaxError: невозможно использовать оператор импорта вне модуля (@cucumber/cucumber) — Node.JS, Playwright и Cucumber

У меня возникает следующая ошибка, когда я пытаюсь скомпилировать свой код Node.js, совместимый с ECMAScript 6:

$ npx cucumber-js --require features/step_definitions/steps.ts --exit
 
import { Before, Given, When, Then } from "@cucumber/cucumber";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1029:16)
    at Module._compile (internal/modules/cjs/loader.js:1078:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
    at Module.load (internal/modules/cjs/loader.js:979:32)
    at Function.Module._load (internal/modules/cjs/loader.js:819:12)
    at Module.require (internal/modules/cjs/loader.js:1003:19)
    at require (internal/modules/cjs/helpers.js:107:18)
    at /Users/sam.levene/QA/playwright-automation/node_modules/@cucumber/cucumber/lib/api/support.js:18:32
    at Array.map (<anonymous>)
    at getSupportCodeLibrary (/Users/sam.levene/QA/playwright-automation/node_modules/@cucumber/cucumber/lib/api/support.js:18:18)

Вот мой код для анализа:

steps.ts

import { Before, Given, When, Then } from "@cucumber/cucumber";
import { Page, chromium } from "@playwright/test";
import { HomePage }  from "../../pages/HomePage";
import { SignInPage } from "../../pages/SignInPage";
import { SignInParameters } from "../../support/SignInParameters";

let homePage: HomePage;
let signInPage: SignInPage;
let signInParameters: SignInParameters;
let page: Page;

Before(async function() {
    var browser = await chromium.launch({
        headless: false,
    });
    var context = await browser.newContext();
    var page = await context.newPage();
    homePage = new HomePage(page);
    signInPage = new SignInPage(page);
    signInParameters = new SignInParameters();
});

(Step definition file. you get the gist.)

кажется, что ошибка говорит о том, что огурец-js не поддерживает импорт типов TypeScript? Но в своих модулях Npm я указываю последнюю версию Cucumber-js:

{
  "name": "playwright-poc",
  "version": "0.0.1",
  "description": "A Proof of Concept for Playwright",
  "scripts": {
    "test": "npx cucumber-js --require features/step_definitions/steps.ts --exit"
  },
  "type": "module",
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@playwright/test": "^1.31.2",
    "@cucumber/cucumber": "^9.0.1"
  }
}

РЕДАКТИРОВАТЬ Я попытался перейти по ссылке из @ParzhFromUkraine и получил следующую ошибку, отредактировав файл в .mjs:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/sam.levene/QA/playwright-automation/features/step_definitions/steps.mjs
    at new NodeError (internal/errors.js:322:7)
    at Module.load (internal/modules/cjs/loader.js:977:11)
    at Function.Module._load (internal/modules/cjs/loader.js:819:12)
    at Module.require (internal/modules/cjs/loader.js:1003:19)
    at require (internal/modules/cjs/helpers.js:107:18)
    at /Users/sam.levene/QA/playwright-automation/node_modules/@cucumber/cucumber/lib/api/support.js:18:32
    at Array.map (<anonymous>)
    at getSupportCodeLibrary (/Users/sam.levene/QA/playwright-automation/node_modules/@cucumber/cucumber/lib/api/support.js:18:18)
    at runCucumber (/Users/sam.levene/QA/playwright-automation/node_modules/@cucumber/cucumber/lib/api/run_cucumber.js:34:53)
    at async Cli.run (/Users/sam.levene/QA/playwright-automation/node_modules/@cucumber/cucumber/lib/cli/index.js:50:29)

Кто-нибудь может помочь с этим?

Взгляните на это: github.com/cucumber/cucumber-js/blob/main/docs/esm.md

Parzh from Ukraine 14.04.2023 13:14

@ParzhfromUkraine - спасибо за ссылку, которая, к сожалению, тоже вернула аналогичную ошибку: ``` Ошибка [ERR_REQUIRE_ESM]: необходимо использовать импорт для загрузки модуля ES: /Users/sam.levene/QA/playwright-automation/features/step_def‌ initions/steps.mjs ```

Raisus 14.04.2023 13:21

@ParzhfromUkraine - я отредактирую основной вопрос с попыткой получить полный журнал ошибок, когда попробую это

Raisus 14.04.2023 13:23

Это потому, что все import транспилируются в require

Parzh from Ukraine 14.04.2023 13:23

Итак, как мне заставить его работать? Должен ли я иметь какой-то пользовательский файл конфигурации?

Raisus 14.04.2023 13:28

Взгляните на эти вопросы: 1) stackoverflow.com/questions/61670459/… и 2) stackoverflow.com/questions/58384179/…. Кто-нибудь из них помогает?

Parzh from Ukraine 14.04.2023 13:35

Давайте продолжим обсуждение в чате.

Raisus 14.04.2023 13:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
271
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете решить это двумя способами -

  • Либо используйте require вместо прямого импорта модулей

нравиться

const { Given, When, Then } = require('@cucumber/cucumber');
  • Или добавьте это в package.json, чтобы он распознал, что тип является модулем.

В вашем package.json

{
   "type": "module"
}

Нет. Использование const заставляет систему жаловаться на другой импорт, в частности на мои локальные файлы .ts, которые следует экспортировать как модули (но жалоба считает, что это не так)

Raisus 14.04.2023 16:42

Кроме того, проверьте свой ответ, так как у меня уже настроен package.json как тип: модуль

Raisus 14.04.2023 16:42
Ответ принят как подходящий

С большими усилиями разработчиков Cucumber-js; Наконец-то я понял, чего мне не хватало, и как это исправить, поэтому теперь я предоставляю это здесь для дальнейшего использования, если у кого-то еще возникнут такие же проблемы.

Во-первых, мне не хватало файлов cucumber.js и tsconfig.json со следующей информацией:

cucumber.js

export default [
    "--import features/**/*.ts",
    "--publish-quiet"
].join(" ");
tsconfig.json

{
    "compilerOptions": {
      "allowJs": true,
      "baseUrl": ".",
      "forceConsistentCasingInFileNames": true,
      "module": "esnext",
      "moduleResolution": "nodenext",
      "noImplicitAny": true,
      "noImplicitReturns": true,
      "noImplicitThis": true,
      "noUnusedLocals": true,
      "sourceMap": true,
      "strictNullChecks": true,
      "esModuleInterop": true,
      "allowSyntheticDefaultImports": true,
      "target": "es6",
      "strict": true,
      "resolveJsonModule": true,
      "isolatedModules": true,
      "noEmit": true
    },
    "exclude": [
      "node_modules",
      ".idea",
      ".vscode"
    ],
    "include": [
      "features/**/*.ts",
    ]
  }

Поскольку это использует ES-Next; который является экспериментальным, мне также нужно было отредактировать package.json так, чтобы он ссылался на загрузчик ESM, а также установил ts-node:

package.json

{
  "name": "playwright-poc",
  "version": "0.0.2",
  "description": "A Proof of Concept for Playwright",
  "scripts": {
    "test": "NODE_OPTIONS=\"--loader ts-node/esm\" npx cucumber-js --parallel 10 --exit"
  },
  "type": "module",
  "keywords": [],
  "author": "Sam Levene",
  "license": "MIT",
  "devDependencies": {
    "@cucumber/cucumber": "^9.0.1",
    "@playwright/test": "^1.31.2",
    "ts-node": "^10.9.1"
  }
}

наконец, мне также пришлось отредактировать файл определения шагов, чтобы повторно сослаться на импорт, чтобы он правильно распознавал файлы:

steps.ts

import { Before, Given, When, Then } from "@cucumber/cucumber";
import { Page, chromium } from "@playwright/test";
import { HomePage }  from "../../pages/HomePage.js";
import { SignInPage } from "../../pages/SignInPage.js";
import { ForgotPasswordPage } from "../../pages/ForgotPasswordPage.js";
import { SignInParameters } from "../../support/SignInParameters.js";

let homePage: HomePage;
let signInPage: SignInPage;
let signInParameters: SignInParameters;
let forgotPasswordPage: ForgotPasswordPage;
let page: Page;

Before(async function() {
    var browser = await chromium.launch({
        headless: false,
    });
    var context = await browser.newContext();
    page = await context.newPage();
    homePage = new HomePage(page);
    signInPage = new SignInPage(page);
    forgotPasswordPage = new ForgotPasswordPage(page);
    signInParameters = new SignInParameters();
});

NB: несмотря на то, что в файле steps.ts указано, что импорт представляет собой .js файлы, они по-прежнему являются .ts файлами.

Другие вопросы по теме