webpack rss解析器:未捕获的类型错误:get不是解析器中的函数,js:79:1

oxcyiej7  于 2023-02-04  发布在  Webpack
关注(0)|答案(1)|浏览(230)

我正在用Node包rss-parser做一个RSS解析器,但我认为它目前只兼容Webpack 4,因为Webpack 4自动填充Node内置,但我是一个newb.js,所以我需要帮助。你可以阅读有关Shimming in Webpack hereUpgrading Webpack from 4 to 5 here的信息。下面是放大的行(解析器:79)

let req = get(requestOpts, (res) => {

下面是整个函数。

parseURL(feedUrl, callback, redirectCount=0) {
    let xml = '';
    let get = feedUrl.indexOf('https') === 0 ? https.get : http.get;
    let urlParts = url.parse(feedUrl);
    let headers = Object.assign({}, DEFAULT_HEADERS, this.options.headers);
    let timeout = null;
    let prom = new Promise((resolve, reject) => {
      const requestOpts = Object.assign({headers}, urlParts, this.options.requestOptions);
      let req = get(requestOpts, (res) => {
        if (this.options.maxRedirects && res.statusCode >= 300 && res.statusCode < 400 && res.headers['location']) {
          if (redirectCount === this.options.maxRedirects) {
            return reject(new Error("Too many redirects"));
          } else {
            const newLocation = url.resolve(feedUrl, res.headers['location']);
            return this.parseURL(newLocation, null, redirectCount + 1).then(resolve, reject);
          }
        } else if (res.statusCode >= 300) {
          return reject(new Error("Status code " + res.statusCode))
        }
        let encoding = utils.getEncodingFromContentType(res.headers['content-type']);
        res.setEncoding(encoding);
        res.on('data', (chunk) => {
          xml += chunk;
        });
        res.on('end', () => {
          return this.parseString(xml).then(resolve, reject);
        });
      })
      req.on('error', reject);
      timeout = setTimeout(() => {
        return reject(new Error("Request timed out after " + this.options.timeout + "ms"));
      }, this.options.timeout);
    }).then(data => {
      clearTimeout(timeout);
      return Promise.resolve(data);
    }, e => {
      clearTimeout(timeout);
      return Promise.reject(e);
    });
    prom = utils.maybePromisify(callback, prom);
    return prom;
  }

以下是Chrome的堆栈跟踪:

Uncaught TypeError: get is not a function
    at Parser.js:79:1
    at new Promise (<anonymous>)
    at Parser.parseURL (Parser.js:76:1)
    at FeedRSSPrint (Popup.tsx:18:1)
    at App (Popup.tsx:30:1)
    at renderWithHooks (react-dom.development.js:16305:1)
    at mountIndeterminateComponent (react-dom.development.js:20074:1)
    at beginWork (react-dom.development.js:21587:1)
    at beginWork$1 (react-dom.development.js:27426:1)
    at performUnitOfWork (react-dom.development.js:26560:1)

//../node_modules/@types/node/https.d.ts中,在https节点包中,它的获取定义为

/**
     * Like `http.get()` but for HTTPS.
     *
     * `options` can be an object, a string, or a `URL` object. If `options` is a
     * string, it is automatically parsed with `new URL()`. If it is a `URL` object, it will be automatically converted to an ordinary `options` object.
     *
     * ```js
     * const https = require('https');
     *
     * https.get('https://encrypted.google.com/', (res) => {
     *   console.log('statusCode:', res.statusCode);
     *   console.log('headers:', res.headers);
     *
     *   res.on('data', (d) => {
     *     process.stdout.write(d);
     *   });
     *
     * }).on('error', (e) => {
     *   console.error(e);
     * });
     * ```
     * @since v0.3.6
     * @param options Accepts the same `options` as {@link request}, with the `method` always set to `GET`.
     */
    function get(options: RequestOptions | string | URL, callback?: (res: http.IncomingMessage) => void): http.ClientRequest;
    function get(url: string | URL, options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest;
    let globalAgent: Agent;
}

node_modules/@types/node/http.d.ts中定义为:

/**
     * Since most requests are GET requests without bodies, Node.js provides this
     * convenience method. The only difference between this method and {@link request} is that it sets the method to GET and calls `req.end()`automatically. The callback must take care to consume the
     * response
     * data for reasons stated in {@link ClientRequest} section.
     *
     * The `callback` is invoked with a single argument that is an instance of {@link IncomingMessage}.
     *
     * JSON fetching example:
     *
     * ```js
     * http.get('http://localhost:8000/', (res) => {
     *   const { statusCode } = res;
     *   const contentType = res.headers['content-type'];
     *
     *   let error;
     *   // Any 2xx status code signals a successful response but
     *   // here we're only checking for 200.
     *   if (statusCode !== 200) {
     *     error = new Error('Request Failed.\n' +
     *                       `Status Code: ${statusCode}`);
     *   } else if (!/^application\/json/.test(contentType)) {
     *     error = new Error('Invalid content-type.\n' +
     *                       `Expected application/json but received ${contentType}`);
     *   }
     *   if (error) {
     *     console.error(error.message);
     *     // Consume response data to free up memory
     *     res.resume();
     *     return;
     *   }
     *
     *   res.setEncoding('utf8');
     *   let rawData = '';
     *   res.on('data', (chunk) => { rawData += chunk; });
     *   res.on('end', () => {
     *     try {
     *       const parsedData = JSON.parse(rawData);
     *       console.log(parsedData);
     *     } catch (e) {
     *       console.error(e.message);
     *     }
     *   });
     * }).on('error', (e) => {
     *   console.error(`Got error: ${e.message}`);
     * });
     *
     * // Create a local server to receive data from
     * const server = http.createServer((req, res) => {
     *   res.writeHead(200, { 'Content-Type': 'application/json' });
     *   res.end(JSON.stringify({
     *     data: 'Hello World!'
     *   }));
     * });
     *
     * server.listen(8000);
     * ```
     * @since v0.3.6
     * @param options Accepts the same `options` as {@link request}, with the `method` always set to `GET`. Properties that are inherited from the prototype are ignored.
     */
    function get(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest;
    function get(url: string | URL, options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest;

当我执行console.log(get)时,它对于HTTP和HTTPS提要都是未定义的。

import Parser from '../RSS/Parser'
const http = require('http');
const https = require('https');

在此显示停止之前的错误是"未捕获的TypeError:流未定义/无法读取未定义"的属性" prototype ",我能够通过使用来自此GitHub thread的信息安装节点包" npm i--save-dev stream "来消除该错误,但我没有使用该库,所以我不知道它为什么会消除该错误。
我将rss解析器文件复制到我的项目中的//RSS文件夹中,将//index.d.ts重命名为//RSS/Parser.d.ts,在末尾添加"export default Parser",并添加//RSS/index.ts,其中包含:

import Parser from './Parser'

export default Parser

看起来这是一个很好的模块配置,但再次我是一个newb.js,所以让我知道,如果这是不正确的。
以下是我的依赖项:

"devDependencies": {
    "@material-ui/core": "^4.12.4",
    "@material-ui/icons": "^4.11.3",
    "@types/chrome": "^0.0.195",
    "@types/react": "^18.0.18",
    "@types/react-dom": "^18.0.6",
    "clean-webpack-plugin": "^4.0.0",
    "copy-webpack-plugin": "^11.0.0",
    "css-loader": "^6.7.1",
    "entities": "^4.4.0",
    "html-webpack-plugin": "^5.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "stream": "^0.0.2",
    "stream-http": "^3.2.0",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.5",
    "ts-loader": "^9.3.1",
    "typescript": "^4.7.4",
    "url": "^0.11.0",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-merge": "^5.8.0",
    "xml2js": "^0.4.23"
  }

我还必须将以下内容添加到Webpack配置中:

module.resolve: {
    extensions: ['.tsx', '.ts', '.js'],
    fallback: { "http": false, "browser": false, "https": false, 
      "stream": false, "url": false, "buffer": false, "timers": false
    }

我试着做npm i --save-dev httpnpm i --save-dev https,但是它们不是合法的npm库,所以我不确定它们是否包括在节点中。

nzrxty8p

nzrxty8p1#

问题是我没有从预建的'rss-parser.min.js'文件中加载rss-parser。当我试图编译rss-parser时,我需要为Node.JS做一些带有回退的事情,但是当你使用rss-parser.min.js文件时,你不需要这样做。我使用的是TypeScript,所以我只是将其添加到我的parser文件中,它工作得很好。

interface Enclosure {
  url: string
  length: number
  type: string
}

interface Item {
  link: string
  guid: string
  title: string
  pubDate: string
  creator: string
  summary: string
  content: string
  isoDate: string
  categories?: string[]
  contentSnippet: string 
  enclosure: Enclosure
}

相关问题