npm require 的问题

Posted

技术标签:

【中文标题】npm require 的问题【英文标题】:Issue with npm require 【发布时间】:2018-02-20 08:29:44 【问题描述】:

我正在运行一个 Nightmare.js 脚本,并在其中尝试require lodash (使用 npm 安装在本地,在 node_modules 中,在 package.json 中注册)。

index.js:

var Nightmare = require('nightmare');
var _ = require('lodash');

function getRandomInt(min, max) 
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;


function getElms(elm) 
    var elsm =  document.querySelectorAll(elm);
    return _.map(elsm, function(elem) return elem.innerhtml; );
 

var someWebsite = new Nightmare( show: false )
  .goto( ***some url*** )
  .wait(getRandomInt(2500, 5000))
  .evaluate(function () 

      var elsm =  document.querySelectorAll(***some selector***);
      return _.map(elsm, function(elem) return elem.innerHTML; );

      // return getElms(***some selector***);


  ).then(function(linkstexts) 
    console.log(linkstexts)
  );

但我明白了:

UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:1):_ 未定义

如果我取消注释并使用return getElms(***some selector***);,则会出现类似问题

这是 package.json


  "name": "nightxp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": 
    "lodash": "^4.17.4",
    "nightmare": "^2.10.0"
  ,
  "devDependencies": ,
  "scripts": 
    "test": "echo \"Error: no test specified\" && exit 1"
  ,
  "author": "",
  "license": "ISC"

我错过了什么?

更新

我尝试将 lodash 传递给浏览器范围,并以 catch() 完成, 但不知何故,lodash 变量仍然没有被传递到作用域(以hackernews 为例):

var Nightmare = require('nightmare');
var lodash = require('lodash');

function getRandomInt(min, max) 
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; 


var facebook = new Nightmare( show: false )
  .goto('https://news.ycombinator.com')
  .wait(getRandomInt(5500, 6000))
  .evaluate(  (lodash) => 
      var elsm =  document.querySelectorAll('tr td.title a.storylink');
      return lodash.map(elsm, function(elem) return elem.innerHTML; );
   , lodash).then(function(titles) 
    console.log(titles)
  ).catch(function (error) 
      console.error('Error:', error);
  );

这就是我得到的:

C:\Projects\nightmare>set DEBUG=nightmare & node index.js
  nightmare queuing process start +0ms
  nightmare queueing action "goto" for https://news.ycombinator.com +4ms
  nightmare queueing action "wait" +2ms
  nightmare queueing action "evaluate" +0ms
  nightmare running +1ms
Error: Cannot read property 'map' of undefined

【问题讨论】:

可能是因为你调用.then(...)后没有.catch(...) 见:***.com/a/41180264/3498950 未处理的承诺拒绝是因为您没有捕获。但真正的问题是为什么 _ 首先是未定义的。你确定你运行了npm install 并且它实际上在 node_modules 中? @spencer.sm 事情是,当我没有遍历数组并且只提取一个元素时,没关系。即使没有 .catch() @Mark_M 是的,lodash 在 node_modules 中。我跑了npm install lodash --save 【参考方案1】:

当你跑步时

var someWebsite = new Nightmare( show: false )
.evaluate(function () 
/* ... */

您现在处于浏览器范围内 - 您可以将 Nightmare.evaluate 视为在独立浏览器的上下文中运行包含的代码,这意味着您的全局范围(包括 _)不可用。

有关将数据传递到作用域的更多信息和一些提示,请参见此处:

https://github.com/segmentio/nightmare/issues/89

https://github.com/segmentio/nightmare/issues/333

编辑:

虽然您可以从节点上下文将简单值传递给 evaluate,但您不能通过函数和方法传递复杂值。这是因为参数在传输过程中是序列化的,这对函数来说很困难。这里有一个问题可以解释一下:

https://github.com/segmentio/nightmare/issues/349

在这种特殊情况下,似乎最简单的事情就是在没有 lodash 的情况下工作,现在这并不难。例如:

var facebook = new Nightmare( show: false )
.goto('https://news.ycombinator.com')
.wait(getRandomInt(5500, 6000))
.evaluate(  () => 
    var elsm =  document.querySelectorAll('tr td.title a.storylink');
    return Array.prototype.map.call(elsm, elem => elem.innerHTML)
)
.then(function(titles) 
    console.log("title", titles)
)
.catch(function (error) 
    console.error('Error:', error);
);

【讨论】:

我试过这个,但它仍然说它无法读取未定义的属性 'map' `.evaluate( (lodash) => var elsm = document.querySelectorAll(someselector ); return lodash.map(elsm, function(elem) return elem.innerHTML; ); , lodash) ` @tonino.j - 查看编辑,看起来像这样使用 lodash 并不容易。 您知道将事物(如函数/库)加载到浏览器上下文中的方式吗?还是只是抢夺并返回一个字符串并在外面处理它的唯一方法?

以上是关于npm require 的问题的主要内容,如果未能解决你的问题,请参考以下文章

我无法让 npm 模块与 require 一起工作?

require 没有在 npm.js:2 中定义

您如何使用带有 require 和模块导出的 npm 包作为纯 JS 库

获取 TypeError:wsc.require 不是 hyco-ws npm 包的功能

require("electron").app 未定义。我 npm 安装了新的模块。不确定该怎么做

require('bignumber.js') 在松露测试中失败,npm ls -g 显示它已安装(Windows)