1

I am getting errors on Google Dev Tools's console when I load my Angular website and make a call to a Cheerio method load('<h2 class="title">Hello world</h2>'); as shown on the Github page.

This is a brand new application, so all I've done is: sudo ng new myProject, sudo chmod -R 777 myProject/, sudo npm install cheerio --save, sudo npm install @types/cheerio --save. Also, because I have gotten errors in the TypeScript compilation in the past, I also ran: sudo npm install stream --save

Atop my app.component.ts file I call import * as cheerio from 'cheerio'; and lastly inside the component:

ngOnInit() {
  cheerio.load('<h2 class="title">Hello world</h2>');
}

Now, when I run ng serve, the exact error message I get is:

inherits_browser.js:5 Uncaught TypeError: Cannot read property 'prototype' of undefined
    at inherits (inherits_browser.js:5)
    at Object../node_modules/cheerio/node_modules/parse5/lib/parser/parser_stream.js (parser_stream.js:27)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/cheerio/node_modules/parse5/lib/index.js (index.js:41)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/cheerio/lib/parse.js (parse.js:5)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/cheerio/lib/cheerio.js (cheerio.js:5)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/cheerio/index.js (index.js:5)
inherits @ inherits_browser.js:5
./node_modules/cheerio/node_modules/parse5/lib/parser/parser_stream.js @ parser_stream.js:27
__webpack_require__ @ bootstrap:78
./node_modules/cheerio/node_modules/parse5/lib/index.js @ index.js:41
__webpack_require__ @ bootstrap:78
./node_modules/cheerio/lib/parse.js @ parse.js:5
__webpack_require__ @ bootstrap:78
./node_modules/cheerio/lib/cheerio.js @ cheerio.js:5
__webpack_require__ @ bootstrap:78
./node_modules/cheerio/index.js @ index.js:5
__webpack_require__ @ bootstrap:78
./src/app/app.component.ts @ main.js:94
__webpack_require__ @ bootstrap:78
./src/app/app.module.ts @ app.component.ts:10
__webpack_require__ @ bootstrap:78
./src/main.ts @ main.ts:1
__webpack_require__ @ bootstrap:78
0 @ main.ts:12
__webpack_require__ @ bootstrap:78
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.js:1

Additionally, if you're going to recommend to instead put import { load } from 'cheerio'; atop the file, I have tried this as well, and the same error appears.

These are the versions of my tools (they're all the latest or very close). Angular CLI: 7.3.6 Node: 11.12.0 OS: darwin x64 Angular: 7.2.11

Edit: I have tried the solution in Adding Cheerio.js to an Angular 6 project?, and it did not solve the problem, in fact it added another error in the console:

cheerio.js:5 Uncaught ReferenceError: require is not defined
    at cheerio.js:5
Arshaan
  • 11
  • 1
  • 4
  • Duplicate? https://stackoverflow.com/questions/52580570/adding-cheerio-js-to-an-angular-6-project – Marcel Lamothe Mar 27 '19 at 20:29
  • Possible duplicate of [Adding Cheerio.js to an Angular 6 project?](https://stackoverflow.com/questions/52580570/adding-cheerio-js-to-an-angular-6-project) – nircraft Mar 27 '19 at 20:36
  • I have actually tried the above links (they're the same link) and it doesn't solve the problem. I updated the bottom of my question to mention that I tried the link MarcelLamothe and nircraft mentioned. – Arshaan Mar 27 '19 at 20:40
  • cheerio is a backend library. You probably want jQuery – pguardiario Mar 27 '19 at 23:11

2 Answers2

3

I also wanted to use cheerio with Angular and just adding the package didn't do the job. The problem was missing NodeJS dependencies. Cheerio uses some NodeJS Core features which are not automatically in your browser.

To get it working I had to include some packages, add some lines to the "polyfill.ts" and add something to the "tsconfig.json"

My solution:

Firstly, I included the following packages with npm:

  • stream-browserify
  • string_decoder
  • events
  • buffer
  • process

One-liner:

npm install stream-browserify string_decoder events buffer process

It is possible that you won't need every one of those packages though.

Then I added the following lines to "polyfill.ts":

// cheerio nodejs emulating imports
import * as process from 'process';
window['process'] = process;

(window as any).global = window;
var global = global || window;

import * as bufferModule from "buffer"
global.Buffer = global.Buffer || bufferModule.Buffer;

This is a mixture of solutions to answers for related issues and questions I found. Here they are:

And my last step was adding a path for the stream module in the "tsconfig.json" to map it to the stream-browserify package in node-modules: (As seen in this answer)

tsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "stream": [
        "node_modules/stream-browserify"
      ]
    }
  }
}

I edited the "tsconfig.json" at the root (the same directory as the "package.json").

Notes and insights

Possibly related issues

Lukas Bühler
  • 33
  • 1
  • 8
0

I'm not familiar with the cheerio library. I have created a StackBlitz example of how to get this to work though.

The project required me to install a few packages with npm as follows: npm install cheerio @types/cheerio events string_decoder

Then in the app.component.ts I imported it with: import * as cheerio from 'cheerio'; and used it in the ngOnInit method as follows: cheerio.load('<h2 class="title">Hello world</h2>').xml();

peinearydevelopment
  • 11,042
  • 5
  • 48
  • 76
  • I copied your exact steps, and when I run it, it still gives the first error I mentioned above. This is extremely odd, everything I'm using is up to date. – Arshaan Mar 27 '19 at 21:04
  • I think for now I'll just have to create my apps on StackBlitz and export them to my local environment. Thanks for whipping this solution up. Also, can I ask how you knew to also npm install `events` and `string_decoder` for this to work? – Arshaan Mar 27 '19 at 21:20