Mustache.js: Suporte para módulo ES

Criado em 29 mai. 2019  ·  18Comentários  ·  Fonte: janl/mustache.js

Olá!

Eu queria saber se existe um plano para oferecer suporte a uma versão do módulo ES do Mustache.js ? Nesse caso, posso contribuir para isso.

Por quê?
Estou trabalhando no projeto Deno e há uma discussão sobre modelos (Deno só oferece suporte a módulos ES). O problema é que não há renderizador de template no momento. Uma ideia era portar o bigode para o Deno , então uma porta significa um fluxo de código diferente que precisa de manutenção. Tê-lo diretamente no bigode seria um benefício para os dois projetos, eu acho. Mas no caso do bigode, significa ter um mustache.mjs adicionado ao repo, editar : ou alterar o mustache.js para torná-lo compatível com o módulo ES.

Seus pensamentos?

ref: https://github.com/denoland/deno_std/issues/391

Comentários muito úteis

Atualização de status; como mencionei no PR que você abriu em meu branch esm-ify , agora tenho alguns testes em vigor que garantem que este pacote funcione como pretendido para diferentes sistemas de módulo que suportamos por anos em # 724.

Vou deixar isso fermentar por alguns dias, pois acabei de empurrar algumas melhorias, apenas no caso de alguém ter alguma objeção ou mais ajustes em mente.

Com esses testes implementados, sinto-me confortável em prosseguir com a transição deste projeto para ter o código-fonte escrito como um módulo ES e etapa de compilação para produzir o que temos em mustache.js hoje - isso certamente será feito em um próximo PR.

Todos 18 comentários

Olá @zekth!

Planos empolgantes que você tem com o deno daqui para frente. Estou muito confiante em tornar este módulo ES do projeto compatível e concordo totalmente com suas ideias sobre como evitar uma portabilidade.

Você tem alguma ideia concreta sobre o que seria necessário para que isso acontecesse?

Aqui está uma porta (realmente feia) que fiz esta manhã (em texto datilografado) https://github.com/zekth/deno_mustache/blob/master/mod.ts

Eu transferi alguns testes apenas para o início.
A única preocupação que tenho são todos os ambientes diferentes que você suporta com bigode, ter o módulo ES do arquivo js principal compatível é melhor do que outro mjs eu acho, mas não quero quebrar nada :)

Muito obrigado pela referência! 👍

Como não tenho experiência com deno, vou disparar algumas perguntas triviais para desencadear algumas discussões:

  1. Quais são os requisitos do deno para fazer este trabalho? Precisa ser um arquivo .mjs ou ele se preocupa com o type="module" de package.json ?
  2. Algum requisito de nomenclatura de arquivo?
  3. O TypeScript importa aqui de alguma forma?

..e assim por diante, qualquer pista para idiotas seria muito apreciada. No momento, tenho muito pouco conhecimento sobre o deno para pensar criativamente sobre maneiras plausíveis de lidar com isso.

  1. Não há nenhum requisito especial, pois só precisa que a biblioteca seja um módulo ES. Exemplo lodash funciona sem nenhuma portabilidade. O carregamento do módulo é feito por meio de busca de HTTP, sem pacote json ou qualquer coisa.
  2. Sem convenção de nomenclatura
  3. Você pode usar TypeScript de JavaScript, Deno trata de ambos.

Por exemplo, usar bigode em deno ficaria assim:

