All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkiverse.web.bundler.deployment.WebBundlerConfig Maven / Gradle / Ivy

There is a newer version: 1.7.1
Show newest version
package io.quarkiverse.web.bundler.deployment;

import static io.quarkiverse.web.bundler.deployment.util.PathUtils.join;
import static io.quarkiverse.web.bundler.deployment.util.PathUtils.prefixWithSlash;
import static java.util.function.Predicate.not;

import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;

import io.quarkus.runtime.annotations.ConfigDocDefault;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import io.smallrye.config.WithName;
import io.smallrye.config.WithParentName;

@ConfigMapping(prefix = "quarkus.web-bundler")
@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
public interface WebBundlerConfig {
    /**
     * The directory in the resources which serves as root for the web assets
     */
    @WithDefault("web")
    String webRoot();

    default String fromWebRoot(String dir) {
        return join(webRoot(), dir);
    }

    /**
     * Bundle entry points config for scripts and styles
     */
    @ConfigDocDefault("if not overridden, by default, 'app' directory will be bundled with 'main' as entry point key")
    Map bundle();

    /**
     * Resources located in {quarkus.web-bundler.web-root}/{quarkus.web-bundler.static} will be served by Quarkus.
     * This directory path is also used as prefix for serving
     * (e.g. {quarkus.web-bundler.web-root}/static/foo.png will be served on {quarkus.http.root-path}/static/foo.png)
     */
    @WithName("static")
    @WithDefault("static")
    String staticDir();

    /**
     * When configured with an internal path (e.g. 'foo/bar'), Bundle files will be served on this path by Quarkus (prefixed by
     * {quarkus.http.root-path}).
     * When configured with an external URL (e.g. 'https://my.cdn.org/'), Bundle files will NOT be served by Quarkus
     * and all resolved paths in the bundle and mapping will automatically point to this url (a CDN for example).
     */
    @WithDefault("static/bundle")
    String bundlePath();

    /**
     * The config for esbuild loaders https://esbuild.github.io/content-types/
     */
    LoadersConfig loaders();

    /**
     * This defines the list of external paths for esbuild (https://esbuild.github.io/api/#external).
     * Instead of being bundled, the import will be preserved.
     */
    @ConfigDocDefault("{quarkus.http.root-path}static/*")
    Optional> externalImports();

    /**
     * Enable or disable bundle splitting (https://esbuild.github.io/api/#splitting)
     * Code shared between multiple entry points is split off into a separate shared file (chunk) that both entry points import
     */
    @WithDefault("true")
    Boolean bundleSplitting();

    /**
     * Configure how dependencies are collected
     */
    WebDependenciesConfig dependencies();

    /**
     * When enabled, Quarkus will create redirections from {bundlePath}/{entryPointKey}.{js,css} to the corresponding file
     * containing the unique hash.
     * This is useful for fixed external access to the bundle files (fullstack microservices).
     */
    @WithDefault("false")
    Boolean bundleRedirect();

    /**
     * The default charset
     */
    @WithDefault("UTF-8")
    Charset charset();

    default String httpRootPath() {
        Config allConfig = ConfigProvider.getConfig();
        final String rootPath = allConfig.getOptionalValue("quarkus.http.root-path", String.class)
                .orElse("/");
        return prefixWithSlash(rootPath);
    }

    default String publicBundlePath() {
        return isExternalBundlePath() ? bundlePath() : join(httpRootPath(), bundlePath());
    }

    default boolean isExternalBundlePath() {
        return bundlePath().matches("^https?://.*");
    }

    default boolean shouldQuarkusServeBundle() {
        return !isExternalBundlePath();
    }

    interface WebDependenciesConfig {

        /**
         * Path to the node_modules directory (relative to the project root).
         */
        @ConfigDocDefault("node_modules will be in the build/target directory")
        Optional nodeModules();

        /**
         * Disable this option to allow using runtime web dependencies.
         * When a runtime scope web dependency is used, the dependency will be present in the target app and served at runtime.
         * When a compile only scope web dependency is used, the dependency will only be used at build time and will not be
         * present in the target app.
         *
         * WARNING: Maven compile scope is considered as a runtime scope, use 'provided' for compile only. On Gradle,
         * 'compileOnly' is compile only.
         *
         */
        @WithDefault("true")
        boolean compileOnly();

        /**
         * Auto import configuration
         */
        AutoImportConfig autoImport();

    }

    interface AutoImportConfig {

        enum Mode {
            ALL,
            STYLES,
            NONE;
        }

