Jest: Suporte para RequireJS

Criado em 15 mai. 2014  ·  84Comentários  ·  Fonte: facebook/jest

Se entendi corretamente, atualmente não há como usar isso com o RequireJS em vez do estilo CommonJS require(). Existem planos de adicionar suporte para RequireJS? É mesmo viável?

Comentários muito úteis

babel-plugin-transform-amd-to-commonjs pode ser útil para resolver o problema de Jest+AMD, especialmente se você já estiver usando algo como babel-jest.

Configurei um projeto de exemplo que mostra como você pode fazer com que o Jest exija arquivos AMD de forma transparente executando a transformação no ambiente de teste.

Não tenho certeza dos detalhes de tal abordagem em um projeto real - em particular uma boa abordagem para compartilhamento de configuração entre Jest/RequireJS/Webpack/etc. O suporte do Jest para o arquivo de configurações .js seria um passo em direção a uma solução mais reutilizável (consulte https://github.com/facebook/jest/issues/2140).

Todos 84 comentários

++

Está em nosso roteiro oferecer suporte a complementos do sistema de módulos para Jest (como require.js, módulos es6, etc), mas infelizmente ainda não chegamos lá.

No entanto, vamos deixar este problema em aberto para acompanhar o progresso -- acho que seria muito útil oferecer suporte a carregadores require.js

@jeffmo webpack suporta commonjs/es6/amd. Se pudéssemos trazer o jest como um plugin, provavelmente poderíamos obter todas essas coisas de graça.

++

temos muitos projetos em uma grande organização e planejamos usar jest, mas somos 100% requirejs. Qualquer eta sobre a integração requirejs?

++

Eu também gostaria de experimentar o jest, mas o projeto atual em que estou está usando o RequireJS.

:+1:

Alguém sugeriu usar isso como um calço, alguém já tentou?

https://github.com/Jakobo/redefine

_Viável com ressalvas_. Eu implementei uma pequena compilação com nodefy em algum aleatório que poderia funcionar como um tapa-buraco. Veja scripts.cjs em pacotes .

Teste decisivo: seus aliases de módulo AMD se alinham com o módulo correspondente em node_modules . Se o teste decisivo falhar, mas você estiver desesperado, poderá criar módulos AMD puros e/ou adicionar links simbólicos a node_modules, mas a ideia me deixa triste. Da minha perspectiva, os externos que eu uso tendem a implementar UMD e instalar por npm para nomes alinhados com meus aliases AMD - não é grande coisa.

(Eu verifiquei o uRequire antes do nodefy, mas o modelo CommonJS o torna funcionalmente equivalente ao nodefy - vou pegar a ferramenta direcionada. Também verifiquei o amdefine, mas o jest usa a correspondência regex em 'require' - talvez haja um AMD anônimo Há sempre UMD, mas codificar UMD com referências document espalhadas parece falta de educação.)

+1

++

Estamos usando react, backbone e requirejs em todo o nosso novo código do lado do cliente. Eu adoraria ser capaz de usar jest e aliviar um pouco a dor de testar reagir. Seria bom reduzir as coisas ao nível da unidade. Atualmente nossos testes para o código react estão sendo feitos com rspec e um webdriver. Embora isso funcione, é menos do que ideal por razões óbvias.

Já existe alguma solução prática? O principal problema que estou enfrentando são as instruções de definição que envolvem os componentes de reação.

+1

@petehunt Me ligou para o Webpack, então isso é algo a ser considerado também.

+1

Alguém pode me indicar um exemplo de jasmine/webpack ou jest/webpack executando testes de navegador com cobertura de código?

++

Quando podemos esperar suporte para requirejs?

+1

+1

+1

+1

+1

+1

Se você usar module.exports em vez de return para sua chamada de definição, você pode adicionar isso ao seu pré-processador.

Funciona para mim :thumbsup:

// preprocessor.js
var ReactTools = require('react-tools');
module.exports = {
  process: function(src) {
    if (/define\(.*?\{/.test(src)) {
      //Remove AMD ceremony for use without require.js or almond.js
      src = src.replace(/define\(.*?\{/, '')
        .replace(/(}\);|}\))$/,'');
    }

    return ReactTools.transform(src);
  }
};

++

+1

+1

+1 para suporte ao RequireJS

+1

@charliedowler Você se importaria de ilustrar um pouco mais essa abordagem. Estou testando e estou com alguns problemas. Comecei adicionando

if (typeof(module) == 'object' && module.exports) { module.exports = <my_element>;  }

No entanto, estou usando return , então estou recebendo um erro de análise do pré-processador. Achei que poderia escapar estendendo o RegEx para também corresponder ao último retorno. Mas parece que não está funcionando de jeito nenhum. Eu continuo recebendo o erro "declaração de retorno ilegal". Provavelmente algo errado com a expressão, e não está pegando.

if (/define\(.*?\{/.test(src)) {
  src = src.replace(/(define\(.*?\{|return.*[\s]}\);?$)/g,'');  
}

Existe uma maneira de eu escrever src para stdout? Um console.log simples não está funcionando.

E por último, supondo que tudo isso funcione. Como você está lidando com as dependências? Como por exemplo React?

+1

Ah! Eu estava brincando com (e gostando muito de brincadeira). Tentei colocá-lo em um projeto real hoje e descobri que não há suporte para requireJS :sob: ... disjuntor para todos os projetos "reais" atuais. Triste mesmo. Com certeza foi uma ideia empolgante!

:+1:

+1

+1

:+1:

:afirmativo:

:+1:

:+1:

Então resolvi isso usando o webpack para compilar meus módulos e testes AMD juntos. Isso me permitiu também usar todos os tipos de carregadores adicionais com meus testes. https://github.com/ninjapanzer/Backbone-Flux-React-Webpack

:+1:

+1

+1

+1

Agradecemos por relatar este problema e agradecemos sua paciência. Notificamos a equipe principal para uma atualização sobre esse problema. Estamos procurando uma resposta nos próximos 30 dias ou o problema pode ser encerrado.

+1

@facebook-github-bot-4, por favor, faça isso!

+1

+1

++

Eu tenho trabalhado no Jestpack, que é um substituto para o 'HasteModuleLoader' do Jest para oferecer suporte ao Webpack. Como resultado, significa que você pode usar qualquer sistema de módulo que o Webpack suporte, incluindo AMD.

Em uma nota lateral, alguém conhece algum projeto de código aberto grande (ish) usando Jest além daqueles que usam módulos de pressa no estilo FB, pois seria realmente útil para testar o desempenho do Jestpack?

Eu também tenho trabalhado em jest-requirejs que é mais uma tentativa de um pré-processador jest padrão que analisa o arquivo de configuração do projeto main.js e executa um deamdify , que remove o define wrapper, reescreve os caminhos obrigatórios com base nos detalhes dos caminhos e baseUrl especificados do main.js e, em seguida, passa o arquivo transformado para jest como de costume.

Ainda trabalhando na sintaxe do plugin/loader e reescrevendo os caminhos jest.dontMock("") , jest.setMock("") e require.requireActual("") dentro do ambiente de teste.

Ei, pessoal, isso é realmente incrível. Gosto da ideia do Jestpack e pretendo tornar muito mais fácil o suporte a resolvedores de módulos adicionais. Finalmente, também quero renovar o site e recomendar soluções como Jestpack como parte do guia de introdução (que tenho em mente :) ). @richardscarrott e @sterpe por favor deixe-me saber se você precisar de alguma coisa.

Também cc @mwolson e @ColCh

(Para todos os outros: por favor, pare de votar nos comentários, não é útil. Se você quer algo construído para brincadeira, por favor envie um pull request. O código ganha argumentos! Pessoalmente, não posso priorizar recursos apenas porque as pessoas da comunidade precisam deles e eu não use _todos os carregadores de módulo_ que estão lá fora.).

Jestpack é interessante, embora eu não seja fã de ter que criar um ponto de entrada por teste. https://github.com/Ticketmaster/jest-webpack-alias resolve o problema um pouco mais genericamente, ao custo de algum pré-processamento e possíveis bugs ainda não descobertos devido à reimplementação do código de resolução do módulo do webpack.

Além disso: os guias de Introdução provavelmente devem mencionar que é uma boa idéia limitar em quais arquivos seu pré-processador é executado, se você tiver um, caso contrário, ele diminui consideravelmente a execução dos testes.

os pré-processadores são executados apenas uma vez e você pode fornecer uma função de chave de cache. jest não executará novamente seu pré-processador se um arquivo não tiver sido alterado.

Pode ser, mas mesmo a primeira execução foi suficiente para adicionar cerca de 10 segundos à execução do nosso conjunto de testes.

Concordou que isso não é rápido. No FB a primeira execução demora quase o dobro das execuções subsequentes, mas pessoalmente não vejo nenhum outro para resolver isso – estamos usando babel e outras transformações personalizadas no FB; não podemos executar testes sem um pré-processador :)

O cache do pré-processador estava me mordendo enquanto desenvolvia o pré-processador requirejs. Eu principalmente ainda uso [email protected] que não tem cache, eu acredito?

Deve funcionar bem com 0,5!

O Webpack é muito rápido no modo dev-watch.

Porque:

  1. Webpack mantém seu tempo de execução na memória (sem recargas)
  2. O código-fonte compilado também está localizado na memória.

Então, no meu pré-processador Jest eu implementei apenas (2) pontos.

Resumindo , um pacote ( memória FS e executar casos de teste na memória FS .

Esse é o meu ponto de vista...

Mas temos outro problema agora: não é possível injetar memória FS no Jest por enquanto.

Pensei em usar a API de cache Jest privada - para injetar a fonte compilada diretamente no cache. Pode ser um hack, então eu estava errado aqui: jest-webpack/issues/4#issuecomment-98623189

Ah, devo mencionar que o Karma com Webpack como pré-processador também está funcionando muito devagar. Então, acho que a principal queda de desempenho é por causa dos recarregamentos do tempo de execução do webpack entre os arquivos.

@cpojer Achei que era sua intenção eventualmente tornar os carregadores de módulo configuráveis, pois já estava disponível, então pensei em dar uma facada no Jestpack. O único problema real que encontrei foi entender a lógica para descobrir mocks manuais para node_modules https://github.com/facebook/jest/issues/509 , acabei optando por uma solução que fazia sentido para mim, mas se você Se for capaz de fornecer qualquer insight sobre esse problema, seria bom alinhar o carregador de módulo do Jestpack com o HasteModuleLoader.

@mwolson O motivo pelo qual o Jestpack usa um ponto de entrada separado por arquivo de teste é garantir que ele ainda possa aproveitar os vários processos do Jest.

moduleLoader já pode ser especificado como parte da configuração, na verdade.

++

Nós gostaríamos disso também. Jest parece um software incrível, mas não pode reescrever tudo o que temos para explicar sem suporte a RequireJS.

+1

Alguém da comunidade está interessado em trabalhar nisso? Eu ficaria feliz em apoiar as pessoas através disso e fazer um plugin oficial do Jest. É improvável que invistamos fortemente nisso no FB em breve. A equipe do Jest é muito pequena (1,5 pessoas) e não podemos trabalhar em todos esses recursos, infelizmente.

Com base no estado atual da comunidade JavaScript e do padrão, não parece que o require js em si tenha um grande futuro para a criação de código JavaScript. Agora temos um sistema de módulos padronizado no ES2015. Babel e Jest agora estão totalmente integrados e funcionam bem juntos. Eu recomendarei a qualquer pessoa que mude para os módulos CommonJS ou ES2015, o que disponibilizará mais ferramentas para você imediatamente.

require JS também tem um documento aqui sobre como converter CommonJS para require.js que pode ser usado para implementações de produção, veja: http://requirejs.org/docs/commonjs.html

Pessoalmente, não vejo vantagem em escrever código usando exigir JS. Eu também ficaria feliz em ajudar a escrever um codemod que pode ajudar a transformar as bases de código JS necessárias para CommonJS. Outro desafio poderia ser escrever um plugin requireJS to CommonJS babel e colocá-lo no pré-processador do Jest.

@cpojer Tive um pouco de sucesso com a abordagem do pré-processador aqui https://github.com/sterpe/jest-requirejs/blob/master/index.js, mas só implementei uma transformação para !text/ plugins até agora. Nossa equipe saiu completamente do requirejs, então eu não tive um motivo para continuar nesse caminho.

Concordo, vejo pouco valor em usar o RequireJS para criar código. Faz sentido para mim compilar o código do módulo CommonJS/ES2015 para requirejs para produção, mas não parece ótimo escrever código com esse estilo manualmente.

Acabei de fazer a migração do RequireJS para o webpack. Existem mais de 300 componentes em nossa base de código. Todo o processo foi surpreendentemente fácil e indolor.

A ferramenta que usei foi https://github.com/Skookum/recast-to-cjs para converter código do estilo AMD para CommonJS.

Também com a ajuda de https://github.com/facebook/jscodeshift , migramos nossa base de código do React 0.11 para 0.14 em poucos dias.

Espero que isso possa ajudar alguém na mesma situação.

@tendente legal! Isso é exatamente o que eu estava falando antes :) Que bom que funcionou tão bem para você.

Como isso está fechado, isso significa que o Facebook não adicionará suporte para isso?

Se por Facebook você quer dizer eu, então sim, é improvável que haja suporte "oficial". Isso não deve impedir você de contribuir para o Jest e obter esse recurso, mas acredito que a maioria das pessoas mudou para os módulos ES ou CommonJS hoje em dia.

Sim, eu sei. Infelizmente, não posso me afastar dessas dependências porque é para trabalho.

babel-plugin-transform-amd-to-commonjs pode ser útil para resolver o problema de Jest+AMD, especialmente se você já estiver usando algo como babel-jest.

Configurei um projeto de exemplo que mostra como você pode fazer com que o Jest exija arquivos AMD de forma transparente executando a transformação no ambiente de teste.

Não tenho certeza dos detalhes de tal abordagem em um projeto real - em particular uma boa abordagem para compartilhamento de configuração entre Jest/RequireJS/Webpack/etc. O suporte do Jest para o arquivo de configurações .js seria um passo em direção a uma solução mais reutilizável (consulte https://github.com/facebook/jest/issues/2140).

@msrose isso é incrível. Muito obrigado por compartilhar isso.

Entendo que esta é uma questão antiga. Uma transformação simples pode funcionar:

exports.process = function (content) {
  return 'function define(name, deps, body) { module.exports = body.apply(undefined, deps.map(require)); }' + content;
}

Eu acho que a transformação de AMD -> CJS pode ser feita de várias maneiras, por exemplo, deamdify , wrapper injetado, etc. O problema, ainda sem solução, são as sintaxes de carregador/plugin no estilo Require. Essas são as coisas como fooTemplate = require('tpl!foo.tpl') e barJson = require('json!bar.json') (como relativamente comuns). Mas havia muitos desses e projetos require-js mundo real estão cheios desse tipo de sintaxe.

Seria ótimo se houvesse uma maneira fácil de reutilizar diretamente os plugins require-js existentes no sistema de transformação que, em última análise, alimenta o carregador de módulo de jest |.

+1

ReferenceError: define is not defined

+1

FALHA srcApp.test.js
● Falha na execução do conjunto de testes

ReferenceError: define is not defined

Você deve usar umd em vez de amd. Se isso não for viável, você deve adicionar uma transformação (por exemplo, o plugin babel vinculado acima).

Quando se trata da sintaxe loader! , não suportamos isso (também não suportamos para Webpack). A solução alternativa é transformar as importações (removendo os carregadores) e deixar o Jest transformar usando sua configuração transform . Discussão relacionada: #4868

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

hramos picture hramos  ·  3Comentários

paularmstrong picture paularmstrong  ·  3Comentários

stephenlautier picture stephenlautier  ·  3Comentários

withinboredom picture withinboredom  ·  3Comentários

gustavjf picture gustavjf  ·  3Comentários