由于“TypeError:undefined不是函数”,sbt和scala.js(使用Node.
当我使用sbt,scala.js运行时,我需要一个错误的帮助,这是一个在Node.js上的本地
javascript代码.
[info] Running net.walend.graph.results.PlotTime Hello from scala [error] /Users/dwalend/projects/ScalaGraphMinimizer/toGhPages/target/scala-2.11/toghpages-fastopt.js:1854 [error] $g["hello"](); [error] ^ [error] TypeError: undefined is not a function [error] at $c_Lnet_walend_graph_results_PlotTime$.main__V (/Users/dwalend/projects/ScalaGraphMinimizer/toGhPages/target/scala-2.11/toghpages-fastopt.js:1854:14) [error] at $c_Lnet_walend_graph_results_PlotTime$.$$js$exported$meth$main__O (/Users/dwalend/projects/ScalaGraphMinimizer/toGhPages/target/scala-2.11/toghpages-fastopt.js:1861:8) [error] at $c_Lnet_walend_graph_results_PlotTime$.main (/Users/dwalend/projects/ScalaGraphMinimizer/toGhPages/target/scala-2.11/toghpages-fastopt.js:1864:15) [error] at Object.<anonymous> (/Users/dwalend/projects/ScalaGraphMinimizer/toGhPages/target/scala-2.11/toghpages-launcher.js:2:107) [error] at Module._compile (module.js:460:26) [error] at Object.Module._extensions..js (module.js:478:10) [error] at Module.load (module.js:355:32) [error] at Function.Module._load (module.js:310:12) [error] at Module.require (module.js:365:17) [error] at require (module.js:384:17) org.scalajs.jsenv.ExternalJSEnv$NonZeroExitException: node.js exited with code 1 at org.scalajs.jsenv.ExternalJSEnv$AbstractExtRunner.waitForVM(ExternalJSEnv.scala:96) at org.scalajs.jsenv.ExternalJSEnv$ExtRunner.run(ExternalJSEnv.scala:143) at org.scalajs.sbtplugin.ScalaJSPluginInternal$.org$scalajs$sbtplugin$ScalaJSPluginInternal$$jsRun(ScalaJSPluginInternal.scala:479) at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$45$$anonfun$apply$27$$anonfun$apply$28.apply(ScalaJSPluginInternal.scala:539) at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$45$$anonfun$apply$27$$anonfun$apply$28.apply(ScalaJSPluginInternal.scala:533) at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47) 我最怀疑我的build.sbt. (它在一个没有scala.js的子项目中.)我想我有一些关节,但不知道要尝试的其他设置. scalaVersion := "2.11.7" scalacOptions ++= Seq("-unchecked","-deprecation","-feature") libraryDependencies ++= Seq( "org.scala-js" %%% "scalajs-dom" % "0.8.1" ) //don't need phantomjs . //jsDependencies += RuntimeDOM jsDependencies += "org.webjars" % "d3js" % "3.5.5-1" / "d3.min.js" jsDependencies += ProvidedJS / "algorithmTime.js" scalaJSStage in Global := FastOptStage persistLauncher := true 我甚至无法通过Node.js从algorthmTime.js中获得“问候”. function hello() { console.log("hello from js") } Scala中的main()很漂亮: object PlotTime扩展js.JSApp { def main(): Unit = { println("Hello from scala") global.hello() val png = global.dataToPng("benchmark/results/v0.1.2/dijkstra.csv") println(png) } } 在尝试Node.js之前,我进一步使用了phantom.js和Rhino. sbt run进入我的本地javascript代码并在d3内部停止 [info] Running net.walend.graph.results.PlotTime Hello from scala hello from js org.mozilla.javascript.EcmaError: TypeError: Cannot call method "querySelector" of undefined (/Users/dwalend/.ivy2/cache/org.webjars/d3js/jars/d3js-3.5.5-1.jar#META-INF/resources/webjars/d3js/3.5.5/d3.min.js#3) at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3701) at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3679) at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3707) at org.mozilla.javascript.ScriptRuntime.typeError2(ScriptRuntime.java:3726) at org.mozilla.javascript.ScriptRuntime.undefCallError(ScriptRuntime.java:3743) at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2269) at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2262) at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:1317) at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:815) at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:109) at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394) at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3102) at org.mozilla.javascript.InterpretedFunction.exec(InterpretedFunction.java:120) at org.mozilla.javascript.Context.evaluateString(Context.java:1078) at org.scalajs.jsenv.rhino.package$ContextOps$.evaluateFile$extension(package.scala:21) at org.scalajs.jsenv.rhino.RhinoJSEnv.org$scalajs$jsenv$rhino$RhinoJSEnv$$internalRunJS(RhinoJSEnv.scala:157) at org.scalajs.jsenv.rhino.RhinoJSEnv$Runner.run(RhinoJSEnv.scala:62) at org.scalajs.sbtplugin.ScalaJSPluginInternal$.org$scalajs$sbtplugin$ScalaJSPluginInternal$$jsRun(ScalaJSPluginInternal.scala:479) at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$45$$anonfun$apply$27$$anonfun$apply$28.apply(ScalaJSPluginInternal.scala:539) at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$45$$anonfun$apply$27$$anonfun$apply$28.apply(ScalaJSPluginInternal.scala:533) at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47) [trace] Stack trace suppressed: run last toGhPages/compile:run for the full output. java.lang.RuntimeException: Exception while running JS code: TypeError: Cannot call method "querySelector" of undefined (/Users/dwalend/.ivy2/cache/org.webjars/d3js/jars/d3js-3.5.5-1.jar#META-INF/resources/webjars/d3js/3.5.5/d3.min.js#3) at scala.sys.package$.error(package.scala:27) at org.scalajs.jsenv.rhino.RhinoJSEnv.org$scalajs$jsenv$rhino$RhinoJSEnv$$internalRunJS(RhinoJSEnv.scala:173) at org.scalajs.jsenv.rhino.RhinoJSEnv$Runner.run(RhinoJSEnv.scala:62) at org.scalajs.sbtplugin.ScalaJSPluginInternal$.org$scalajs$sbtplugin$ScalaJSPluginInternal$$jsRun(ScalaJSPluginInternal.scala:479) at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$45$$anonfun$apply$27$$anonfun$apply$28.apply(ScalaJSPluginInternal.scala:539) at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$45$$anonfun$apply$27$$anonfun$apply$28.apply(ScalaJSPluginInternal.scala:533) at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47) 这个错误表明我的代码正在做它应该做的事情.然而,互联网智慧说chasing in Rhino “querySelector” is a dead end and Node.js is a better choice. 我怀疑我在系统中缺少一些sbt开关,但不知道还有什么要寻找的. 我也看不出它应该如何运作.我是javascript的新手,但我不知道这些javascript文件中的任何一个如何依赖于任何生成的文件中的任何其他文件. (scala.js’s tutorial上的示例使用index.html页面中的脚本标记将所有内容链接在一起.) > tree toGhPages/target/scala-2.11/ toGhPages/target/scala-2.11/ ├── classes │?? ├── JS_DEPENDENCIES │?? ├── algorithmTime.js │?? └── net │?? └── walend │?? └── graph │?? └── results │?? ├── PlotTime$.class │?? ├── PlotTime$.sjsir │?? └── PlotTime.class ├── toghpages-fastopt.js ├── toghpages-fastopt.js.map └── toghpages-jsdeps.js 大图:我正在尝试使用sbt,scala.js和d3为scala图算法库创建性能图表.第一批图表看起来很有希望,但github不支持README.md页面上的javascript.为此,我需要一个简单的图像.我想了解更多有关scala.js和d3的信息,它吸引了我这种方法. 解决方法
快速解决
要在Node.js中工作,请不要正确声明要显示的成员(即没有var或命名函数): hello = function() { console.log("hello from js") }; 这是一个可怕的黑客,但将解决algorithmTime.js的包含问题.最后“适当”的解决方案. 背景 在一般情况下编写不同的JavaScript文件很难,因为没有标准化的方法.传统的HTML-include标签只具有连接所有代码的语义.这是我们尝试在Scala.js运行器中模拟的语义. 但是,Node.js使用CommonJS模块系统.在该系统中,库显式地导出成员,而使用站点将它们放入命名空间.这避免了命名冲突. 例: // Library (foo.js) exports.foo = function() { return 1; }; // Using code var lib = require("foo.js"); lib.foo() // returns 1 这允许库声明本地值而不会将它们泄漏到调用者中. (请注意:虽然我们在这里有一个名为require的函数,但这不是RequireJS). 但是,在Scala.js跑步者中,我们需要“只包括”foo.js,这就带来了挑战.我们应该为require调用的结果使用什么名称?这就是commonJSName的含义(例如见下文). 如果未设置给定依赖项的commonJSName,则在Node.js运行器中,我们将仅发出 require(<name.js>); 没有将它分配给任何东西. (为什么不直接转储你说的文件?再见合理的堆栈跟踪). 这在Node.js中有一个非常有趣的效果.考虑以下文件(bar.js): var a = 1; b = 2; 现在我们做: require("bar.js") console.log(a); // undefined console.log(b); // 2 似乎b泄漏到全局环境中而a则没有泄漏.这就是quickfix工作的原因. 解决方案 要获得更好的解决方案,您有两种选择: >提交Node.js,编写特定于其模块系统的库 解决方案1 modules.exports = function() { console.log("hello from js") }; 将commonJSName添加到您的依赖项: jsDependencies += ProvidedJS / "algorithmTime.js" commonJSName "hello" 除了Node.js之外,这将失败,原因有两个: > JS VM可能不支持CommonJS样式包含 解决方案2 自动侦测: var hello = {}; // Scope to prevent leakage (function(exp) { hello.hello = function() { console.log("hello from js"); } })(exports ? exports : hello); 在这种情况下,您还需要设置commonJSName. 此外,您可能已经从代码中怀疑这需要您有一个额外的间接,因为CommonJS要求顶级导出为对象(IIRC).因此,您需要调整Scala.js代码: global.hello.hello(); 但是,如果您的库导出多个符号,无论如何这可能是一个好主意.此外,这可能适用于大多数JS环境(并且应该在我们使用Scala.js提供的三种环境中工作). 结语 我们(Scala.js团队)对这种情况非常不满,因为我们认为包含JS库应该像依赖JVM域中的其他Scala和/或Java库一样简单.但是,我们还没有找到更好的解决方案来支持每种包含方式,这是一个巨大的设计,工程和维护工作(如果系统发生变化或新系统出现怎么办?). 相关讨论:#457和#706. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |