【问题标题】:New Vaadin 14 app fails to run, error "Failed to determine 'node' tool." Missing Node.js and npm tools新的 Vaadin 14 应用程序无法运行,错误“无法确定‘节点’工具。”缺少 Node.js 和 npm 工具
【发布时间】:2019-12-21 11:49:13
【问题描述】:

在选择 Plain Java Servlet 选项后,我使用 Get Started 页面创建了一个新的 Vaadin 14 应用程序。

网页成功下载了我解压的.zip文件,并使用IntelliJ Ultimate Edition 2019.2版本打开。我等了几分钟,Maven 完成了它的工作,下载并重新配置了项目。最后我去了 IntelliJ 中的 Maven 面板,并运行了 Lifecycle 项目 cleaninstall

我在控制台上收到以下错误消息。

[ERROR] Failed to execute goal com.vaadin:vaadin-maven-plugin:14.0.0:prepare-frontend (default) on project acme: Execution default of goal com.vaadin:vaadin-maven-plugin:14.0.0:prepare-frontend failed: 
[ERROR] 
[ERROR] ======================================================================================================
[ERROR] Failed to determine 'node' tool.
[ERROR] Please install it either:
[ERROR]   - by following the https://nodejs.org/en/download/ guide to install it globally
[ERROR]   - or by running the frontend-maven-plugin goal to install it in this project:
[ERROR]   $ mvn com.github.eirslett:frontend-maven-plugin:1.7.6:install-node-and-npm -DnodeVersion="v10.16.0" 
[ERROR] ======================================================================================================

discussion on Vaadin Forum

我提交了Ticket # 6262 Configure Maven to automatically install Node.js & npm,向 Vaadin 团队建议要求和省略 Node.js 和 npm 是一个问题。

【问题讨论】:

  • 需要节点和节点依赖是一个sh**。 1:我们的 DEV 机器无法直接访问互联网。 2:设置 HTTP_PROXY 也不适用于 npm。 3:我们使用 vaadin 只是因为我们需要远离 node.js sh** 但现在只是为了启动入门应用程序(LOL)而一团糟。用了 1.5 天还是不行
  • 请注意。在 Vaadin 14.2 中,maven 插件已更改为在系统中找不到节点时自动在项目中安装节点。
  • @TatuLund 在my Answer 中注明。感谢您提供的信息以及您在 Vaadin 上所做的所有工作。

标签: node.js maven npm vaadin vaadin-flow


【解决方案1】:

更新:14.2 中没有问题

Vaadin 14.2 和 16 已更改为现在在 Maven 驱动的项目中自动包含必要的 npm 工具。无需手动安装 Node.js & npm

引用this blog post

自动安装 Node.js

从版本 14.2 和 16 开始,Node.js 安装(包括 npm)会自动进行。它安装到主文件夹内的.vaadin 文件夹,并从那里重复用于所有 Vaadin 项目。和以前一样,Node 仅用于构建事物的前端;部署生产后它不会运行!

进一步改进:pnpm 代替 npm

有效的前端依赖管理 - pnpm 在幕后,npm 从 14.0 开始就被用于管理前端依赖项。现在,我们增加了对pnpm 的支持,它带来了以下好处:

  1. 与本地计算机和 CI 系统上的 npm 相比,构建时间更短,因为 pnpm 只下载一次包并从本地缓存中重复使用它们。

  2. 在您的项目中更新 Vaadin 版本时,无需删除 package.json、lock 文件或 node_modules 文件夹。

在 14.2 中,仍默认使用 npm,但我们鼓励您测试 pnpm 并向我们提供反馈。尝试 pnpm 很简单:没有迁移,只需使用配置属性或 Maven 插件配置启用它。您可以了解更多关于 pnpm here 的信息。 Vaadin 16 将默认使用 pnpm。

我已经验证这很好用。我现在已经从我的 Mac 中手动删除了 Node.js/npm 安装。


tl;博士

Vaadin 14 团队希望您在计算机上安装 Node.jsnpm 工具。

作为替代方案,Vaadin 14 似乎正在与 Node.js/npm 一起工作,通过您可以在您的MavenPOM 文件。请参阅下面的XMLsn-p 了解您的 POM。

如果您希望在您的计算机上全局安装 Mode/npm,请务必阅读 Tom Novosad 的 other Answer

详情

从 Vaadin 14 开始,Vaadin team is switching

...作为他们从Polymer 2 到Polymer 3 过渡的一部分。

请参阅博文,Bower and npm in Vaadin 14+

希望,作为 Vaadin-on-Java 用户,我们不需要关心这些底层技术细节……但有一件事:不幸的是,npmNode.js 工具是必需的,但 不是 默认捆绑在您的 Vaadin 项目中

您有两种解决方案:

  • 全局安装工具。
  • 在您的项目中安装。

