Solucionado (ver solução)
Solucionado
(ver solução)
11
respostas

Unexpected Token

Ao tentar rodar o código de teste, recebi o seguinte erro:

FAIL  test/index.test.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    D:\Alura\Javascript\Node\lib-markdown\test\index.test.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { expect, test } from "@jest/globals";
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.481 s
Ran all test suites matching /.\\test/i.

Meu código está da seguinte forma:

index.test.js:

import { expect, test } from "@jest/globals";
import { pegaArquivos } from "../index";

test('deve ser uma função', () => {
    expect(typeOf(pegaArquivos())).toBe('function')
});

obs: eu alterei o nome para pegaArquivos, não está escrito errado.

package.json:

{
  "name": "lib-markdown",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest ./test",
    "cli": "node cli.js ./arquivos/texto1.md",
    "cli2": "node cli.js ./arquivos/"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "module",
  "dependencies": {
    "chalk": "^5.0.1",
    "node-fetch": "^3.2.3"
  },
  "devDependencies": {
    "jest": "^27.5.1"
  }
}

Tentei utilizar outras soluções que vi, mas sem sucesso. Alguém pode me ajudar, por favor?

11 respostas

Oi Gustavo!

Quando usamos módulos do EcmaScript para fazer o import/export, é necessário colocar a extensão .js nos arquivos. Por exemplo,

import { pegaArquivos } from "../index";

Deve ser:

import { pegaArquivos } from "../index.js";

Verifique também como você está fazendo as exportações dos arquivos no .index.js. Se estiver exportando apenas a função pegaArquivos, não é necessário desestruturar com {}.

Uma última coisa: o operador typeof é escrito dessa forma, tudo em minúsculo (confuso, eu sei). A forma typeOf não é reconhecida pelo JS.

Bons estudos! :)

solução!

Olá, Juliana!

Eu fiz as alterações, mas continuo com o mesmo erro:

import { expect, test } from "@jest/globals";
import pegaArquivos from "../index.js";

test('deve ser uma função', () => {
    expect(typeof pegaArquivos).toBe('function')
});
PS D:\Alura\Javascript\Node\lib-markdown> npm run test

> detect-links-md@1.0.0 test
> jest ./test

 FAIL  test/index.test.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    D:\Alura\Javascript\Node\lib-markdown\test\index.test.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { expect, test } from "@jest/globals";
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.519 s
Ran all test suites matching /.\\test/i.

Me parece que não estou conseguindo importar o jest, mas não sei o que fazer.

Fechei a dúvida sem querer, como desfaço?

Não tem problema. Se quiser passar o link do seu repositório, com o código completo fica mais fácil de ver o que está acontecendo!

Estou com a mesma dificuldade, o código está similar ao do Gustavo, sem a importação do JEST.

Estou com este mesmo problema e não consigo resolver.

Segue meu respositório git:

https://github.com/gmlessa/lib-markdown

Oi Gustavo e todo mundo que está com a mesma dúvida! Vamos lá.

A implementação da sintaxe ESM de importação/exportação (essa que usa import e export no lugar de module.exports e require) foi feita no NodeJS e, a partir daí, as libs que usamos com ele, por exemplo o Jest e o Chalk, têm que se adaptar e implementar o suporte ao ESM também.

O que acontece é que, no caso do Jest, essa implementação ainda está em caráter experimental na versão 27.5.1, o que está gerando alguns contratempos.

Você pode resolver essa questão dos testes da seguinte forma:

  1. No package.json, substitua a linha do script de testes por "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js ./test",. Isso vai adicionar uma "flag" para que o Jest use módulos de forma experimental (como explicado no link acima).
  2. No arquivo index.js, comente a linha onde você importa o chalk e delete do código a chamada para chalk.red(). A linha 19 fica dessa forma: throw new Error(erro.code, 'Não há arquivo no caminho');.

Com isso, os testes devem rodar normalmente.

Se você tentar somente o passo 1, sem deletar o Chalk do projeto, vai receber o erro Cannot find module '#ansi-styles' from 'node_modules/chalk/source/index.js'; por esse motivo é mais fácil deletar.

Esse problema do Jest com o Chalk não é um bug do projeto, mas sim do próprio Jest quando tentamos usar ESM ao invés da sintaxe anterior (CJS) de importação/exportação, como é possível conferir nesta issue e também nessa outra issue que foram abertas no repositório do Jest por users que tiveram problemas semelhantes em usar as duas bibliotecas juntas.

A integração de dependências é um assunto que dá pano pra manga no NodeJS justamente por causa desse tipo de problema ou "breaking changes" de bibliotecas que podem quebrar todo um código. Existem ferramentas como o dependabot que ajudam a contornar alguns desses problemas; você pode ler mais sobre o assunto nesse artigo.

Se ainda tiver algum outro erro ao rodar os testes, só falar. Bons estudos! :)

Problema resolvido por aqui, muito obrigado!

Agora sim! Tudo funcionou perfeitamente! Muito obrigada, Ju!

> detect-links-md@1.0.0 test
> node --experimental-vm-modules node_modules/jest/bin/jest.js ./test

(node:8760) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
 PASS  test/index.test.js
  √ deve ser uma função (5 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.222 s
Ran all test suites matching /.\\test/i.

Para quem quiser uma solução alternativa (que não sei se é a mais adequada, mas funcionou kkk), eu incluí na raiz do projeto um arquivo de configuração do Babel (babel.config.json) com um plugin para converter código ESM em CJS:

{
  "env": {
    "test": {
      "plugins": ["@babel/plugin-transform-modules-commonjs"]
    }
  }
}

Daí eu instalei esse plugin com o npm e isso resolveu para as importações de arquivos dentro do projeto. Para resolver a questão da lib Chalk, eu só instalei a versão 4.1.2, a última versão antes das versões 5.x.x. Ou seja, antes da lib ser do tipo ESM. Agora meus testes estão funcionando ok aqui.