taoqf / node-html-parser

A very fast HTML parser, generating a simplified DOM, with basic element query support.
MIT License
1.11k stars 107 forks source link

Problem with loading as ECMAScript module (ESM) #149

Closed AgainPsychoX closed 3 years ago

AgainPsychoX commented 3 years ago

Problem

I wanted to use the package in project that is using the modules (ECMAScript Modules / ESM / `"type": "module").

Sadly I can't:

import { parse } from "node-html-parser";
         ^^^^^
SyntaxError: Named export 'parse' not found. The requested module 'node-html-parser' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'node-html-parser';
const { parse } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:179:5)
    at async Loader.import (node:internal/modules/esm/loader:178:24)
    at async Object.loadESM (node:internal/process/esm_loader:68:5)
    at async handleMainPromise (node:internal/modules/run_main:63:12)

Despite the building process includes outputting esm files, they are not recognized (by anything).

Environment

module version: 4.1.4 node version: 16.9.0 npm version: 7.21.1

elijaholmos commented 3 years ago

I am having this error as well

taoqf commented 3 years ago

I have no idea about this issue, but you can use:

import parse from 'node-html-parser';

to avoid this.

AgainPsychoX commented 3 years ago

@taoqf Sadly it does not work while using from ES module...

Exports from CJS modules work in ES module, but default isn't working like it used to do in CJS.

import parse from "node-html-parser";
console.log(parse);
const test = parse('<div>test</div>');
console.log(test);
{
  CommentNode: [Getter],
  HTMLElement: [Getter],
  parse: [Getter],
  default: [Getter],
  valid: [Getter],
  Node: [Getter],
  TextNode: [Getter],
  NodeType: [Getter]
}
TypeError: parse is not a function
AgainPsychoX commented 3 years ago

Only way to do it without the #150 would be like below:

import NodeHTMLParser from "node-html-parser";
// @ts-ignore
const { parse } = NodeHTMLParser;
console.log(parse);
const test = parse('<div>test</div>');
console.log(test);
[Function: parse]
<ref *1> HTMLElement {
  parentNode: null,
  childNodes: [
    HTMLElement {
      parentNode: [Circular *1],
      childNodes: [Array],
      rawAttrs: '',
      nodeType: 1,
      rawTagName: 'div',
      id: '',
      classList: [DOMTokenList]
    }
  ],
  rawAttrs: '',
  nodeType: 1,
  rawTagName: null,
  id: '',
  classList: DOMTokenList {
    _set: Set(0) {},
    _afterUpdate: [Function (anonymous)]
  }
}

but please note, it does not work properly with Typescript (hence the ts-ignore to supress error).

Even with the error suppression, the types does not working anymore (everything stays any). Many codebases rules disallow using explicit any, so it's very annoying.

nonara commented 3 years ago

I will be addressing this by adding a workable ESM output. Follow the issue below for updates. Closing this as duplicate

Main Issue: