cheeriojs / cheerio

The fast, flexible, and elegant library for parsing and manipulating HTML and XML.
https://cheerio.js.org
MIT License
28.67k stars 1.64k forks source link

How is current support for react-native? #1169

Closed lattice0 closed 3 years ago

lattice0 commented 6 years ago

I'm following https://github.com/cheeriojs/cheerio/issues/1058 and I discovered https://github.com/oyyd/cheerio-without-node-native which works but is a fork.

I then tried to install events, stream and utils as mentioned, and also had to install buffer. I now get

undefined is not an object (evaluating superCtor.prototype)

https://imgur.com/a/VSukm

RLesser commented 6 years ago

I've run into the same issue as above. Is this something that will ever be fixed? It seems like a dependency issue and I'm unsure how difficult it would be to provide support for react native dependencies.

fb55 commented 6 years ago

PRs welcome :)

liamjones commented 6 years ago

The only thing I had to do was cut out the streaming related exports at the bottom of the parser5 module's index.js for this to work in RN (since I'm not using them). I'm doing that automatically after install via https://github.com/ds300/patch-package

jmasaki24 commented 6 years ago

The only thing I had to do was cut out the streaming related exports at the bottom of the parser5 module's index.js for this to work in RN (since I'm not using them). I'm doing that automatically after install via https://github.com/ds300/patch-package

I got all the way to node_modules/parse5/lib/index.js (i had to npm install util and utils), but I couldn't find the 'streaming related exports'. There is an index.d.ts file with an "export class serializerstream extends stream.readable" at the very bottom. After commenting out that section, I cannot run patch-package, is says "patch-package requires git". I ran it anyway, and get an: undefined is not a function (evaluating '_iterator2[typeof Symbol === "function"? symbol.iterator: "@@iterator"]()').

what should I do!?

npm: 6.5.2 cheerio-without-node-native: 1.0.0-rc.2 react: 16.5.0 react-native: 0.57.3 image

NightFarmer commented 6 years ago

The only thing I had to do was cut out the streaming related exports at the bottom of the parser5 module's index.js for this to work in RN (since I'm not using them). I'm doing that automatically after install via https://github.com/ds300/patch-package

I got all the way to node_modules/parse5/lib/index.js (i had to npm install util and utils), but I couldn't find the 'streaming related exports'. There is an index.d.ts file with an "export class serializerstream extends stream.readable" at the very bottom. After commenting out that section, I cannot run patch-package, is says "patch-package requires git". I ran it anyway, and get an: undefined is not a function (evaluating '_iterator2typeof Symbol === "function"? symbol.iterator: "@@iterator"').

what should I do!?

npm: 6.5.2 cheerio-without-node-native: 1.0.0-rc.2 react: 16.5.0 react-native: 0.57.3 image

I suggest you give up this idea, js is very inefficient, parsing html in RN will cause UI to be stuck, then I tried react-native-threads, although the UI is not stuck, but the waiting time will exceed the user's patient.
Now I use flutter instead of RN, which works well.

liamjones commented 6 years ago

I got all the way to node_modules/parse5/lib/index.js (i had to npm install util and utils), but I couldn't find the 'streaming related exports'.

what should I do!?

@jmasaki24 - this is the change I made to parse5 via patch-package: https://gist.github.com/liamjones/ae7f6f6ae6139fd4a8931f43a052b517

Maskedman99 commented 5 years ago

I was trying to get around #1058 and I found a solution but it involves the original cheerio module rather than the fork

$ npm i cheerio@0.22.0 $ npm i events stream buffer

I found the solution at https://www.jianshu.com/p/ddf574337c47 , you have to translate the page as its in foreign language.

 const cheerio = require("cheerio"); 
 let $ = cheerio.load('<h2 class="title">Hello world</h2>')
 console.log($("h2").text());

the above code works smooth. but,

const response = fetch('http://github.com') const $ = cheerio.load(response.text()) gives error Can't find variable: buffer

micheilsgrey commented 4 years ago

I was trying to get around #1058 and I found a solution but it involves the original cheerio module rather than the fork

$ npm i cheerio@0.22.0 $ npm i events stream buffer

I found the solution at https://www.jianshu.com/p/ddf574337c47 , you have to translate the page as its in foreign language.

 const cheerio = require("cheerio"); 
 let $ = cheerio.load('<h2 class="title">Hello world</h2>')
 console.log($("h2").text());

the above code works smooth. but,

const response = fetch('http://github.com') const $ = cheerio.load(response.text()) gives error Can't find variable: buffer

