diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/FrontendTools.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/FrontendTools.java index 87256bd19fd..50428e22884 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/FrontendTools.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/FrontendTools.java @@ -589,7 +589,13 @@ public List getPnpmExecutable() { List pnpmCommand = getSuitablePnpm(); assert !pnpmCommand.isEmpty(); pnpmCommand = new ArrayList<>(pnpmCommand); - pnpmCommand.add("--shamefully-hoist=true"); + // Force hoisted (flat npm-style) layout. CLI takes precedence over + // .npmrc, so this is unambiguous even if the project lacks the + // generated .npmrc. Replaces the previous --shamefully-hoist=true, + // which only controls the partial-hoist heuristic on top of the + // default isolated layout and did not consistently expose every + // transitive at the project root. + pnpmCommand.add("--config.node-linker=hoisted"); return pnpmCommand; } diff --git a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json index 712bbcb1214..26e5ceefc40 100644 --- a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json +++ b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json @@ -15,6 +15,7 @@ "@rollup/plugin-replace": "6.0.3", "@rollup/pluginutils": "5.3.0", "@babel/preset-react": "7.28.5", + "@babel/types": "7.28.5", "rollup-plugin-visualizer": "6.0.5", "rollup-plugin-brotli": "3.1.0", "vite-plugin-checker": "0.12.0", diff --git a/flow-server/src/main/resources/npmrc b/flow-server/src/main/resources/npmrc index ed70490312f..43df9048dc1 100644 --- a/flow-server/src/main/resources/npmrc +++ b/flow-server/src/main/resources/npmrc @@ -3,5 +3,11 @@ # # This file sets the default parameters for manual `pnpm install`. # +# node-linker=hoisted produces a flat node_modules layout (like npm), +# so every transitive dependency lives at the project root. Flow's +# frontend tooling and bundled Vite plugins (e.g. the React function +# location plugin) import transitive deps that pnpm's symlink-based +# layout did not consistently hoist, even with shamefully-hoist=true. +node-linker=hoisted shamefully-hoist=true strict-peer-dependencies=false diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendToolsTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendToolsTest.java index 1b27b979c68..02c7b43930c 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendToolsTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendToolsTest.java @@ -449,8 +449,10 @@ public void knownFaultyNpmVersionThrowsException() { @Test public void getPnpmExecutable_executableIsAvailable() { List executable = tools.getPnpmExecutable(); - // command line should contain --shamefully-hoist=true option - Assert.assertTrue(executable.contains("--shamefully-hoist=true")); + // command line should force hoisted node-linker so transitive + // deps are always installed at the project root + Assert.assertTrue( + executable.contains("--config.node-linker=hoisted")); Assert.assertTrue( executable.stream().anyMatch(cmd -> cmd.contains("pnpm"))); } diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdaterTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdaterTest.java index df2518ab3b1..2e50aba2b44 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdaterTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdaterTest.java @@ -169,6 +169,7 @@ public void getDefaultDevDependencies_includesAllDependencies_whenUsingVite() { expectedDependencies.add("transform-ast"); expectedDependencies.add("strip-css-comments"); expectedDependencies.add("@babel/preset-react"); + expectedDependencies.add("@babel/types"); expectedDependencies.add("@types/react"); expectedDependencies.add("@types/react-dom"); expectedDependencies.add("@preact/signals-react-transform"); diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskRunPnpmInstallTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskRunPnpmInstallTest.java index d185cc164d2..f2669e363de 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskRunPnpmInstallTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskRunPnpmInstallTest.java @@ -245,6 +245,7 @@ public void runPnpmInstall_npmRcFileNotFound_newNpmRcFileIsGenerated() String content = FileUtils.readFileToString(npmRcFile, StandardCharsets.UTF_8); Assert.assertTrue(content.contains("shamefully-hoist")); + Assert.assertTrue(content.contains("node-linker=hoisted")); } @Test