JavaScript 友好的预处理器困境
我从事一个(即将完成的)Javascript 项目已经有 14 个多月了。该项目一开始只是一个黑客项目,我预计会在一夜之间完成,但随着时间的推移,Javascript 部分已经成长为 68 个独立文件和 10,314 个非空行,遗憾的是目前依赖于 C 预处理器来构建。
很难解释我是如何最终在 Javascript 中使用 cpp 的:这只是一个 hack,我需要一些可以给我宏扩展、ifdef、define 和 include 的东西,而不需要太多的努力。经过大约 3 秒的考虑,我意识到 cpp 对于该任务来说是“完美”的:
- 提供一个在发布模式下消失的 LOG() 宏。
- 提供一个 ASSERT() 宏,该宏在发布模式下消失,并生成用原始文件和行号标记的异常。
- 将 LOG() 和 ASSERT() 实现替换为允许生成“已检查”构建的代码,该构建会在发生事件时以紧凑的形式记录事件,如果发生崩溃,则将事件报告回服务器。
- 根据与 Python 后端共享的配置文件,将 PROJECT_SOME_CONFIG_VAR_NAME 替换为“1”。
像所有真正的黑客一样,这个黑客现在被硬编码到项目中,我真的不想去考虑替换它所需的工作。我的项目已达到这样的阶段:我想将代码库移至其自己的专用测试服务器(而不是我的笔记本电脑),但是在设置 Linux 实例时,我发现 4.1 之后的 GNU cpp 版本不再预处理 Javascript因错误而崩溃。
我认为现在是真正解决这个混乱问题的好时机,而不是将特定版本的 GCC 添加到构建要求列表中。但我的问题是,我找不到与 cpp 具有相同功能和功能的替代预处理器!我考虑过m4,但m4本身就是一个痛苦的世界。我发现其他特定于 Javascript 的预处理器缺乏我当前依赖的所有功能,例如:
__FILE__
&__LINE__
- 可变参数宏
- 包括保护
- 令牌串联
- 条件编译
我正在认真考虑仅为 Javascript 实现一个全新的预处理器,它完全借用了 C 预处理器语法,因为它运行得很好。我只是想知道在这样做之前是否有更好的选择。 :) 也许已经有一个类似 cpp 的通用预处理器我可以换入?替换这 68 个文件中的所有预处理器语法所需的工作量接近简单地重新实现预处理器所需的工作量。
我很惊讶我能在依赖 C 预处理器的情况下取得如此大的成就;对于这项任务来说,它比健康的理解更有效。我的另一个选择是静态构建适用于 Linux、Darwin-i386、Win32 的 cpp-4.1 版本,并将这些二进制文件存储在项目的存储库中。
帮助!
I've been working on a (nearly finished) Javascript project for a little over 14 months now. The project started out as a hack I expected to finish overnight, but over time the Javascript part has grown up to be 68 separate files and 10,314 non-empty lines, sadly currently dependent on the C preprocessor for building.
It's hard to explain how I ended up using cpp for the Javascript: this was only a hack, and I needed something that gave me macro expansion, ifdef, define, and includes without too much effort. After about 3 second's consideration, I realized cpp was "perfect" for the task:
- Provide a LOG() macro that disappears in release mode.
- Provide an ASSERT() macro that disappears in release mode, and generates exceptions tagged with original file and line number.
- Swap LOG() and ASSERT() implementations for code that allows producing a "checked" build, which logs events in a compact form as they occur, that are reported back to the server if a crash occurs.
- Replacing PROJECT_SOME_CONFIG_VAR_NAME with "1", based on a configuration file shared with the Python backend.
Like all true hacks, this hack is now so hard-coded into the project that I truly hate to even think about the work that will be required to replace it. My project is reaching the stage where I want to move the code base to its own dedicated test server (rather than my laptop), however on setting up a Linux instance, I've discovered that GNU cpp versions after 4.1 no longer preprocess the Javascript with crashing out with an error.
Rather than add a specific version of GCC to the list of build requirements, I figured now would be a good time to truly fix this mess. My problem is, though, that I can't find a replacement preprocessor with the same power and features as cpp! I have considered m4, but m4 is a world of pain unto itself. Other Javascript-specific preprocessors I have found lack all the features I am currently depending on, e.g.:
__FILE__
&__LINE__
- Variadic macros
- Include guards
- Token concatenation
- Conditional compilation
I am seriously considering implementing a brand new preprocessor just for Javascript, that completely borrows the C preprocessor syntax since it has worked so well. I'm just wondering if there are better options before doing so. :) Perhaps there is already a cpp-like generic preprocessor I could swap in? The work required to replace all the preprocessor syntax in those 68 files approaches the amount of work required to simply reimplement the preprocessor.
I'm quite surprised I ever made it so far while relying on the C preprocessor; it is more effective at this task than healthy for the mind to comprehend. Another option open to me is statically building versions of cpp-4.1 for Linux, Darwin-i386, Win32, and storing those binaries in the project's repository.
Help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否已经尝试过mcpp?它是一个“便携式 C 预处理器”
如果失败,您可以尝试使用通用宏处理器(例如 gema)在其上构建足够的 cpp。
Have you already tried mcpp? It's a "portable C preprocessor"
Should that fail, you could try using a generic macro processor (like gema) and build enough cpp on top of it.
我根据类似问题的答案研究了 cpp 和其他一些竞争者。然后找到了我认为迄今为止最好的答案 - PHP。考虑一下:
1) PHP 确实是一个预处理器(它的缩写)。
2) PHP 已准备好在大多数服务器上运行。您所要做的就是将文件扩展名从“.js”更改为“.php”或“.js.php”,或者(我的偏好)对服务器配置文件进行简单编辑(您可以在其他地方找到详细信息) )。
3) 许多 JavaScript 开发人员已经熟悉或精通 PHP。
4) 与许多其他预处理器不同,PHP 是图灵完备的。
5)您只需要基本的PHP知识即可受益匪浅。
6) PHP 的文档/教程/论坛比其他预处理器多得多。
但大多数情况下,它很奇怪,但很酷。感谢给我这个想法的人 - 我现在找不到他们的帖子。
I looked at cpp and a few other contenders based on answers to similar questions. Then found what I think is the best answer by far - PHP. Consider:
1) PHP is indeed a preprocessor (its in the acronym).
2) PHP is ready to go on most servers. All you have to do is either change your file extensions from ".js" to ".php" or ".js.php", or (my preference) make a simple edit to a server config file (you can find the details elsewhere).
3) Many JavaScript developers are already familiar with or expert at PHP.
4) PHP is Turing-complete, unlike many other preprocessors.
5) You only need basic PHP knowledge to benefit a lot.
6) There is way more documentation/tutorials/forums for PHP than other preprocessors.
But mostly, it's so weird it's cool. Thanks to whoever gave me the idea - I can't find their post at the moment.