Mustache.js: ES 模块支持

创建于 2019-05-29  ·  18评论  ·  资料来源: janl/mustache.js

你好!

我想知道是否有计划支持Mustache.js的 ES 模块版本? 如果是这样,我可以为此做出贡献。

为什么?
我在做Deno项目,有一个关于模板的讨论(Deno 只支持 ES 模块)。 问题是目前没有模板渲染器。 一个想法是将mustache移植到Deno ,因此移植意味着需要维护的不同代码流。 我认为将它直接放在小胡子上对这两个项目都有好处。 但是在 mustache 的情况下,这意味着将mustache.mjs添加到 repo,编辑: 或更改 mustache.js 以使其与 ES 模块兼容。

你的意见?

参考: https :

最有用的评论

状态更新; 正如我在您针对我的esm-ify 分支打开的 PR 中提到的那样,我现在进行了一些测试,以确保此包按我们在 #724 中支持多年的不同模块系统的预期工作。

我会让这个酝酿几天,因为我只是推动了一些改进,以防万一有人有任何异议或更多的调整。

有了这些测试,我很乐意继续将这个项目转换为将源代码编写为 ES 模块并构建步骤以生成我们今天在mustache.js中得到的内容——这当然会完成在即将到来的公关中。

所有18条评论

嗨@zekth!

您在 deno 方面制定了令人兴奋的计划。 我对让这个项目的 ES 模块兼容非常积极,并且完全同意你关于避免移植的想法。

你有什么具体的想法来实现这一点吗?

这是我今天早上完成的(非常丑陋的)端口(在打字稿中) https://github.com/zekth/deno_mustache/blob/master/mod.ts

我已经移植了一些测试只是为了开始。
我唯一担心的是您使用 mustache 支持的所有不同环境,让主 js 文件 ES 模块兼容比另一个mjs更好,我认为但我不想破坏任何东西:)

非常感谢参考! 👍

由于我对 deno 的经验为零,我将提出一些琐碎的问题来引发一些讨论:

  1. deno 必须满足哪些要求才能使其工作? 它需要是一个.mjs文件还是关心type="module"package.json
  2. 任何文件命名要求?
  3. TypeScript 在这里重要吗?

..等,任何假人线索将不胜感激。 目前,我对 deno 知之甚少,无法创造性地思考解决这个问题的合理方法。

  1. 没有特殊要求,因为它只需要库是一个 ES 模块。 示例lodash无需任何移植即可工作。 模块的加载是通过 HTTP 获取完成的,没有包 json 或任何东西。
  2. 没有命名约定
  3. 你可以使用 JavaScript 的 TypeScript,Deno 处理两者。

例如在 deno 中使用 mustache 看起来像:

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

如果您想了解更多信息,可以查看 Ryan 的演讲: https :

凉爽的!

所以这里有一些散文来分享一些想法和背景。 我对 ES 模块的理解是,根据export ed 的内容,它们在语法上是可解析的。 这与其前身如 CommonJS、AMD 等形成了鲜明的对比,后者本质上更具动态性。

考虑到这一点,我今天还假设IIFE 围绕着 mustache.js 的主体,旨在检测当前运行代码的模块系统,将无法在 ES 模块领域中工作 - 如果我'我错了!

这意味着必须有一个.js | .mjs | .ts文件,它有一个简单的export ...就像你在你的端口中一样: zekth/deno_mustache/mod.ts#L689

当我们还想保持旧的行为时,乐趣就开始了,与使用其他模块系统的项目保持兼容,甚至根本不使用模块系统,因此需要提到的 IIFE 包装器 :thinking: 提醒一下,这意味着项目在服务器和浏览器上运行。

因为我们肯定不想让两个不同的实现(ES 模块 + 其余的)同步,所以开始觉得值得考虑一个构建步骤。 例如,如果我们以 ES 模块样式编写源代码,那么构建步骤可以像我们今天一样将其转换为非 ES 模块。 或者反过来,如果这不那么具有侵入性。

最后要注意的是,我非常喜欢尽可能小步骤。 我通常对 TypeScript 持积极态度,但是如果我们继续关注 ES 模块并进行另一轮关注是否转换为 TypeScript/导出 typedef,现在是否可以?

想到任何其他想法或更正?

