【问题标题】:Beautify / lint whitespace in JavaScript [closed]JavaScript中的美化/ lint空白[关闭]
【发布时间】:2013-02-22 06:06:09
【问题描述】:

我想对 JavaScript 中的空白进行 lint(甚至可能是自动)美化。问题是是否有任何工具可以做到这一点。

我知道 JSLint 和 JSHint,例如,可以检查缩进和尾随空格,这都很好,但这些不是您可能拥有的唯一类型的空格。

我也想检查的是:

  • 在某些结构之前或之后是否有空行?
  • 是否有多个空行?
  • 某些事物之间是否有单个空格(这由 JSLint / JSHint 部分检查)?
  • ...

基本上,我希望拥有现代 IDE(例如 Visual Studio 和 Resharper)可以做的一切,但作为可以嵌入到 Grunt 中的命令行工具。

我发现在这个方向上做某事的唯一东西是esformatter,但根据它的网站

仍处于早期开发阶段,缺少对许多重要功能的支持。

当然,如果有更成熟的东西就好了。

有什么想法吗?

【问题讨论】:

  • 查看 jsfiddle.net,看看它的 TidyUp 按钮是如何工作的。
  • 这基本上利用了github.com/einars/js-beautify,它也做得太少了。例如,它无法处理在特定位置插入新行,如下所述:github.com/einars/js-beautify/issues/141。正如我所说,我希望它像 Visual Studio + Resharper(或类似的东西)一样强大。
  • 这很痛苦,但您可以从命令行调用 Eclipse 的代码格式化程序。它可能也提供了您正在寻找的所有选项。
  • 哇,我不知道。你有什么好的链接可以提供给我,以便我阅读更多相关信息吗?
  • 本篇博文并非特定于 Javascript 版本,但应该是相似的,因为它们共享相同的界面。 peterfriese.de/…

标签: javascript node.js gruntjs code-formatting


【解决方案1】:

更新 6 个月和大量搜索后

我建议您查看 eslint。它建立在可插拔 linting 规则的概念之上,这正是您所要求的。您可以使用 grunt-plugin grunt-eslint 指定 linting 规则并使其自动化。它仍然是 pre-alpha,但比 esformatter 发展得更快。它有一个明确定义的roadmap


原创

您提出的问题没有简单的答案。所以让我把它分解并分部分回答。您需要在命令行上嵌入现代 IDE 的功能,例如 Visual Studio 和 Resharper,您可以将其嵌入到 Grunt 中。对您(可能)想要的功能进行广泛分类:

  • 编译器/调试器
    • 在运行之前/期间测试错误。
  • 检查/标记可疑代码
    • 遵循编码标准,有助于发现可能的缺陷。
  • 格式化器/美化器
    • 使代码可读

在制作 IDE 时,请牢记以上所有内容。因此,很难在 IDE 中为 node 找到一个同样强大的格式化程序。

调试器

我知道可以为节点使用 eclipse 调试器。检查这个link

lint/格式化程序

对于 grunt(基于 JSLint/JSHint):

  1. grunt-contrib-jshint
  2. grunt-jslint
  3. grunt-linter
  4. grunt-jsbeautifier

esformatter 功能强大,因为它使用esprima 来解析和格式化 Javascript。它是格式化程序而不是 lint,因此您可能必须在使用它之前对代码进行 lint。您可以查看其他一些使用esprima 的格式化程序:

codepainter 使用 ECMAscript 的 JavaScript 美化器

从它支持的样式属性来看,它有一些你可以使用的特性:

  1. 缩进:{ 字符:'?',宽度:? }
  2. LastEmptyLine:存在,省略
  3. 报价类型:单、双
  4. SpaceAfterControlStatements:存在,省略
  5. SpaceAfterAnonymousFunctions:存在,省略
  6. SpacesAroundOperators:存在,省略
  7. 尾随空格:strip

esmangle ECMAScript 代码修改器/压缩器

esmangle 使用esprima 作为解析器,使用escodegen 作为代码生成器。见demo

ECMAscript 有很多包正在开发中,你可以查看它们here

【讨论】:

  • @Golo 更新了答案。
【解决方案2】:

"@Golo:所以你想要的是能够指定在每种语言结构之间、在每种上下文中如何出现空白?(例如,if-then-else 如何在 do 循环中与在函数的顶层)?

Golo:没错 :-)"

那么你需要的是访问代码中每个点的语言结构,以及每个语言元素(开始/结束行/列)的精确位置信息。对于 linting,您需要一种针对这些事物组合编写测试的方法。对于repair,您需要一种方法来重新生成满足您的约束的文本。您显然希望所有这些都易于配置。

您想要的“结构”是语法树中的解析器生成的。上下文是围绕感兴趣结构的句法结构。您不需要抽象语法树,因为这会丢失要检查/控制其位置的具体标记,因此您需要完整的具体分析树。

解析器对精确的源位置不感兴趣,但词法分析器(需要将输入流分解为语言标记以提供给解析器)可以收集这些精确信息。您担心“什么构成列调整以及调整多少”的一些复杂问题。一些例子: 制表符:制表符到下一个 8 字符边界? 4个字?到预先指定的选项卡列?在 linux 上,“LF”将行号前移,并将列数重置为 1。在 Windows 上,“CR/LF”是一对。在我遇到的其他操作系统上,它只是“CR”;在真正现代的系统上,Unicode 换行符应该这样做。那么,如果在linux上,应该如何对待CR呢?在文本中找到空字符怎么样? ^Z?其他控制字符(例如,^L [formfeed])?

