Search code examples
node.jstypescript

Typescript adds plain export statement


I am building some typescript/react console app for Node.js.

If there is any import module in the source code it adds the export {}; into the output.

How I can get rid of the stuff please?

I use

  • typescript 4.1.2
  • ts-node
  • tsconfig:
{
    "compilerOptions": {
        "module": "ESNext",
        "jsx": "react",
        "esModuleInterop": true,
        "moduleResolution": "node",
        "skipLibCheck": true,
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "node_modules",
    ]
}

Source code:

import { useState, useEffect } from "react";
console.log("aaa");

Output:

console.log("aaa");
export {}; // <------ the problem

Fun fact: when I remove the import, the export disappear.


Solution

  • With the introduction of modules in ECMAScript 2015, ECMAScript has been split into two slightly incompatible languages: Scripts and Modules. However, there is no way to explicitly mark a resource as either a Script or a Module in-band. The only way to do that is out-of-band, e.g. via HTTP Content-Types or a command line flag that explicitly tells the ECMAScript engine to interpret the file as a Module.

    So, in order to make it clear to the ECMAScript execution engine, that this is, in fact, a Module not a Script, the only way is to make sure that the resource can only legally interpreted as a Module and not a Script.

    An empty export statement serves that purpose, since it is illegal in Scripts but has no side-effects.

    Long story short: you cannot remove the export statement, because that will make the file ambiguous: it is impossible to tell from the source code alone whether the file is a Script or a Module. And for reasons of backwards-compatibility, most ECMAScript engines interpret ambiguous resources as Scripts. (A more strict engine might reject the file altogether, which is also not what you want.)

    So, if you remove the export statement, your file will no longer be interpreted as a Module. However, the TypeScript source file is a Module (because it contains an import statement), therefore the compiler must emit the export statement in order to ensure that the compiled file is also a Module.