无法通过Java代码启动Appium服务及import语法错误问题求助
解决Appium启动时的
SyntaxError: Cannot use import statement outside a module错误 这个错误很常见,原因是你指定的appium/lib/appium.js是Appium v2+使用的ES模块文件(用了import语法),但Node.js默认以CommonJS模式运行,无法直接识别ES模块的语法。下面是几个靠谱的解决办法:
1. 使用Appium官方提供的正确入口文件
Appium v2+的核心代码已经迁移到ES模块,官方的启动入口不是lib/appium.js,而是build/main.js。你只需要修改withAppiumJS指向的文件路径即可:
修改后的Option 1代码
public static void runAppiumService(String portNumber) { // Build parameters for appium server: AppiumServiceBuilder appiumServiceBuilder = new AppiumServiceBuilder(); appiumServiceBuilder.usingPort(Integer.parseInt(portNumber)) .withIPAddress("127.0.0.1") // 替换为Appium v2的正确入口文件 .withAppiumJS(new File("C:\\Users\\Ritesh Mittal\\AppData\\Roaming\\npm\\node_modules\\appium\\build\\main.js")) .withArgument(GeneralServerFlag.SESSION_OVERRIDE) .withLogFile(new File(System.getProperty("user.dir") + "/target/resources/appium_server_logs_" + Thread.currentThread().getId())); AppiumDriverLocalService service = AppiumDriverLocalService.buildService(appiumServiceBuilder); service.start(); }
修改后的Option 2代码
另外注意:Option 2里不要把会话的DesiredCapabilities传给withCapabilities,这个方法是用来配置服务启动参数的,不是会话参数。同时替换正确的Appium入口:
DesiredCapabilities dc = new DesiredCapabilities(); dc.setCapability(MobileCapabilityType.DEVICE_NAME, deviceName); dc.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); dc.setCapability(MobileCapabilityType.APP, System.getProperty("user.dir")+"/src/test/resources/apps/CRMNextNative 6.29.0-release_screenshot_enabled.apk"); dc.setCapability("automationName","UiAutomator2"); dc.setCapability("appPackage", "com.crmnextmobile.crmnextofflineplay"); dc.setCapability("appActivity", "com.crmnextmobile.crmnextofflineplay.qr.QrScannerActivity"); dc.setCapability("enforceAppInstall", true); // 修正拼写错误:原代码是enforceAppInsall URL url = new URL("http://127.0.0.1:"+portNumber+"/wd/hub"); AppiumDriverLocalService service; service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder() .usingPort(Integer.parseInt(portNumber)) .usingDriverExecutable(new File("C:\\Program Files\\nodejs\\node.exe")) // 替换为正确的入口文件 .withAppiumJS(new File("C:\\Users\\Ritesh Mittal\\AppData\\Roaming\\npm\\node_modules\\appium\\build\\main.js")) .withArgument(GeneralServerFlag.RELAXED_SECURITY) .withArgument(GeneralServerFlag.SESSION_OVERRIDE) .withArgument(GeneralServerFlag.LOG_LEVEL, "error")); // 移除这里的.withCapabilities(dc),会话capabilities在创建Driver时传入 service.start(); logger.info("Appium started ......"); Thread.sleep(10000); driver = new AppiumDriver(url,dc); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); System.out.println("CRMNext automation start..");
2. 更简化的方式:依赖全局安装的Appium
如果你已经通过npm install -g appium全局安装了Appium,可以不用手动指定withAppiumJS和usingDriverExecutable,AppiumServiceBuilder会自动找到系统中的Appium命令,代码会更简洁:
AppiumDriverLocalService service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder() .usingPort(Integer.parseInt(portNumber)) .withIPAddress("127.0.0.1") .withArgument(GeneralServerFlag.RELAXED_SECURITY) .withArgument(GeneralServerFlag.SESSION_OVERRIDE) .withArgument(GeneralServerFlag.LOG_LEVEL, "error")); service.start();
额外注意事项
- 确认你的Appium版本:如果是v1.x,入口确实是
lib/appium.js,但v2.x必须用build/main.js,可以通过appium -v命令查看版本; - 检查端口占用:启动服务前确保指定的端口没有被其他进程占用,可以用
netstat -ano | findstr :<你的端口号>命令排查; - 拼写错误:你的Option 2里把
enforceAppInstall拼写成了enforceAppInsall,这个会导致capability不生效,已经帮你修正了。
内容的提问来源于stack exchange,提问作者mittalri
相关产品推荐
相关产品推荐