What's funny is that i did all as in that guide. And the only way all worked is when i debug project through the IDE VSCode. Otherwise all the time getting same error. Release version not helped too.

Maskedman99 commented 4 years ago

I couldn't get cheerio to work in react-native, so I searched for something else for weeks and came across this comment in reddit https://www.reddit.com/r/reactnative/comments/9b08oj/a_frustrated_developer/e4zzsrb/. u/heo5981 suggested https://github.com/ashi009/node-fast-html-parser and was also kind enough to show me an example on how to parse the HTML with it. If anyone is interested, I can add an example.

micheilsgrey commented 4 years ago

I couldn't get cheerio to work in react-native, so I searched for something else for weeks and came across this comment in reddit https://www.reddit.com/r/reactnative/comments/9b08oj/a_frustrated_developer/e4zzsrb/. u/heo5981 suggested https://github.com/ashi009/node-fast-html-parser and was also kind enough to show me an example on how to parse the HTML with it. If anyone is interested, I can add an example.

I replaced cheeriowith cheerio-without-node-native and all working fine now.

ospfranco commented 4 years ago

cheerio-without-node-native is kinda abandonware at this point, I'm the creator of link-preview-js and I'm getting security warnings, it would be nice to know if there is a path forward here

micheilsgrey commented 4 years ago

I couldn't get cheerio to work in react-native, so I searched for something else for weeks and came across this comment in reddit https://www.reddit.com/r/reactnative/comments/9b08oj/a_frustrated_developer/e4zzsrb/. u/heo5981 suggested https://github.com/ashi009/node-fast-html-parser and was also kind enough to show me an example on how to parse the HTML with it. If anyone is interested, I can add an example.

I replaced cheeriowith cheerio-without-node-native and all working fine now.

UPDATE: after I upgrade to react-native 0.63.2 from 0.61.4 buffer issue came back even with cheerio-without-node-native

matthewmueller commented 4 years ago

Can someone summarize the problem? Is the problem that React Native doesn't support node.js modules that cheerio depends on? Modules like events & stream?

ospfranco commented 4 years ago

Can someone summarize the problem? Is the problem that React Native doesn't support node.js modules that cheerio depends on? Modules like events & stream?

yes

matthewmueller commented 4 years ago

Okay, I've done a quick search through the source tree. Cheerio's source doesn't rely on any Node.js standard modules.

index.js
8:var staticMethods = require('./lib/static');
10:exports = module.exports = require('./lib/cheerio');
17:exports.version = require('./package.json').version;

test/xml.js
1:var expect = require('expect.js'),
2:    cheerio = require('..'),
4:      extend: require('lodash/assignIn'),

test/parse.js
1:var expect = require('expect.js'),
2:    assign = require('lodash/assign'),
3:    parse = require('../lib/parse'),
4:    defaultOpts = require('../lib/options').default;

lib/options.js
1:var assign = require('lodash/assign');

lib/utils.js
1:var cloneDeepWith = require('lodash/cloneDeepWith');

test/api/deprecated.js
6:var expect = require('expect.js'),
7:    fixtures = require('../fixtures'),
8:    cheerio = require('../..');

lib/static.js
1:var htmlparser2Adapter = require('parse5-htmlparser2-tree-adapter');
11:var serialize = require('dom-serializer').default;
12:var defaultOptions = require('./options').default;
13:var flattenOptions = require('./options').flatten;
14:var select = require('css-select');
15:var parse5 = require('parse5');
16:var parse = require('./parse');
18:  merge: require('lodash/merge'),
19:  defaults: require('lodash/defaults'),
38:  var Cheerio = require('./cheerio');

test/api/manipulation.js
1:var expect = require('expect.js'),
2:    cheerio = require('../..'),
3:    fruits = require('../fixtures').fruits,

test/api/utils.js
1:var expect = require('expect.js'),
2:    fixtures = require('../fixtures'),
3:    cheerio = require('../..');

test/api/css.js
1:var expect = require('expect.js');
2:var cheerio = require('../..');

test/api/forms.js
1:var expect = require('expect.js'),
2:    cheerio = require('../..'),
3:    forms = require('../fixtures').forms;

test/api/attributes.js
1:var expect = require('expect.js');
3:var cheerio = require('../..');
4:var fruits = require('../fixtures').fruits;
5:var vegetables = require('../fixtures').vegetables;
6:var food = require('../fixtures').food;
7:var chocolates = require('../fixtures').chocolates;
8:var inputs = require('../fixtures').inputs;

benchmark/suite.js
1:var fs = require('fs');
2:var path = require('path');
4:var Benchmark = require('benchmark');
5:var JSDOM = require('jsdom').JSDOM;
6:var Script = require('vm').Script;
7:var cheerio = require('..');

