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 的问题的主要内容,如果未能解决你的问题,请参考以下文章
您如何使用带有 require 和模块导出的 npm 包作为纯 JS 库
获取 TypeError:wsc.require 不是 hyco-ws npm 包的功能