import * as mustache from 'https://raw.githubusercontent.com/janl/mustache.js/master/mustache.js'
mustache.render(......

Se você quiser mais informações, pode conferir esta palestra de Ryan: https://www.youtube.com/watch?v=z6JRlx5NC9E

Legal!

Então, aqui estão algumas divagações para compartilhar alguns pensamentos e contexto. Meu entendimento dos módulos ES é que eles devem ser sintaticamente analisáveis ​​em termos do que é export ed. Isso é um contraste sombrio com seus precursores como CommonJS, AMD etc, que são muito mais dinâmicos por natureza.

Com isso em mente, também estou assumindo que o IIFE em torno do corpo do mustache.js hoje, destinado a detectar o recurso do sistema de módulo em que o código é executado atualmente, não funcionará no módulo ES - corrija-me se eu ' Estou errado!

Isso significa que deve haver um arquivo .js | .mjs | .ts que tenha um export ... puro e simples como o que você tem em seu porto: zekth / deno_mustache / mod.ts # L689 .

A diversão começa quando também queremos manter o comportamento antigo, para ser compatível com projetos que usam outros sistemas de módulo ou nem mesmo um sistema de módulo, daí a necessidade do mencionado invólucro IIFE: pensando: E como um lembrete, isso significa projetos rodando em servidores e navegadores.

Como certamente não queremos manter duas implementações diferentes (módulos ES + o resto) em sincronia, parece que vale a pena considerar uma etapa de compilação. Por exemplo, se escrevêssemos o código-fonte no estilo de módulo ES, então uma etapa de construção poderia convertê-lo em um módulo não ES como temos hoje. Ou o contrário, se for menos intrusivo.

Como nota final, sou um grande fã de dar os pequenos passos possíveis. Em geral, sou positivo em relação ao TypeScript, mas, por enquanto, está certo se mantivermos o foco nos módulos ES e fizermos uma rodada diferente com foco em converter ou não em TypeScript / exportar typedefs?

Algum outro pensamento ou correção que vem à mente?

Você está totalmente certo, o primeiro passo seria adicionar a pilha TypeScript e usar o compilador para gerar vários arquivos como commonjs / ES5 / ES6 e assim por diante (https://www.typescriptlang.org/docs/handbook/compiler-options .html). Usar o compilador TS não nos força a usar o TypeScript, podemos usar o código ES6 também.

Oh, essa é uma ótima sugestão! Tentando usar o compilador TS como uma ferramenta de compilação comum do ES -> outros sistemas de módulo a princípio. Isso tornará uma conversão de TS plausível mais tarde muito menos arriscada.

Você consegue dar uma chance a essa abordagem? Não necessariamente resolvendo tudo de uma vez, mas pelo menos os primeiros blocos de construção. Seria realmente valioso ter algo concreto para olhar e basear discussões futuras.

Então, eu tentei fazer uma transição para um módulo ES.

Minha prova de conceito acabou usando rollup.js em vez do compilador TypeScript (ou babel) principalmente por causa da versão UMD que eles geram - ainda precisamos disso para manter a compatibilidade com sistemas de módulo mais antigos ou nenhum sistema de módulo.

Há alguma chance de você fazer um teste com o deno para ver se funciona conforme o esperado? phillipj / mustache.js # esm-ify mustache.mjs

@phillipj vai

Alguns erros, mas acho que são pequenas correções:

error TS2339: Property 'render' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► file:///Users/vlegoff/projects/genesys/github/telemetry/t/mustache.ts:10:23

10 var output = mustache.render('{{title}} spends {{calc}}', view);
                         ~~~~~~

error TS2554: Expected 2 arguments, but got 1.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:525:52

525   var context = (view instanceof Context) ? view : new Context(view);
                                                       ~~~~~~~~~~~~~~~~~

  An argument for 'parentContext' was not provided.

    ► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:377:25

    377 function Context (view, parentContext) {
                                ~~~~~~~~~~~~~


error TS2339: Property 'escape' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:640:21

640     return mustache.escape(value);
                        ~~~~~~

error TS2339: Property 'clearCache' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:659:10

659 mustache.clearCache = function clearCache () {
             ~~~~~~~~~~

error TS2339: Property 'parse' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:668:10

668 mustache.parse = function parse (template, tags) {
             ~~~~~

error TS2339: Property 'render' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:678:10

678 mustache.render = function render (template, view, partials, tags) {
             ~~~~~~

error TS2339: Property 'to_html' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:690:10

690 mustache.to_html = function to_html (template, view, partials, send) {
             ~~~~~~~

error TS2339: Property 'render' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:693:25

693   var result = mustache.render(template, view, partials);
                            ~~~~~~

error TS2339: Property 'escape' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:704:10

704 mustache.escape = escapeHtml;
             ~~~~~~

error TS2339: Property 'Scanner' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:707:10

707 mustache.Scanner = Scanner;
             ~~~~~~~

error TS2339: Property 'Context' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:708:10

708 mustache.Context = Context;
             ~~~~~~~

error TS2339: Property 'Writer' does not exist on type '{ name: string; version: string; tags: string[]; }'.

► https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs:709:10

709 mustache.Writer = Writer;
             ~~~~~~


Found 12 errors.

código:

import mustache from 'https://raw.githubusercontent.com/phillipj/mustache.js/esm-ify/mustache.mjs';

var view = {
  title: 'Joe',
  calc: function() {
    return 2 + 4;
  },
};

var output = mustache.render('{{title}} spends {{calc}}', view);

console.log(output);

quer que eu tente fazer uma RP no seu arquivo .mjs ?

Obrigado!

Percebo agora que devo compartilhar um pouco mais do contexto sobre o que tentei fazer inicialmente, desculpe.

Conforme discutimos anteriormente, minha tentativa inicial com o compilador TypeScript também resultou em alguns erros, um pouco semelhantes aos que você forneceu agora. No entanto, surpreendeu-me que gerou resultados e foi muito próximo do que eu queria.

O que não fiquei satisfeito foi o código UMD que envolveu a saída compilada. Principalmente duas coisas:

  1. Ele não tem o retorno de expor o conteúdo do pacote no escopo global (pense em window.Mustache ). Isso é vital para nossos usuários que não possuem um sistema de módulo instalado.
  2. Em projetos com CommonJS, o conteúdo deste pacote é exposto como module.exports.default vez de module.exports . Embora esse possa ser o comportamento correto e esperado quando CommonJS require() s um módulo ES, ele quebrará a compatibilidade com versões anteriores, o que eu esperava evitar.

Como meu objetivo principal era antes de tudo fazer a transição do código-fonte para um módulo ES, não introduzindo o TypeScript, decidi tentar diferentes compiladores / bundlers para ver se eles faziam as coisas de maneira diferente para evitar os dois desafios acima.

Daí a razão pela qual acabei com rollup.js. A saída UMD é o que precisamos e não causa nenhuma alteração significativa para os usuários deste pacote.

Entããão à minha pergunta real; precisamos nos preocupar com o TypeScript no momento?

Meu entendimento no início desta discussão foi que não poderíamos considerar a transição completa para o TypeScript ainda, já que ajudaria deno no entanto, se fosse realmente um módulo ES, mas posso ter entendido isso um pouco mal.

Acho que o principal problema é a primeira inicialização do bigode como aqui:
https://github.com/janl/mustache.js/blob/master/mustache.js#L14

e também este: https://github.com/janl/mustache.js/blob/master/mustache.js#L536
pode ser reescrito como new Context(view, null)

você não acha?

Acho que o principal problema é a primeira inicialização do bigode ..

Você provavelmente está certo. Na versão .mjs , tentei mover isso para o código-fonte real, pelo menos, em vez de ser um objeto passado do invólucro UMD:

var mustache = {
  name: 'mustache.js',
  version: version,
  tags: [ '{{', '}}' ]
}

Seria legal ver sua abordagem que consertaria esses erros do TypeScript 👍

pode ser reescrito como novo Contexto (visão, nulo)

Quase ... new Context(view, undefined) o equivalente a não passar um segundo argumento?

Sim, correto sobre new Context

Vou tentar algo tão :)

Aqui está o PR: https://github.com/phillipj/mustache.js/pull/1
O CI está quebrado, mas não entendo por que recebi essas mensagens de linting

Incrível, muito obrigado! Muito ocupado nos próximos dias, farei o meu melhor para revisar antes do fim da semana.

Atualização de status; como mencionei no PR que você abriu em meu branch esm-ify , agora tenho alguns testes em vigor que garantem que este pacote funcione como pretendido para diferentes sistemas de módulo que suportamos por anos em # 724.

Vou deixar isso fermentar por alguns dias, pois acabei de empurrar algumas melhorias, apenas no caso de alguém ter alguma objeção ou mais ajustes em mente.

Com esses testes implementados, sinto-me confortável em prosseguir com a transição deste projeto para ter o código-fonte escrito como um módulo ES e etapa de compilação para produzir o que temos em mustache.js hoje - isso certamente será feito em um próximo PR.

728 foi aberto para escrutínio público.

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

Questões relacionadas

rlightner picture rlightner  ·  7Comentários

connor11528 picture connor11528  ·  3Comentários

kuldeepdhaka picture kuldeepdhaka  ·  9Comentários

SmasherHell picture SmasherHell  ·  18Comentários

barbalex picture barbalex  ·  5Comentários