Search in sources :

Example 1 with NodeTasks

use of com.vaadin.flow.server.frontend.NodeTasks in project flow by vaadin.

the class DevModeInitializer method initDevModeHandler.

/**
 * Initialize the devmode server if not in production mode or compatibility
 * mode.
 *
 * @param classes
 *            classes to check for npm- and js modules
 * @param context
 *            VaadinContext we are running in
 * @return the initialized dev mode handler or {@code null} if none was
 *         created
 *
 * @throws VaadinInitializerException
 *             if dev mode can't be initialized
 */
public static DevModeHandler initDevModeHandler(Set<Class<?>> classes, VaadinContext context) throws VaadinInitializerException {
    ApplicationConfiguration config = ApplicationConfiguration.get(context);
    if (config.isProductionMode()) {
        log().debug("Skipping DEV MODE because PRODUCTION MODE is set.");
        return null;
    }
    if (!config.enableDevServer()) {
        log().debug("Skipping DEV MODE because dev server shouldn't be enabled.");
        return null;
    }
    // This needs to be set as there is no "current service" available in
    // this call
    FeatureFlags.get(context).setPropertiesLocation(config.getJavaResourceFolder());
    String baseDir = config.getStringProperty(FrontendUtils.PROJECT_BASEDIR, null);
    if (baseDir == null) {
        baseDir = getBaseDirectoryFallback();
    }
    // Initialize the usage statistics if enabled
    if (config.isUsageStatisticsEnabled()) {
        StatisticsStorage storage = new StatisticsStorage();
        DevModeUsageStatistics.init(baseDir, storage, new StatisticsSender(storage));
    }
    String generatedDir = System.getProperty(PARAM_GENERATED_DIR, Paths.get(config.getBuildFolder(), DEFAULT_GENERATED_DIR).toString());
    String frontendFolder = config.getStringProperty(PARAM_FRONTEND_DIR, System.getProperty(PARAM_FRONTEND_DIR, DEFAULT_FRONTEND_DIR));
    File flowResourcesFolder = new File(baseDir, config.getFlowResourcesFolder());
    Lookup lookupFromContext = context.getAttribute(Lookup.class);
    Lookup lookupForClassFinder = Lookup.of(new DevModeClassFinder(classes), ClassFinder.class);
    Lookup lookup = Lookup.compose(lookupForClassFinder, lookupFromContext);
    Builder builder = new NodeTasks.Builder(lookup, new File(baseDir), new File(generatedDir), new File(frontendFolder), config.getBuildFolder());
    log().info("Starting dev-mode updaters in {} folder.", builder.getNpmFolder());
    if (!builder.getGeneratedFolder().exists()) {
        try {
            FileUtils.forceMkdir(builder.getGeneratedFolder());
        } catch (IOException e) {
            throw new UncheckedIOException(String.format("Failed to create directory '%s'", builder.getGeneratedFolder()), e);
        }
    }
    File generatedPackages = new File(builder.getGeneratedFolder(), PACKAGE_JSON);
    // Regenerate webpack configuration, as it may be necessary to
    // update it
    // TODO: make sure target directories are aligned with build
    // config,
    // see https://github.com/vaadin/flow/issues/9082
    File target = new File(baseDir, config.getBuildFolder());
    builder.withWebpack(Paths.get(target.getPath(), "classes", VAADIN_WEBAPP_RESOURCES).toFile(), Paths.get(target.getPath(), "classes", VAADIN_SERVLET_RESOURCES).toFile());
    builder.useV14Bootstrap(config.useV14Bootstrap());
    if (!config.useV14Bootstrap() && isEndpointServiceAvailable(lookup)) {
        String connectJavaSourceFolder = config.getStringProperty(CONNECT_JAVA_SOURCE_FOLDER_TOKEN, Paths.get(baseDir, DEFAULT_CONNECT_JAVA_SOURCE_FOLDER).toString());
        String connectApplicationProperties = config.getStringProperty(CONNECT_APPLICATION_PROPERTIES_TOKEN, Paths.get(baseDir, DEFAULT_CONNECT_APPLICATION_PROPERTIES).toString());
        String connectOpenApiJsonFile = config.getStringProperty(CONNECT_OPEN_API_FILE_TOKEN, Paths.get(baseDir, config.getBuildFolder(), DEFAULT_CONNECT_OPENAPI_JSON_FILE).toString());
        builder.withEndpointSourceFolder(new File(connectJavaSourceFolder)).withApplicationProperties(new File(connectApplicationProperties)).withEndpointGeneratedOpenAPIFile(new File(connectOpenApiJsonFile));
    }
    // generate those
    if (!new File(builder.getNpmFolder(), PACKAGE_JSON).exists() || !generatedPackages.exists()) {
        builder.createMissingPackageJson(true);
    }
    Set<File> frontendLocations = getFrontendLocationsFromClassloader(DevModeStartupListener.class.getClassLoader());
    boolean useByteCodeScanner = config.getBooleanProperty(SERVLET_PARAMETER_DEVMODE_OPTIMIZE_BUNDLE, Boolean.parseBoolean(System.getProperty(SERVLET_PARAMETER_DEVMODE_OPTIMIZE_BUNDLE, Boolean.FALSE.toString())));
    boolean enablePnpm = config.isPnpmEnabled();
    boolean useGlobalPnpm = config.isGlobalPnpm();
    boolean useHomeNodeExec = config.getBooleanProperty(InitParameters.REQUIRE_HOME_NODE_EXECUTABLE, false);
    String[] additionalPostinstallPackages = config.getStringProperty(InitParameters.ADDITIONAL_POSTINSTALL_PACKAGES, "").split(",");
    String frontendGeneratedFolder = config.getStringProperty(PROJECT_FRONTEND_GENERATED_DIR_TOKEN, Paths.get(baseDir, DEFAULT_PROJECT_FRONTEND_GENERATED_DIR).toString());
    JsonObject tokenFileData = Json.createObject();
    NodeTasks tasks = builder.enablePackagesUpdate(true).useByteCodeScanner(useByteCodeScanner).withFlowResourcesFolder(flowResourcesFolder).withFrontendGeneratedFolder(new File(frontendGeneratedFolder)).copyResources(frontendLocations).copyLocalResources(new File(baseDir, Constants.LOCAL_FRONTEND_RESOURCES_PATH)).enableImportsUpdate(true).runNpmInstall(true).populateTokenFileData(tokenFileData).withEmbeddableWebComponents(true).enablePnpm(enablePnpm).useGlobalPnpm(useGlobalPnpm).withHomeNodeExecRequired(useHomeNodeExec).withProductionMode(config.isProductionMode()).withPostinstallPackages(Arrays.asList(additionalPostinstallPackages)).build();
    Runnable runnable = () -> runNodeTasks(context, tokenFileData, tasks);
    CompletableFuture<Void> nodeTasksFuture = CompletableFuture.runAsync(runnable);
    Lookup devServerLookup = Lookup.compose(lookup, Lookup.of(config, ApplicationConfiguration.class));
    if (FeatureFlags.get(context).isEnabled(FeatureFlags.VITE)) {
        return new ViteHandler(devServerLookup, 0, builder.getNpmFolder(), nodeTasksFuture);
    } else {
        return new WebpackHandler(devServerLookup, 0, builder.getNpmFolder(), nodeTasksFuture);
    }
}
Also used : Builder(com.vaadin.flow.server.frontend.NodeTasks.Builder) JsonObject(elemental.json.JsonObject) UncheckedIOException(java.io.UncheckedIOException) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) StatisticsSender(com.vaadin.base.devserver.stats.StatisticsSender) WebpackHandler(com.vaadin.base.devserver.WebpackHandler) ViteHandler(com.vaadin.base.devserver.ViteHandler) StatisticsStorage(com.vaadin.base.devserver.stats.StatisticsStorage) Lookup(com.vaadin.flow.di.Lookup) ApplicationConfiguration(com.vaadin.flow.server.startup.ApplicationConfiguration) File(java.io.File) NodeTasks(com.vaadin.flow.server.frontend.NodeTasks)

Aggregations

ViteHandler (com.vaadin.base.devserver.ViteHandler)1 WebpackHandler (com.vaadin.base.devserver.WebpackHandler)1 StatisticsSender (com.vaadin.base.devserver.stats.StatisticsSender)1 StatisticsStorage (com.vaadin.base.devserver.stats.StatisticsStorage)1 Lookup (com.vaadin.flow.di.Lookup)1 NodeTasks (com.vaadin.flow.server.frontend.NodeTasks)1 Builder (com.vaadin.flow.server.frontend.NodeTasks.Builder)1 ApplicationConfiguration (com.vaadin.flow.server.startup.ApplicationConfiguration)1 JsonObject (elemental.json.JsonObject)1 File (java.io.File)1 IOException (java.io.IOException)1 UncheckedIOException (java.io.UncheckedIOException)1