use of com.vaadin.flow.server.frontend.FrontendTools in project flow by vaadin.
the class BuildFrontendUtil method prepareFrontend.
/**
* Prepares the Frontend
*
* @param adapter
* - the PluginAdapterBase.
* @throws IOException
* - Could not forceMkdir(adapter.generatedFolder());
* @throws ExecutionFailedException
* - While NodeTasks.execute()
* @throws URISyntaxException
* - Could not build an URI from nodeDownloadRoot().
*/
public static void prepareFrontend(PluginAdapterBase adapter) throws IOException, ExecutionFailedException, URISyntaxException {
final URI nodeDownloadRootURI = adapter.nodeDownloadRoot();
FrontendToolsSettings settings = getFrontendToolsSettings(adapter);
FrontendTools tools = new FrontendTools(settings);
tools.validateNodeAndNpmVersion();
try {
FileUtils.forceMkdir(adapter.generatedFolder());
} catch (IOException e) {
throw new IOException("Failed to create folder '" + adapter.generatedFolder() + "'. Verify that you may write to path.", e);
}
File flowResourcesFolder = new File(adapter.npmFolder(), Paths.get(adapter.buildFolder(), DEFAULT_FLOW_RESOURCES_FOLDER).toString());
ClassFinder classFinder = adapter.getClassFinder();
Lookup lookup = adapter.createLookup(classFinder);
NodeTasks.Builder builder = new NodeTasks.Builder(lookup, adapter.npmFolder(), adapter.generatedFolder(), adapter.frontendDirectory(), adapter.buildFolder()).useV14Bootstrap(adapter.isUseDeprecatedV14Bootstrapping()).withFlowResourcesFolder(flowResourcesFolder).createMissingPackageJson(true).enableImportsUpdate(false).enablePackagesUpdate(false).runNpmInstall(false).withNodeVersion(adapter.nodeVersion()).withNodeDownloadRoot(nodeDownloadRootURI).setNodeAutoUpdate(adapter.nodeAutoUpdate()).withHomeNodeExecRequired(adapter.requireHomeNodeExec()).setJavaResourceFolder(adapter.javaResourceFolder()).withProductionMode(adapter.productionMode());
// Copy jar artifact contents in TaskCopyFrontendFiles
builder.copyResources(adapter.getJarFiles());
try {
builder.build().execute();
} catch (ExecutionFailedException exception) {
throw exception;
} catch (Throwable throwable) {
// NOSONAR Intentionally throwable
throw new ExecutionFailedException("Error occured during goal execution: " + throwable.getMessage() + "\n\nPlease run Maven with the -e switch (or Gradle with the --stacktrace switch), to learn the full stack trace.", throwable);
}
}
use of com.vaadin.flow.server.frontend.FrontendTools in project flow by vaadin.
the class BuildFrontendUtil method runFrontendBuild.
/**
* Execute the frontend build with the wanted build system.
*
* @param adapter
* - the PluginAdapterBase.
* @throws TimeoutException
* - while running build system
* @throws URISyntaxException
* - while parsing nodeDownloadRoot()) to URI
*/
public static void runFrontendBuild(PluginAdapterBase adapter) throws TimeoutException, URISyntaxException {
ClassFinder classFinder = adapter.getClassFinder();
Lookup lookup = adapter.createLookup(classFinder);
final FeatureFlags featureFlags = new FeatureFlags(lookup);
featureFlags.setPropertiesLocation(adapter.javaResourceFolder());
FrontendToolsSettings settings = getFrontendToolsSettings(adapter);
FrontendTools tools = new FrontendTools(settings);
if (featureFlags.isEnabled(FeatureFlags.VITE)) {
BuildFrontendUtil.runVite(adapter, tools);
} else {
BuildFrontendUtil.runWebpack(adapter, tools);
}
}
use of com.vaadin.flow.server.frontend.FrontendTools in project flow by vaadin.
the class BuildFrontendUtilTest method testWebpackRequiredFlagsPassedToNodeEnvironment.
@Test
public void testWebpackRequiredFlagsPassedToNodeEnvironment() throws IOException, URISyntaxException, TimeoutException {
Assume.assumeFalse("Test not runnable on Windows", FrontendUtils.isWindows());
Assume.assumeTrue("Test requires /bin/bash", new File("/bin/bash").exists());
TemporaryFolder tmpDir = new TemporaryFolder();
tmpDir.create();
File baseDir = tmpDir.newFolder();
// setup: mock a webpack executable
File webpackBin = new File(baseDir, "node_modules/webpack/bin");
Assert.assertTrue(webpackBin.mkdirs());
File webPackExecutableMock = new File(webpackBin, "webpack.js");
Assert.assertTrue(webPackExecutableMock.createNewFile());
PluginAdapterBase adapter = Mockito.mock(PluginAdapterBase.class);
Mockito.when(adapter.npmFolder()).thenReturn(baseDir);
Mockito.when(adapter.projectBaseDirectory()).thenReturn(tmpDir.getRoot().toPath());
FrontendTools tools = Mockito.mock(FrontendTools.class);
// given: "node" stub that exits normally only if expected environment
// set
File fakeNode = new File(baseDir, "node");
try (PrintWriter out = new PrintWriter(fakeNode)) {
out.println("#!/bin/bash");
out.println("[ x$NODE_OPTIONS == xexpected ]");
out.println("exit $?");
}
Assert.assertTrue(fakeNode.setExecutable(true));
Mockito.when(tools.getNodeExecutable()).thenReturn(fakeNode.getAbsolutePath());
Map<String, String> environment = new HashMap<>();
environment.put("NODE_OPTIONS", "expected");
Mockito.when(tools.getWebpackNodeEnvironment()).thenReturn(environment);
// then
BuildFrontendUtil.runWebpack(adapter, tools);
// terminates successfully
}
use of com.vaadin.flow.server.frontend.FrontendTools in project flow by vaadin.
the class BrowserLauncher method runNodeCommands.
private static int runNodeCommands(String script) throws InterruptedException, IOException {
FrontendToolsSettings settings = new FrontendToolsSettings("", () -> FrontendUtils.getVaadinHomeDirectory().getAbsolutePath());
FrontendTools tools = new FrontendTools(settings);
String node = tools.getNodeExecutable();
List<String> command = new ArrayList<>();
command.add(node);
command.add("-e");
command.add(script);
ProcessBuilder builder = FrontendUtils.createProcessBuilder(command);
return builder.start().waitFor();
}
use of com.vaadin.flow.server.frontend.FrontendTools in project flow by vaadin.
the class AbstractDevServerRunner method doStartDevServer.
/**
* Starts the dev server and returns the started process.
*
* @return the started process or {@code null} if no process was started
*/
protected Process doStartDevServer() {
ApplicationConfiguration config = getApplicationConfiguration();
ProcessBuilder processBuilder = new ProcessBuilder().directory(getProjectRoot());
FrontendTools tools = new FrontendTools(config, getProjectRoot());
tools.validateNodeAndNpmVersion();
List<String> command = getServerStartupCommand(tools);
FrontendUtils.console(FrontendUtils.GREEN, START);
if (getLogger().isDebugEnabled()) {
getLogger().debug(FrontendUtils.commandToString(getProjectRoot().getAbsolutePath(), command));
}
processBuilder.command(command);
Map<String, String> environment = processBuilder.environment();
updateServerStartupEnvironment(tools, environment);
try {
Process process = processBuilder.redirectErrorStream(true).start();
/*
* We only can save the dev server process reference the first time
* that the DevModeHandler is created. There is no way to store it
* in the servlet container, and we do not want to save it in the
* global JVM.
*
* We instruct the JVM to stop the server daemon when the JVM stops,
* to avoid leaving daemons running in the system.
*
* NOTE: that in the corner case that the JVM crashes or it is
* killed the daemon will be kept running. But anyways it will also
* happens if the system was configured to be stop the daemon when
* the servlet context is destroyed.
*/
Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
DevServerOutputTracker outputTracker = new DevServerOutputTracker(process.getInputStream(), getServerSuccessPattern(), getServerFailurePattern(), this::onDevServerCompilation);
outputTracker.find();
getLogger().info(LOG_START, getServerName());
int timeout = Integer.parseInt(config.getStringProperty(InitParameters.SERVLET_PARAMETER_DEVMODE_WEBPACK_TIMEOUT, DEFAULT_TIMEOUT_FOR_PATTERN));
outputTracker.awaitFirstMatch(timeout);
return process;
} catch (IOException e) {
getLogger().error("Failed to start the " + getServerName() + " process", e);
} catch (InterruptedException e) {
getLogger().debug(getServerName() + " process start has been interrupted", e);
}
return null;
}
Aggregations