This month I learned - October 2017

October has been a very busy month for me. I spoke at five events including RuhrJS and JSConf Budapest and oh well... I had such an excellent time with wonderful people. 😊 Thanks everybody!

That said I hadn't had much time to read all the things that flodded my inbox but I think that's okay. At least I made it up to three learnings in October. Enjoy!

  • How to quickly perform a syntax check of a JavaScript file

    Recently I came across a tweet by Ingvar Stepanyan. He shared the --check flag for executing JavaScript files in Node.js. I didn't know about this option.

    $ node --check some.js
    
    $ node --check some-invalid.js
    /Users/stefanjudis/test.js:3
    });
    ^
    SyntaxError: Unexpected token }
      at checkScriptSyntax (bootstrap_node.js:457:5)
      at startup (bootstrap_node.js:153:11)
      at bootstrap_node.js:575:3

    What --check enables is a quick check for syntax errors of a JavaScript file without actually executing it. This can be very handy when you're transforming code and just want to make sure the transformation result is valid JavaScript.

    On that note: I came accross the vm module which was mentioned in the replies to the tweet. The vm module is part of Node core and you can use it to evaluate/execute JavaScript in a sandboxed environment which you control, too.

    So far I didn't need this module but you can use it to evaluate and syntax check JavaScript files from within your scripts.

    const vm = require('vm');
    const script = new vm.Script('var a =');

    The constructor of vm.Script throws an exceptions if there are any syntax errors.

    This module looks quite interesting. So, if you're dealing with generated code you might want to check it out. ;)

  • How to automatically respond to confirmations in CLI tools

    Recently we released a new CLI tool to migrate data in Contentful. It's currently in beta and we'll constantly work on it to make it better.

    Last week we received a question in our community forum. A user asked if he could use the CLI programmatically. He had the problem that the CLI asks at some point for confirmation and this makes it hard to run in a CI environment.

    ? Do you want to apply the migration? (Y/n)

    So how could you answer that question when it's not you running this command but the CI environment.

    My colleage Stephan had a cool solution. He responded that the unix command yes could help out here. yes – what kind of command is that?

    The man page for yes is not giving much information but according to Wikipedia this is what it does:

    By itself, the yes command outputs 'y' or whatever is specified as an argument, followed by a newline repeatedly until stopped by the user or otherwise killed; when piped into a command, it will continue until the pipe breaks (i.e., the program completes its execution).

    So when you execute yes sunshine this is what you get:

    $ yes sunshine
    sunshine
    sunshine
    sunshine
    sunshine
    sunshine
    ...

    And you get a lot of sunshine then. ;)

    So what you can do with yes is that you can combine it with CLI commands and auto-respond to confirmations.

    $ yes Y | contentful-migration --space-id xxx migration.js

    There is another way to answer confirmation in a CLI automatically though. It turns out that you can also just echo and pipe the string into the command.

    $ echo yes | contentful-migration --space-id xxx migration.js

    I think that's pretty cool stuff and this will definitely help me for my next automation tasks.

  • Not every JavaScript function is constructable

    Šime Vidas recently tweeted about the object method shorthand definition. The tweet described that shorthand method defintions are not constructable and can not be used with the new keyword.

    You can’t invoke an object method as a constructor if you’ve used the shorthand syntax.

    I'm not using the new keyword very often these days but this fact surprised me. So I started digging the EcmaScript spec to figure out what differences arrow functions and the shorthand have in comparison to function property definitions.

    There are three ways to define a method in an object and they're not only syntatically different but also behave differently.

    The "constructable differences"

    Reading the specification it turns out that JavaScript objects have internal methods that define their specific behavior.

    Each object in an ECMAScript engine is associated with a set of internal methods that defines its runtime behaviour.

    There are "essential internal methods" and these range from e.g. [[GetPrototypeOf]] to [[OwnPropertyKeys]].

    When we're dealing with functions (and remember these are objects, too) there can be also "additional Essential Internal Methods" which include [[Call]] and [[Construct]]. [[Construct]] is what is used when we use new or super to create a new object.

    It turns out though that not every function includes [[Construct]] which means that not every function is a constructor function.

    Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function.

    Looking at the definition of the new operations we'll see that it is supposed to throw a TypeError whenever isConstructor is false. isContructor looks up the [[Construct]] internal method.

    If IsConstructor (constructor) is false, throw a TypeError exception.

    So, let's look at the following three lines of code and see what happens when we want to use the functions Fn, Arrow and Shorthand as a constructor:

    const example = {
      Fn: function() { console.log(this); },
      Arrow: () => { console.log(this); },
      Shorthand() { console.log(this); }
    };
    
    new example.Fn();        // Fn {}
    new example.Arrow();     // Uncaught TypeError: example.Arrow is not a constructor
    new example.Shorthand(); // Uncaught TypeError: example.Shorthand is not a constructor

    That's the surprising part of Šime's tweet.

    The definition for every function creation goes down to FunctionCreate defined in the EcmaScript spec.

    The spec for FunctionCreate is very clear:

    FunctionCreate (kind, ParameterList, Body, Scope, Strict, prototype)
    [...]
      1. If the prototype argument was not passed, then 
        a. Let prototype be the intrinsic object %FunctionPrototype%.
      2. If "kind" is not Normal, let allocKind be "non-constructor".
    [...]

    So it turns out that only functions of type Normal will be constructable and will implement [[Construct]]. Reading the spec further you'll find that arrow functions use kind Arrow and method shorthand definitions use kind Method. This results in them being a "non-constructor".

    That's it and this is where this behavior come from.

Tags for this post

Disqus loads a ton of things and I'd like to save this. If you want to comment hit the button below.

If you like this post share it or follow me on Twitter.