JavaScript友好的预处理器困境

13

我已经在一个将近完成的JavaScript项目上工作了14个月。这个项目最初只是我期望在一夜之间就能完成的hack,但随着时间的推移,JavaScript部分已经发展成为68个独立文件和10,314行非空代码,目前不幸依赖于C预处理器进行构建。

很难解释我是如何使用cpp来处理JavaScript的:这只是一个hack,我需要一些能够方便地进行宏展开,ifdef、define和include操作的东西。经过大约3秒钟的考虑,我意识到cpp完全"完美"地解决了这个问题:

  • 提供一个LOG()宏,在发布模式下消失。
  • 提供一个ASSERT()宏,在发布模式下消失,并生成带有原始文件和行号标记的异常。
  • 为允许生成"checked"版本的代码交换LOG()和ASSERT()实现,该版本会在紧凑的形式中记录事件,并在发生崩溃时将它们报告回服务器。
  • 根据与Python后端共享的配置文件,用"1"替换PROJECT_SOME_CONFIG_VAR_NAME。

像所有真正的hack一样,这个hack现在已经被硬编码到项目中,以至于我真的不愿意想象要替换它所需要的工作量。我的项目正在到达我想将代码库移动到它自己的专用测试服务器(而不是我的笔记本电脑)的阶段,但是在设置Linux实例时,我发现GNU cpp 4.1版本后不再预处理JavaScript并且会崩溃出错。

与其将特定版本的GCC添加到构建要求列表中,我认为现在是真正解决这个问题的好时机。但是,我的问题是我找不到一个具有与cpp相同强大功能和特性的替代预处理器!我考虑过m4,但m4本身也很麻烦。我发现其他一些针对JavaScript的预处理器缺少我目前依赖的所有功能,例如:

  • __FILE__ & __LINE__
  • 可变宏
  • 包含保护
  • 标记连接
  • 条件编译
  • 我正在认真考虑为Javascript实现全新的预处理器,完全借用C预处理器语法,因为它已经被证明效果很好。在这样做之前,我想知道是否有更好的选择。:) 或许已经有一个cpp类似的通用预处理器可以替换掉?替换那68个文件中所有预处理器语法所需的工作量接近于重新实现预处理器所需的工作量。

    我很惊讶自己依赖C预处理器做到了这么远;它对这个任务的效果比健康的头脑能理解的要好得多。我的另一个选择是静态构建Linux、Darwin-i386、Win32版本的cpp-4.1,并将这些二进制文件存储在项目的存储库中。

    救命啊!


    好的,我理解你的感受。你搞砸了一件事,但是为什么 C++ 会崩溃呢?它不应该这样。 - Stefano Borini
    @Stefano,这不是像分段错误那样的真正崩溃。解析器混淆了Javascript的词汇和语法集,显然与C的不同。GCC 4.2+似乎有更严格的解析器。 - dmw
    出于好奇:哪些JS结构会让C++感到困惑? - Christoph
    也许你可以修改另一个类似于CPP的工具(例如http://www.haskell.org/cpphs/),以更好地满足你的需求。或者,你可以用JavaScript编写一个JavaScript预处理器,因为你现在已经熟悉这种语言了;-) - ephemient
    1
    @Christoph,至少使用单引号的字符串:'David'是有效的Javascript,而它在C中是无效的。在4.2之前,GCC似乎会通过无效的标记,但现在不再如此。@ephemient 很可能是这样 :) 实际上,任务应该更简单,因为我不需要C预处理器的完全通用性和规则。 - dmw
    @David:我无法重现您在gcc 4.4.0中的问题;您能否添加一个失败的简单示例? - Christoph
    2个回答

    4
    你尝试过 mcpp 吗?它是一个“便携式C预处理器”。
    如果那个不起作用,你可以尝试使用通用的宏处理器(例如gema),并在其上构建足够多的cpp。

    2
    感谢提供mcpp的链接:在“-@old”模式下,它可以做得很好,但似乎由于我在字符串中使用单引号字符(C中的字符字面量),所以出现了错误。暂时调查gema。 - dmw
    1
    我把这个问题的答案授予给你,因为它是最有用的答案。最终,我决定咬紧牙关将整个代码库转换为Google Closure,因为它几乎拥有纯Javascript所需的所有功能,并且编译器在“部署”时提供相同的好处(将其链接在一起并删除调试代码)。 - dmw

    0

    我查看了cpp和其他一些类似问题的答案,然后发现迄今为止我认为最好的答案 - PHP。考虑以下几点:

    1)PHP确实是一个预处理器(它在缩写中)。

    2)大多数服务器都可以使用PHP。您只需要将文件扩展名从“.js”更改为“.php”或“.js.php”,或者(我更喜欢的方式)对服务器配置文件进行简单编辑(您可以在其他地方找到详细信息)。

    3)许多JavaScript开发人员已经熟悉或精通PHP。

    4)与许多其他预处理器不同,PHP是图灵完备的。

    5)您只需要基本的PHP知识就可以获得很多好处。

    6)相比其他预处理器,PHP有更多的文档/教程/论坛。

    但最重要的是,它非常奇怪,因此很酷。感谢给我提供这个想法的人 - 我目前找不到他们的帖子。


    1
    为什么PHP比其他编程语言更好?你能举些例子吗?例如,如何创建一个在发布模式下消失的_LOG()宏或以优雅的方式替换PROJECT_SOME_CONFIG_VAR_NAME为“1”? - fredrik.hjarner

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接