javascripttypescriptdecoratortypescript-decoratorquokka.js

Can't get quokka.js working with TypeScript 5.x and ES Decorators


I'm trying to run quokka.js in VSCode against a simple TypeScript file with the following decorator:

function message<Input extends new (...args: any) => any>(msg: string) {
    return function (value: Input, context: ClassDecoratorContext) {
    // remaining code removed for brevity...

Here is the consuming class:

@message("Hello from the employee class")
export class Employee {
    public firstName: string;

So a couple of notes, this code does transpile using the tsc command, and the resulting transpiled .js file does work with quokka.js. However, if I run quokka.js on the TypeScript file itself (start on current file), quokka will fail with the following:

​​​​​Quokka 'Decorators.ts' (node: v18.16.0, TypeScript: v5.3.3)​​​​ Failed to instrument scripts/typescript/Advanced/Decorators.js  47 | var ESDecorators;  48 | (function (ESDecorators) { 

49 | @message("Hello from the employee class")  | ^ SyntaxError: Unexpected character '@' (49:4)

Notice it's using TypeScript 5.3.3 shown in the error message which does work with ES Decorators. In fact I've used the following quokka.js configuration in package.json to ensure it's using this version locally installed, and not using swc, babel, or anything else:

  "quokka": { 
    "ts": {
      "compiler": "typescript",
      "swc": false
    }
  }

With TypeScript 5.x+, you also don't need the legacy experimentalDecorators flags turned on so the following is commented out in tsconfig.json:

// "experimentalDecorators": true,
// "emitDecoratorMetadata": true, 

So just to level set, the code works, transpiles with the TypeScript compiler, and valid JavaScript is omitted. That indicates a syntactically correct code sample. The problem is only with quokka.js running the TypeScript file directly. Even though it's using TypeScript 5.3.3 as displayed in the error, it cant understand the @ synatax of Decorators. My research has yielded nothing, and this should work. What do I need to do please to make this ES Decorator code work while running quokka.js?


Solution

  • I figured this out and it was not quokka specific but rather with the TypeScript configuration. Ironically esnext even though supposed to point to the latest and greatest spec, actually has this nuance and can't be run as-is:

    "using any new JavaScript features that are not yet officially part of an ECMAScript standard, but are in a draft stage (i.e. Stage 3 Decorators), those features will be left as is"

    Therefore if I use the older es2018 the decorators work as expected. Per the behavior:

    "Any newer JavaScript features used in your TypeScript code that are not part of ECMAScript 2016 will be transpiled down to equivalent ECMAScript 2018 syntax"

    In this case the decorators are transpiled and work correctly so long as it can be transpiled to compatible JS that will run today.