        /**
         * Enable or disable auto-import of web dependencies:
         * all: auto-import all web dependencies (scripts and styles)
         * styles: auto-import only styles web dependencies (scss, sass, css)
         * none: disable auto-import
         *
         * ** Only direct dependencies are auto-imported, not transitive ones.**
         *
         * This is using the dependencies package.json (module, main, style, scss, saas fields) to detect the presence of source
         * scripts and styles:
         * - For all libraries enriching your html experience (htmx, hypercript, lazyload, ...), you don't necessarily need a
         * script, auto-import is a comfort.
         * - For styling libraries (Bootstrap, Semantic, ...), you most likely want to always auto-import the styles.
         * - For other web libraries (React, Vue, Lit, ...), you will import everything manually in your app scripts.
         */
        @WithDefault("none")
        @WithParentName
        Mode mode();

        default boolean isEnabled() {
            return mode() != Mode.NONE;
        }
    }

    interface LoadersConfig {

        /**
         * Configure the file extensions using the js loader: https://esbuild.github.io/content-types/#javascript
         */
        @WithDefault("js,cjs,mjs")
        Optional> js();

        /**
         * Configure the file extensions using the jsx loader: https://esbuild.github.io/content-types/#jsx
         */
        @WithDefault("jsx")
        Optional> jsx();

        /**
         * Configure the file extensions using the tsx loader: https://esbuild.github.io/content-types/#jsx
         */
        @WithDefault("tsx")
        Optional> tsx();

        /**
         * Configure the file extensions using the ts loader: https://esbuild.github.io/content-types/#typescript
         */
        @WithDefault("ts,mts,cts")
        Optional> ts();

        /**
         * Configure the file extensions using the css loader: https://esbuild.github.io/content-types/#css
         */
        @WithDefault("css")
        Optional> css();

        /**
         * Configure the file extensions using the local-css loader: https://esbuild.github.io/content-types/#css
         */
        @WithDefault(".module.css")
        Optional> localCss();

        /**
         * Configure the file extensions using the global-css loader: https://esbuild.github.io/content-types/#css
         */
        Optional> globalCss();

        /**
         * Configure the file extensions using the file loader: https://esbuild.github.io/content-types/#file
         * This loader will copy the file to the output directory and embed the file name into the bundle as a string.
         */
        @WithDefault("aac,abw,arc,avif,avi,azw,bin,bmp,bz,bz2,cda,csv,yaml,yml,doc,docx,eot,epub,gz,gif,htm,html,ico,ics,jar,jpeg,jpg,jsonld,mid,midi,mp3,mp4,mpeg,mpkg,odp,ods,odt,oga,ogv,ogx,opus,otf,png,pdf,ppt,pptx,rar,rtf,svg,tar,tif,tiff,ttf,vsd,wav,weba,webm,webp,woff,woff2,xhtml,xls,xlsx,xml,xul,zip,3gp,3g2,7z")
        Optional> file();

        /**
         * Configure the file extensions using the copy loader: https://esbuild.github.io/content-types/#copy
         */
        Optional> copy();

        /**
         * Configure the file extensions using the base64 loader: https://esbuild.github.io/content-types/#base64
         */
        Optional> base64();

        /**
         * Configure the file extensions using the binary loader: https://esbuild.github.io/content-types/#binary
         */
        Optional> binary();

        /**
         * Configure the file extensions using the dataurl loader: https://esbuild.github.io/content-types/#data-url
         */
        Optional> dataUrl();

        /**
         * Configure the file extensions using the empty loader: https://esbuild.github.io/content-types/#empty-file
         */
        Optional> empty();

        /**
         * Configure the file extensions using the text loader: https://esbuild.github.io/content-types/#text
         */
        @WithDefault("txt")
        Optional> text();

        /**
         * Configure the file extensions using the json loader: https://esbuild.github.io/content-types/#json
         */
        @WithDefault("json")
        Optional> json();

    }

    interface EntryPointConfig {

        /**
         * Enable or disable this entry point.
         * You can use this to use the map key as key and dir for this entry point.
         */
        @WithParentName
        @WithDefault("true")
        boolean enabled();

        /**
         * The directory for this entry point under the web root.
         */
        @ConfigDocDefault("the bundle map key")
        Optional dir();

        /**
         * The key for this entry point (use the same key as another to bundle them together).
         */
        @ConfigDocDefault("the bundle map key")
        Optional key();

        /**
         * Indicate if this directory contains qute tags (as .html files)
         * This is only available if the Quarkus Qute extension is in the project.
         */
        @WithDefault("false")
        boolean quteTags();

        default String effectiveDir(String mapKey) {
            return dir().filter(not(String::isBlank)).orElse(mapKey);
        }

        default String effectiveKey(String mapKey) {
            return key().filter(not(String::isBlank)).orElse(mapKey);
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy