Dorad
Dorad

Reputation: 3682

ReferenceError: Node is not defined (trying to use Node interface in typescript function in nodejs application)

While extending Cheerio library, I implemented the following static function (other extension functions work fine):

$.nodeType = function (elem: CheerioElement): number {
    switch (elem.type) {
        case "comment":
            return Node.COMMENT_NODE; // <--- it fails here
        case "tag":
            return Node.ELEMENT_NODE; // <--- it fails here
        case "text":
            return Node.TEXT_NODE;    // <--- it fails here
        default:
            return -1;
    }
};

The following error appears during runtime (compilation with tsc -b succeed):

ReferenceError: Node is not defined

Node interface is part of the DOM API. Thus, I realized the need of explicitly include the DOM API under compilerOptions section of tsconfig.json.

However, I still get that runtime error.

Minimal relevant part of tsconfig.json:

{
    "compilerOptions": {
        "baseUrl": ".",
        "incremental": true,
        "lib": [
            "esnext",
            "dom"
        ],
        "module": "commonjs",
        "noImplicitAny": true,
        "outDir": "./lib/",
        "sourceMap": true,
        "target": "esnext",
        "watch": true
    },
    "include": [
        "./src/**/*.ts",
    ]
}

I thought of explicitly import Node lib in the specific .ts file which contains the function, but I didn't find any "include-able" standard DOM lib.

Upvotes: 8

Views: 3011

Answers (2)

bmaupin
bmaupin

Reputation: 16015

lorefnon explained the problem; here's a slightly hacky way to fix it:

  1. Install jsdom

    npm install jsdom
    
  2. Add this to the top of your file:

    const { JSDOM } = require('jsdom'); // or import { JSDOM } from 'jsdom';
    const Node = new JSDOM('').window.Node;
    

Upvotes: 1

lorefnon
lorefnon

Reputation: 13115

Including a typescript lib doesn't polyfill the feature in an environment where it is not available.

While including "dom" type definitions will make the types available (at the compile time), but it doesn't actually make the Node API (typically provided by the browser runtime) available at runtime.

If you really need this functionality at runtime, you will need to also include an implementation of DOM for node.js such as jsdom which provides this API.

Upvotes: 2

Related Questions