lib/parse.js
4:var htmlparser = require('htmlparser2');
5:var parse5 = require('parse5');
6:var htmlparser2Adapter = require('parse5-htmlparser2-tree-adapter');

benchmark/benchmark.js
3:var Suites = require('./suite');

lib/api/forms.js
14:      map: require('lodash/map'),

docs/template/publish.js
3:var doop = require('jsdoc/util/doop');
4:var env = require('jsdoc/env');
5:var fs = require('jsdoc/fs');
6:var helper = require('jsdoc/util/templateHelper');
7:var logger = require('jsdoc/util/logger');
8:var path = require('jsdoc/path');
9:var taffy = require('taffydb').taffy;
10:var template = require('jsdoc/template');
11:var util = require('util');
302:                        symbol.name = symbol.name.replace('module:', '(require("') + '"))';
525:        staticFileFilter = new (require('jsdoc/src/filter')).Filter(conf.default.staticFiles);
526:        staticFileScanner = new (require('jsdoc/src/scanner')).Scanner();

lib/cheerio.js
6:var parse = require('./parse'),
7:    defaultOptions = require('./options').default,
8:    flattenOptions = require('./options').flatten,
9:    isHtml = require('./utils').isHtml,
11:      extend: require('lodash/assignIn'),
12:      bind: require('lodash/bind'),
13:      forEach: require('lodash/forEach'),
14:      defaults: require('lodash/defaults'),
21:  require('./api/attributes'),
22:  require('./api/traversing'),
23:  require('./api/manipulation'),
24:  require('./api/css'),
25:  require('./api/forms'),

lib/api/manipulation.js
10:var parse = require('../parse'),
11:    html = require('../static').html,
12:    text = require('../static').text,
15:    utils = require('../utils'),
21:      flatten: require('lodash/flatten'),
22:      bind: require('lodash/bind'),
23:      forEach: require('lodash/forEach'),

test/api/traversing.js
2:var expect = require('expect.js'),
3:    cheerio = require('../..'),
4:    food = require('../fixtures').food,
5:    fruits = require('../fixtures').fruits,
6:    drinks = require('../fixtures').drinks,
7:    text = require('../fixtures').text;

lib/api/traversing.js
10:var select = require('css-select'),
11:    utils = require('../utils'),
13:    uniqueSort = require('htmlparser2').DomUtils.uniqueSort,
16:      bind: require('lodash/bind'),
17:      forEach: require('lodash/forEach'),
18:      reject: require('lodash/reject'),
19:      filter: require('lodash/filter'),
20:      reduce: require('lodash/reduce'),

lib/api/attributes.js
10:var text = require('../static').text,
11:    utils = require('../utils'),
20:      forEach: require('lodash/forEach'),
21:      extend: require('lodash/assignIn'),
22:      some: require('lodash/some'),

lib/api/css.js
8:var domEach = require('../utils').domEach,
10:      pick: require('lodash/pick'),

test/cheerio.js
1:var expect = require('expect.js'),
2:    htmlparser2 = require('htmlparser2'),
3:    cheerio = require('../'),
4:    fixtures = require('./fixtures'),
8:      filter: require('lodash/filter'),

In principle, cheerio is just a text processor, so it doesn't really need to depend on events or stream.

In practice, we have some dependencies that are useful outside of cheerio. I'd suggest figuring out which dependencies are causing problems, then we can decide what to do about them.

liamjones commented 4 years ago

@matthewmueller It was parse5's streaming related dependencies which were causing the issue for us. By removing the streaming-based parts of cheerio (see https://github.com/cheeriojs/cheerio/issues/1169#issuecomment-430909780) it functioned in RN fine for us.

micheilsgrey commented 4 years ago

react-native-cheerio working fine with react-native 0.63.2.

fb55 commented 3 years ago

cheerio@1.0.0-rc.5 should resolve this issue. Both parse5 and htmlparser2 had their native dependencies removed as far as I can tell; would love it if someone could have another try!

fb55 commented 3 years ago

Closing this for now. Will reopen should someone report issues.

ospfranco commented 3 years ago

I just tested it and it seems to be working! thanks @fb55! 🎉🎉🎉🎉

fb55 commented 3 years ago

Awesome, thanks for testing!

iamshrikantjha commented 1 year ago

It's working. ❤️

carbopilot commented 3 months ago

Broken again in the new release. :(

cimpianRadu commented 2 months ago

I can confirm that it is not working for react-native... 😢

Screenshot 2024-08-21 at 09 53 48