给定一个源文件,该文件被精确解析为一个带有捕获源位置的 CST,现在您想要检查一个结构是否按照您想要的方式对齐。首先,您需要指定结构;做循环?构造函数?数据声明?然后,您需要对列位置进行谓词来进行精确控制。

几乎所有提供语法树的工具都没有提供任何简单的方法来引用此类结构。几乎你被困在编写经典的类似编译器的过程代码,它知道语法树的形状并爬过它寻找感兴趣的树节点,然后环顾四周看看是否存在其他相关的树节点。进入此模式后,您可以识别所需的树,然后编写更多程序代码来检查间距约定。

程序转换系统 (PTS) 通常提供“源到源”重写,您可以在其中直接使用语言的表面语法编写模式。这比程序上绕树爬要方便得多。一些做源到源模式对;有些提供仅指定单个模式的能力。 PT 系统还必须能够解析感兴趣的语言,并使您能够为特定任务添加自定义检查。

例如,我们的 DMS Software Reengineering Toolkit 解析 ECMAScript,并提供此类源模式规范,以及附加自定义条件和操作的能力。举个例子:

domain ECMAScript;

pattern ideal_if_statement_layout(e:expression,s:statement):statement =
     " if (\e)
          \s"  if diagnose_not_equal(column(s),parentheses_column(e));

表达了对“if then”语句的兴趣(您可以对“if then else”使用不同的模式),以及对检查语句元素位置的自定义列比较函数的约束。 “diagnose_not_equal”自定义函数会产生 lint-complaints。引号是元引号;它们是模式匹配语言的一部分,而不是底层语言。 es 是元变量,分别匹配任何语言结构表达式语句。因为这些正在应用于 CST,所以它们不能与预期的目标不匹配。自定义函数“column”只获取与s的最左边子树相关联的起始列信息; DMS 中的树管理 API 使这基本上变得微不足道。需要“括号列”,因为该模式会告诉您 e 的位置; "(" 位于 e 上方的树节点中,因此需要稍微导航树以找到 "(",然后提取其 最右边 列使用 DMS 树 API 轻松完成。

您可以构建任意复杂的模式;您也可以在一种模式中设定条件,取决于另一种模式的匹配。因此,使用适量的自定义列提取函数,您可以编写各种 linting 检查。

这不会让您轻松检查“if”关键字是否位于“(”关键字左侧的一个空格。您可以在某种程度上通过添加自定义检查来表达,例如“statement_keyword_column”等,但这开始变得尴尬了。

您可能会注意到模式的布局;也可以将其用作约束。 DMS 不提供执行此操作的直接方法。但是,它完全能够将自己的模式描述读取为。使用它,可以提取图案的明显布局,并使用它来检查结构布局。这需要对 DMS 的使用有一定的了解,但这是一个汗水问题,而不是理论或缺失的机制。

我个人不太喜欢布局上的 linting;我希望文件只是被重新塑造。 DMS 确实有漂亮的打印规则,可以将您的 CST(无论其布局是什么)转换为受其漂亮打印规则控制的布局。目前,这些规则是特定于树节点的,并且是用语法编码的,所以它们受到了一些限制。可以写(在语法中):

   stmt =  'if' expression stmt ';'
   <<PrettyPrinter>>:  { V(H('if,expression),I(stmt[1])) }

这将导致所有 if-then 语句重新生成为:

    if expresssion
       stmt

[V 表示两个子框的“垂直框”; H 表示“水平框”,I 表示“缩进框”]

仔细使用这些漂亮的打印规则可以很好地重新格式化代码。它并不完美,因为您无法以这种方式控制多个语句的布局。但这是 DMS 的一部分,实际上很容易修改。

理想的解决方案是使用模式语言,并使用模式中的布局来控制漂亮打印。这在我们的计划中,但遗憾的是,还没有在 DMS 中。

我认为其他 PTS 可以在某种程度上表达上述模式,并且它们中的大多数都有某种方式来指定像 DMS 那样的漂亮打印。所以好消息是这些工具可以满足您的大部分需求。不太好的消息是选择其中一种工具并学会使用它需要付出很大的努力。一个下午还远远不够。

【讨论】:

    【解决方案3】:

    我使用 Eclipse,因为我编写了 java、javascript、perl(EPIC 插件)、shell 脚本等等。 Eclipse 将使用CTRL-SHIFT-F 快捷方式轻松编码格式化任何这些语言以及更多语言。这在 IDE 中对我很有效。

    命令行,可以调用eclipse的格式化工具。见:

    1. Eclipse command line formatting of Java code
    2. Can the Eclipse Java formatter be used stand-alone

    话虽如此,除非您或您的团队中的其他人已经在使用 Eclipse,否则它的开销可能会超出您的预期。但! Eclipse 的代码格式是高度可配置的,可以解决您的一些空白/空行问题。

    【讨论】:

      【解决方案4】:

      google 闭包 lint 有一个修复 lint 功能,它可以为您优化您的代码并使其与 google 样式指南一致。 https://developers.google.com/closure/utilities/docs/linter_howto

      【讨论】:

        【解决方案5】:

        基本上,我希望拥有现代 IDE(例如 Visual Studio 和 Resharper)可以做的一切,但作为可以嵌入到 Grunt 中的命令行工具。

        这个怎么样:https://npmjs.org/package/grunt-jsbeautifier

        它本质上是 https://npmjs.org/package/js-beautify 包装到 Grunt 任务中。

        编辑,扩展我原来的答案:我不熟悉 VS Resharper 的功能,但是 - 至少根据自述文件 - 有一个选项可以让 JSLint 开心(并且我们都知道这有多挑剔)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-17
          • 2010-10-19
          • 2011-09-03
          • 1970-01-01
          • 2019-12-02
          • 2011-10-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多