Conditional Compilation

Hi,

A remarkable shift that happened in the JavaScript world in 2015 was the systematic usage of JavaScript transpilers, or rather compiler, in a build step before execution. This was of course pushed by the will to use shinny new ES6 features and syntactic sugar without waiting for people to use compatible browsers, but it also open the door to “new” possibilities of code transformation at compile time rather than at run time.

One of these transformation I think the Meteor community is interested in, is about including some blocks of code on specific targets and not the others. As a full stack platform, we have always done things like that:

function postComment(blogAuthor, comment) {
  if (Meteor.isServer) {
    sendEmailNotification(blogAuthor);
  }
  Comments.insert(comment);
}

The issue with that snippet is that since the conditional is executed at run-time the server code is still send to the client. This is both inefficient (as we are consuming client bandwidth to send them code that they never need) but also potentially dangerous as it may leak some informations about the server. And so as developers get conscious of the dangers of a potential leak, they will avoid these inline platform targeting altogether and will simply write code for different platforms in different files.

I sure agree than putting things in different files is generally a good practice, however I still see a case for inline targeting. This is not only about isClient/isServer but also about things like isCordova or isAndroidNative where it’s likely that our code share a lot with the web client, but just in one specific function we want to call an API that isn’t available in the browser. As we’ll get better support for app testing in Meteor 1.3, we will also execute code in specific environments like isTest or isBenchmark or simply isDevelopement.

So I’m opening a discussion to find out what the Meteor community think is the best way to execute these conditionals at compile-time rather than run-time. TypeScript community has a similar discussion happening here and they also mention that Webpack already has the basic feature implemented.

I tend to think that a new syntax is more appropriate than transparently replacing certain variables at compile time like Webpack is currently doing. This is also the approach others programming langues already took (eg. Rust CFG).

Do you think conditional compilation is needed in the context of a full-stack platform like Meteor? Do you think we should introduce a new language syntax? or re-use an upcoming one like ES7 decorators? or use simple variables like Webpack is doing? I’m also curious if some of you have some insights about TC39 discussions on the matter.

Maxime

Whenever I hear “conditional compilation” I usually break out in a cold sweat remembering the C #ifdef days I’ve tried desperately to forget …

That being said, have you seen the Babel Macros plugin? Conditional compilation with Babel!