You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Scalatest测试Scala.js+Slinky React Native应用报错求助

问题描述

我正尝试用Slinky创建React Native应用,并用Scala.js版的Scalatest运行测试。build.sbt的依赖配置如下:

scalaVersion := "2.13.8"

libraryDependencies += "me.shadaj" %%% "slinky-native" % "0.7.0"
libraryDependencies += "me.shadaj" %%% "slinky-hot" % "0.7.0"
libraryDependencies += "org.scalatest" %%% "scalatest" % "3.2.13" % "test"

编写基础测试后,执行sbt test命令时出现如下错误:

[info] Fast optimizing /Users/arindamray/IdeaProjects/temp/DanceApp/target/scala-2.13/app-test-fastopt
/Users/arindamray/IdeaProjects/temp/DanceApp/node_modules/react-native/index.js:14
import typeof AccessibilityInfo from './Libraries/Components/AccessibilityInfo/AccessibilityInfo';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/Users/arindamray/IdeaProjects/temp/DanceApp/target/scala-2.13/app-test-fastopt/main.js:3:27)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
[error] org.scalajs.testing.common.RPCCore$ClosedException: org.scalajs.testing.adapter.JSEnvRPC$RunTerminatedException
[error]         at org.scalajs.testing.common.RPCCore.helpClose(RPCCore.scala:223)
[error]         at org.scalajs.testing.common.RPCCore.close(RPCCore.scala:215)
[error]         at org.scalajs.testing.adapter.JSEnvRPC.close(JSEnvRPC.scala:68)
[error]         at org.scalajs.testing.adapter.JSEnvRPC.$anonfun$new$1(JSEnvRPC.scala:59)
[error]         at org.scalajs.testing.adapter.JSEnvRPC.$anonfun$new$1$adapted(JSEnvRPC.scala:59)
[error]         at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
[error]         at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
[error]         at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
[error]         at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
[error]         at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
[error]         at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
[error]         at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
[error] Caused by: org.scalajs.testing.adapter.JSEnvRPC$RunTerminatedException
[error]         at org.scalajs.testing.adapter.JSEnvRPC.$anonfun$new$1(JSEnvRPC.scala:59)
[error]         at org.scalajs.testing.adapter.JSEnvRPC.$anonfun$new$1$adapted(JSEnvRPC.scala:59)
[error]         at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
[error]         at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
[error]         at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
[error]         at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
[error]         at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
[error]         at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
[error]         at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
[error] Caused by: org.scalajs.jsenv.ExternalJSRun$NonZeroExitException: exited with code 1
[error]         at org.scalajs.jsenv.ExternalJSRun$$anon$1.run(ExternalJSRun.scala:195)

请问该如何修复此问题?若有调试线索也请不吝赐教。


修复方案

1. 配置Node.js以ES模块模式运行测试

Scala.js默认用CommonJS模式编译测试代码,但React Native依赖是ES模块格式,导致Node.js将其识别为非模块文件报错。需要修改编译配置并告知Node.js使用ES模块:

在build.sbt中添加:

// 全局设置ES模块编译
scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.ESModule) }
// 单独为测试环境设置ES模块编译
Test / scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.ESModule) }

同时在项目根目录创建package.json,添加:

{
  "type": "module"
}

2. 改用JSDOM作为测试环境

React Native的API依赖原生移动环境,纯Node.js无法模拟。使用JSDOM可以提供浏览器环境的模拟,同时天然支持ES模块:

首先添加JSDOM依赖到测试范围:

libraryDependencies += "org.scala-js" %%% "scalajs-jsenv-jsdom-nodejs" % "1.13.0" % Test

然后在build.sbt中指定测试环境:

Test / jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv()

3. Mock React Native模块(适合单元测试)

如果仅测试Slinky组件的逻辑,不需要完整的React Native环境,可以mock掉相关组件:

创建测试用mock文件(如src/test/scala/mocks/ReactNativeMock.scala):

import slinky.core.ExternalComponent

object ReactNativeMock {
  object View extends ExternalComponent {
    override val component = "div"
  }

  // 根据测试需求,mock Text、Image等其他React Native组件
}

在测试代码中使用这些mock组件替代原生的React Native组件,避免加载真实的React Native依赖。


调试线索

  • 检查Node.js版本:确保使用v14及以上版本,该版本对ES模块支持更完善
  • 查看编译输出:检查target/scala-2.13/app-test-fastopt/main.js的模块格式,确认是否为ES模块
  • 重置依赖:删除node_modules和package-lock.json,重新执行npm install,确保React Native依赖安装完整

内容的提问来源于stack exchange,提问作者arinray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:10:33