你说得对,第一步是添加 TypeScript 堆栈并使用编译器输出多个文件,如 commonjs/ES5/ES6 等(https://www.typescriptlang.org/docs/handbook/compiler-options .html)。 使用 TS 编译器并不强制我们使用 TypeScript,我们也可以使用 ES6 代码。

哦,这是一个很好的建议! 尝试使用TS编译器作为ES->其他模块系统的普通构建工具。 这将使以后看似合理的 TS 转换风险降低很多。

你能试一试这种方法吗? 不一定一次性解决所有问题,但至少是第一个构建块。 有一些具体的东西可以查看并围绕未来的讨论进行,这将是非常有价值的。

Sooo 我尝试过渡到 ES 模块。

我的概念证明最终使用 rollup.js 而不是 TypeScript 编译器(或 babel),主要是因为它们生成的 UMD 版本——我们仍然需要它来保持与旧模块系统或根本没有模块系统的兼容性。

您是否愿意使用 deno 对其进行测试运行,以查看它是否按预期工作? phillipj/mustache.js#esm-ify mustache.mjs

@phillipj会做的!

一些错误,但我认为这些都是小修正:

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.

代码:

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);

要我尝试对您的.mjs文件进行 PR 吗?

谢谢!

现在意识到我应该分享更多关于我最初尝试做的事情的背景,抱歉。

正如我们之前所讨论的,我对 TypeScript 编译器的初始尝试也产生了很多错误,与您现在提供的错误有些相似。 尽管如此,它确实产生了输出并且非常接近我想要的结果,这让我感到惊讶。

我不满意的是它包裹在编译输出中的 UMD 代码。 主要是两点:

  1. 它没有将包内容公开到全局范围的后备(想想window.Mustache )。 这对于我们没有模块系统的用户来说至关重要。
  2. 在使用 CommonJS 的项目中,这个包的内容公开为module.exports.default而不是module.exports 。 虽然当 CommonJS require()是 ES 模块时,这可能是正确和预期的行为,但它会破坏向后兼容性,我希望避免这种情况。

由于我的主要目标是首先将源代码转换为 ES 模块,而不是引入 TypeScript,因此我决定尝试不同的编译器/捆绑器,看看它们是否做了不同的事情来避免上述两个挑战。

这就是我最终使用 rollup.js 的原因。 它的 UMD 输出是我们所需要的,它不会对这个包的用户造成任何破坏性的变化。

Sooo 到我的实际问题; 我们现在需要关心 TypeScript 吗?

在本次讨论的早些时候,我的理解是我们可以考虑还没有完全过渡到 TypeScript,因为如果它确实是一个 ES 模块,它仍然会帮助deno ,但我可能有点误解了?

我认为主要问题是胡子的第一次初始化,如下所示:
https://github.com/janl/mustache.js/blob/master/mustache.js#L14

还有这个: https :
可以改写为new Context(view, null)

你不觉得吗?

我认为主要问题是小胡子的第一次初始化..

你也许是对的。 在.mjs版本中,我尝试将其移动到至少实际的源代码中,而不是从 UMD 包装器传入的对象:

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

看到你的方法可以修复那些 TypeScript 错误会很酷👍

可以重写为 new Context(view, null)

几乎.. new Context(view, undefined)不等于根本不传递第二个参数吗?

关于new Context是正确的

我会尝试一些东西:)

这是公关: https :
CI 坏了,但我不明白为什么我会收到那些 linting 消息

太棒了,非常感谢! 接下来的几天很忙,我会尽量在周末前复习一下。

状态更新; 正如我在您针对我的esm-ify 分支打开的 PR 中提到的那样,我现在进行了一些测试,以确保此包按我们在 #724 中支持多年的不同模块系统的预期工作。

我会让这个酝酿几天,因为我只是推动了一些改进,以防万一有人有任何异议或更多的调整。

有了这些测试,我很乐意继续将这个项目转换为将源代码编写为 ES 模块并构建步骤以生成我们今天在mustache.js中得到的内容——这当然会完成在即将到来的公关中。

728 已开放接受公众审查。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

kuldeepdhaka picture kuldeepdhaka  ·  9评论

SmasherHell picture SmasherHell  ·  18评论

mbrodala picture mbrodala  ·  16评论

MatthijsZw picture MatthijsZw  ·  18评论

rlightner picture rlightner  ·  7评论