我更喜欢后者。而且我更喜欢让 Maven 在我的项目中自动安装它们,而我手动完成的家务工作更少。

CAVEAT:我不知道我的 node/npm-per-project 解决方案的限制或后果。我几乎不知道任何一个节点/npm 的目的或性质,也不知道 Vaadin 如何使用它们。因此,使用此解决方案需要您自担风险。我只能说它似乎对我有用。

frontend-maven-plugin 添加到您的项目中

Maven 可以使用frontend-maven-plugin 工具在您的 Vaadin 项目中下载并安装带有 npm 的 Node.js。

在您的 Vaadin 项目中打开 Maven POM 文件。

在该 POM 的 <build> <defaultGoal>jetty:run</defaultGoal> <plugins> 元素中添加以下块。

    <plugin>
        <groupId>com.github.eirslett</groupId>
        <artifactId>frontend-maven-plugin</artifactId>
        <!-- Use the latest released version:
        https://repo1.maven.org/maven2/com/github/eirslett/frontend-maven-plugin/ -->
        <version>1.8.0</version>

        <executions>
            <execution>
                <!-- optional: you don't really need execution ids, but it looks nice in your build log. -->
                <id>install node and npm</id>
                <goals>
                    <goal>install-node-and-npm</goal>
                </goals>
                <!-- optional: default phase is "generate-resources" -->
                <phase>generate-resources</phase>
            </execution>
        </executions>
        <configuration>
            <nodeVersion>v10.16.3</nodeVersion>

            <!-- optional: with node version greater than 4.0.0 will use npm provided by node distribution -->
            <!--                    <npmVersion>2.15.9</npmVersion>-->

            <!-- optional: where to download node and npm from. Defaults to https://nodejs.org/dist/ -->
            <!--                    <downloadRoot>http://myproxy.example.org/nodejs/</downloadRoot>-->
        </configuration>
    </plugin>

当然,您可以调整 sn-p 以使用最新版本号。查看the Node.js page 获取最新版本号。

请注意,我们注释掉了 npm 项,因为该工具与最新版本的 Node.js 捆绑在一起。

剩余步骤:

  1. 在 IntelliJ 的 Maven 面板中,运行名为 cleaninstallLifecycle 项目。稍等片刻,下载和配置更多项目。 (请注意控制台历史记录中的“正在安装节点版本 v10.16.3”项。)
  2. 在同一面板的Plugins > jetty 部分中,运行jetty:run 项。等待 Jetty 服务器启动以运行您的 Vaadin 应用程序。

在控制台上,您应该会看到类似这样的内容(mysterious Quiet Time warning is perennial 包含所有 Vaadin 版本):

[INFO] Started Jetty Server
[INFO] Using Non-Native Java sun.nio.fs.PollingWatchService
[WARNING] Quiet Time is too low for non-native WatchService [sun.nio.fs.PollingWatchService]: 1000 < 5000 ms (defaulting to 5000 ms)
  1. 将您的网络浏览器指向:http://localhost:8080/,当您的应用程序成功运行时,会看到“单击我”按钮。

此解决方案来自 Maven 插件 frontend-maven-plugin 的项目页面。请注意,示例 POM 片段不正确,未能将 &lt;execution&gt; 标记包装在复数 &lt;executions&gt; 标记中。我在那里提交了ticket # 838

您可能想在 Vaadin 论坛中关注 this discussion

这里有一个完整的 POM 文件供您参考。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>work.basil.example</groupId>
    <artifactId>acme</artifactId>
    <name>acme</name>
    <version>2.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>13</maven.compiler.source>
        <maven.compiler.target>13</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <failOnMissingWebXml>false</failOnMissingWebXml>

        <vaadin.version>14.0.5</vaadin.version>

        <drivers.downloader.phase>pre-integration-test</drivers.downloader.phase>
    </properties>

    <repositories>
        <repository>
            <id>central</id>
            <url>https://repo1.maven.org/maven2/</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <!-- Repository used by many Vaadin add-ons -->
        <repository>
            <id>Vaadin Directory</id>
            <url>https://maven.vaadin.com/vaadin-addons</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>central</id>
            <url>https://repo1.maven.org/maven2/</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <type>pom</type>
                <scope>import</scope>
                <version>${vaadin.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <!-- Replace artifactId with vaadin-core to use only free components -->
            <artifactId>vaadin</artifactId>
            <exclusions>
                <!-- Webjars are only needed when running in Vaadin 13 compatibility mode -->
                <exclusion>
                    <groupId>com.vaadin.webjar</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.insites</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymer</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymerelements</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.vaadin</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.webcomponents</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- Added to provide logging output as Vaadin uses -->
        <!-- the unbound SLF4J no-operation (NOP) logger implementation -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-testbench</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>jetty:run</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
            </plugin>
            <!-- Jetty plugin for easy testing without a server -->
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.19.v20190610</version>
                <configuration>
                    <!-- If using IntelliJ IDEA with autocompilation, this
                    might cause lots of unnecessary compilations in the
                    background.-->
                    <scanIntervalSeconds>2</scanIntervalSeconds>
                    <!-- Use war output directory to get the webpack files -->
                    <webAppConfig>
                        <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
                    </webAppConfig>
                </configuration>
            </plugin>

            <!--
                Take care of synchronizing java dependencies and imports in
                package.json and main.js files.
                It also creates webpack.config.js if not exists yet.
            -->
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-frontend</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <!-- Use the latest released version:
                https://repo1.maven.org/maven2/com/github/eirslett/frontend-maven-plugin/ -->
                <version>1.8.0</version>

                <executions>
                    <execution>
                        <!-- optional: you don't really need execution ids, but it looks nice in your build log. -->
                        <id>install node and npm</id>
                        <goals>
                            <goal>install-node-and-npm</goal>
                        </goals>
                        <!-- optional: default phase is "generate-resources" -->
                        <phase>generate-resources</phase>
                    </execution>
                </executions>
                <configuration>
                    <nodeVersion>v10.16.3</nodeVersion>

                    <!-- optional: with node version greater than 4.0.0 will use npm provided by node distribution -->
                    <!--                    <npmVersion>2.15.9</npmVersion>-->

                    <!-- optional: where to download node and npm from. Defaults to https://nodejs.org/dist/ -->
                    <!--                    <downloadRoot>http://myproxy.example.org/nodejs/</downloadRoot>-->
                </configuration>
            </plugin>

        </plugins>
    </build>

    <profiles>
        <profile>
            <!-- Production mode is activated using -Pproduction -->
            <id>production</id>
            <properties>
                <vaadin.productionMode>true</vaadin.productionMode>
            </properties>

            <dependencies>
                <dependency>
                    <groupId>com.vaadin</groupId>
                    <artifactId>flow-server-production-mode</artifactId>
                </dependency>
            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>com.vaadin</groupId>
                        <artifactId>vaadin-maven-plugin</artifactId>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>build-frontend</goal>
                                </goals>
                                <phase>compile</phase>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>integration-tests</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.eclipse.jetty</groupId>
                        <artifactId>jetty-maven-plugin</artifactId>
                        <version>9.4.19.v20190610</version>
                        <configuration>
                            <scanIntervalSeconds>0</scanIntervalSeconds>
                            <stopPort>8081</stopPort>
                            <stopWait>5</stopWait>
                            <stopKey>${project.artifactId}</stopKey>
                        </configuration>
                        <executions>
                            <execution>
                                <id>start-jetty</id>
                                <phase>pre-integration-test</phase>
                                <goals>
                                    <goal>deploy-war</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>stop-jetty</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>stop</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

                    <!-- Runs the integration tests (*IT) after the server is started -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <version>3.0.0-M3</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <trimStackTrace>false</trimStackTrace>
                            <enableAssertions>true</enableAssertions>
                            <systemPropertyVariables>
                                <!-- Pass location of downloaded webdrivers to the tests -->
                                <webdriver.chrome.driver>${webdriver.chrome.driver}</webdriver.chrome.driver>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>

                    <plugin>
                        <groupId>com.lazerycode.selenium</groupId>
                        <artifactId>driver-binary-downloader-maven-plugin</artifactId>
                        <version>1.0.17</version>
                        <configuration>
                            <onlyGetDriversForHostOperatingSystem>true
                            </onlyGetDriversForHostOperatingSystem>
                            <rootStandaloneServerDirectory>
                                ${project.basedir}/drivers/driver
                            </rootStandaloneServerDirectory>
                            <downloadedZipFileDirectory>
                                ${project.basedir}/drivers/driver_zips
                            </downloadedZipFileDirectory>
                            <customRepositoryMap>
                                ${project.basedir}/drivers.xml
                            </customRepositoryMap>
                        </configuration>
                        <executions>
                            <execution>
                                <!-- use phase "none" to skip download step -->
                                <phase>${drivers.downloader.phase}</phase>
                                <goals>
                                    <goal>selenium</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

【讨论】:

  • 请注意,Vaadin 不是“切换到使用 Node.js 和 npm”,它是从 polymer2 / bower / webjars 迁移到 polymer3 / npm。
  • @rmuller 我看不出“切换”与“迁移”有何不同,但我确实为 Bower 和 WebJars 添加了几个链接。谢谢。
  • 忘记转换和迁移的措辞,引入另一个词令人困惑,我的错。最重要的变化是聚合物2 -> 3。
  • @rmuller 我进一步列举了图书馆汤,以及背景信息的链接。我喜欢结果。再次感谢。
  • 我曾经让 vaadin 使用我全局安装的 node.js/npm,直到它对我的同事不起作用。现在使用带有frontend-maven-plugin 的本地节点,其插件定义与您在此处编写的完全相同。现在对我和同事来说都工作得很好。而且我在安装failed to execute path-to-global-npm/npm.cmd -v 期间不再收到烦人的日志消息。感谢罗勒的回答。
【解决方案2】:

问题出在方法上

FrontendUtils::getNpmExecutable(String baseDir)

来自 flow-server.jar。该方法试图定位

node/node_modules/npm/bin/npm-cli.js

在 $baseDir 中(这是准备前端目标的项目根文件夹)。当该路径不存在时,代码继续执行“where/which npm.cmd”以获取“npm.cmd”的绝对路径。就我而言,全局安装了 NodeJS,它返回正确的路径。

随后代码继续尝试执行“path-to-npm.cmd\npm.cmd -v”,以确保 npm.cmd 存在并且可运行。

这是方法中的问题:

ProcessBuilder FrontEndUtils::createProcessBuilder(List&lt;String&gt; command)

在此方法中,在某些情况下,程序代码会将环境变量“PATH”设置为 npm.cmd 的路径(因为 ProcssBuilder.environment() 返回的映射不包含“PATH”变量)。

接下来尝试执行命令'path-to-npm\npm.cmd -v'时,进程的退出值为1,stderr非空,因为'chcp'命令在其他东西之前被调用'npm.cmd'(可能是 SETLOCAL 命令),但现在 'chcp' 不在 PATH 中。

以下代码将这些条件(退出代码 1,stderr 非空)评估为执行 npm.cmd 时的错误,并且

无法确定“npm.cmd”工具。

消息已打印。

这发生在我全局安装的 Windows 10、Vaadin Flow 14.0.1、NodeJS 10.16.3 上。

使用应用程序运行 tomcat 服务器时也会遇到同样的问题,因为 $baseDir 变量包含 tomcat bin 目录的路径。

解决方法

作为一种解决方法,将 NodeJS 目录的符号链接到项目根目录就足够了(如果应用程序在 Tomcat 上运行,还可以将 NodeJS 链接到 Tomcat 的 bin 目录)。

【讨论】:

  • 这对我有用。我宁愿在全球安装一个节点,而不是每个 vaadin 项目安装一个。我在管理员提示下使用的命令是“mklink /d node c:\nodejs”,显然调整了路径。这是在 vaadin 项目中运行的。
【解决方案3】:

我在测试新的 Vaadin 14 时出现了这个问题。 我按照说明安装了节点,但我是用之前打开的 Idea 和另一个项目(除了这个)来做的。 仅当我重新启动 Idea 时问题才消失。

【讨论】:

    【解决方案4】:

    更准确地说,有一种情况是可以在插件运行时的日志中找到真正的错误: 命令 '[C:\Program Files\nodejs\npm.cmd, -v]' 失败,退出代码为 '1'

    但是如果您从提示符处运行相同的命令,那么您会发现命令和退出代码没有任何问题。

    正如有人提到的,问题是 Windows 尝试运行“chcp”,但它不在 PATH 上(由 maven 插件操作)。这发生在我的案例中,因为我在注册表中修改为始终使用 UTF 编码运行 cmd。在 Windows 中,这是通过执行“chcp 65001”以及(之前)任何批处理或命令文件(如 npm.cmd ... 我的简单解决方案是将 chcp.com 从 System32 目录复制到 nodejs 目录...

    【讨论】:

    • 不幸的是,将 chcp 复制到 nodejs 对我不起作用。我不得不使用 mklink 命令在 Vaadin 项目中创建指向 nodejs 安装文件夹的符号链接,如 Tom Novosad 的回答中所述。跨度>
    【解决方案5】:

    安装节点后,我在编译 vaadin 应用程序时遇到了同样的问题。
    需要重启PC才能定位节点并运行成功。

    【讨论】:

      【解决方案6】:

      这里几乎一样。 Win 10,JDK 11.0.2,node 10.16.2 全局安装

      mvn 结果

      [ERROR] Failed to determine 'npm.cmd' tool. 
      [ERROR] Please install it either:
      [ERROR] - by following the https://nodejs.org/en/download/ guide to install it globally
      [ERROR] - or by running the frontend-maven-plugin goal to install it in this project:
      [ERROR] $ mvn com.github.eirslett:frontend-maven-plugin:1.7.6:install-node-and-npm -DnodeVersion="v10.16.0"
      

      所以...全局安装它的第一个建议失败了。第二个有效。

      【讨论】:

        猜你喜欢
        • 2020-03-06
        • 2015-05-28
        • 1970-01-01
        • 2020-07-08
        • 1970-01-01
        • 1970-01-01
        • 2017-10-13
        • 2021-07-11
        • 2017-11-17
        相关资源
        最近更新 更多