Skip to content

Commit

Permalink
Merge pull request #40298 from phillip-kruger/web-dependency-alignment
Browse files Browse the repository at this point in the history
Align web-dependency-locator with some of the web-bundler features
  • Loading branch information
phillip-kruger authored Apr 27, 2024
2 parents 944bb12 + 9452cc7 commit b00e49d
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public enum Feature {
VAULT,
VERTX,
VERTX_GRAPHQL,
WEBJARS_LOCATOR;
WEB_DEPENDENCY_LOCATOR;

public String getName() {
return toString().toLowerCase().replace('_', '-');
Expand Down
89 changes: 1 addition & 88 deletions docs/src/main/asciidoc/http-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ include::_attributes.adoc[]
:sectnumlevels: 4
:topics: http,web,webjars,mvnpm,vertx,servlet,undertow
:extensions: io.quarkus:quarkus-vertx-http
:web-locator-ga: quarkus-web-dependency-locator

This document clarifies different HTTP functionalities available in Quarkus.

Expand All @@ -35,93 +34,7 @@ location to function correctly.

=== From web dependencies like webjars or mvnpm

==== WebJars
If you are using https://www.webjars.org[WebJars], like the following JQuery one:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.1</version>
</dependency>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
implementation("org.webjars:jquery:3.1.1")
----

and rather write `/webjars/jquery/jquery.min.js` instead of `/webjars/jquery/3.1.1/jquery.min.js`
in your HTML files, you can add the `{web-locator-ga}` extension to your project.
To use it, add the following to your project's dependencies:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>{web-locator-ga}</artifactId>
</dependency>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
implementation("io.quarkus:{web-locator-ga}")
----

==== Mvnpm

If you are using https://mvnpm.org[mvnpm], like the following Lit one:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>org.mvnpm</groupId>
<artifactId>lit</artifactId>
<version>3.1.2</version>
</dependency>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
implementation("org.mvnpm:lit:3.1.2")
----

you can use the `{web-locator-ga}` as described above to reference the resource without the version, however with mvnpm you can
also use https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap[importmaps].

The importmap is generated by the `{web-locator-ga}` extension, and available at `/_importmap/generated_importmap.js`.
This mean adding the following to your `index.html` will allow you to import web libraries by name:

[source,html]
----
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My app</title>
<script src="/_importmap/generated_importmap.js"></script> <1>
<script type="module">
import '@lit'; <2>
import 'app/demo-app.js'; <3>
</script>
</head>
</html>
----
<1> Use the generated importmap
<2> Import web libraries
<3> Import your own files, this can be done by adding `quarkus.web-dependency-locator.import-mappings.app/ = /app/` to the config. Any key-value pair can be added.

Look at the xref:web-dependency-locator.adoc[Web dependency locator] guide for details on how to use https://www.webjars.org[WebJars], https://mvnpm.org[mvnpm] and https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap[importmaps]

=== From a local directory

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
144 changes: 144 additions & 0 deletions docs/src/main/asciidoc/web-dependency-locator.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
= Web dependency locator
include::_attributes.adoc[]
:categories: web
:summary: Learn more about how to use the web dependency locator
:numbered:
:sectnums:
:sectnumlevels: 4
:topics: http,web,webjars,mvnpm,vertx,servlet,undertow
:extensions: io.quarkus:quarkus-web-dependency-locator
:web-locator-ga: quarkus-web-dependency-locator

This document shows how static resources can be served from web dependency jars like https://www.webjars.org[WebJars] and https://mvnpm.org[mvnpm].

== Using the `{web-locator-ga}` extension

[source,xml,subs="attributes+",role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>{web-locator-ga}</artifactId>
</dependency>
----

[source,gradle,subs="attributes+",role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
implementation("io.quarkus:{web-locator-ga}")
----

=== WebJars
If you are using https://www.webjars.org[WebJars], like the following JQuery one:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.1</version>
</dependency>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
implementation("org.webjars:jquery:3.1.1")
----

you can reference the files in the jar from your HTML, example `/webjars/jquery/3.1.1/jquery.min.js`.

The above is available by default, however, adding the `{web-locator-ga}` extension allows you to reference the files without having to include the version in the path, example `/webjars/jquery/jquery.min.js`.

=== Mvnpm

If you are using https://mvnpm.org[mvnpm], like the following Lit one:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>org.mvnpm</groupId>
<artifactId>lit</artifactId>
<version>3.1.2</version>
</dependency>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
implementation("org.mvnpm:lit:3.1.2")
----

you can reference the files in the jar from your HTML, example `/_static/lit/3.1.2/index.js`.

The above is available by default, however, adding the `{web-locator-ga}` extension allows you to reference the files without having to include the version in the path, example `/_static/lit/index.js`.

==== ImportMaps

Mvnpm jars also allows you to use an https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap[importmap], that will
allow you to just use module imports, example `import { LitElement, html, css} from 'lit';`.

The importmap is generated by the `{web-locator-ga}` extension, and available at `/_importmap/generated_importmap.js`.
This means adding the following to your `index.html` will allow you to import web libraries by name:

[source,html]
----
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My app</title>
<script src="/_importmap/generated_importmap.js"></script> <1>
<script type="module">
import '@lit'; <2>
import 'app/demo-app.js'; <3>
</script>
</head>
</html>
----
<1> Use the generated importmap
<2> Import web libraries
<3> Import your own files, this can be done by adding `quarkus.web-dependency-locator.import-mappings.app/ = /app/` to the config. Any key-value pair can be added.

===== Automatic imports

You can also automate the imports above. To do this, move your web assests from `src/main/resources/META-INF/resources` to `src/main/web`
and now replace the above scripts and imports with `{#bundle /}`:

[source,html]
----
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My app</title>
{#bundle /} <1>
</head>
</html>
----
<1> This will be replaced at build time with the importmap script, and also include any CSS and JavaScript discovered in the `/app` directory.

This allows you to add libraries, js and css without having to change your HTML. Hot-reload is also supported.

=== Dev UI

When adding the `{web-locator-ga}` extension , you can see the files being served, and the generated importmap, in the Dev UI:

image:web-dependency-locator-screenshot01.png[alt=Card in Dev UI]
image:web-dependency-locator-screenshot02.png[alt=Files]
image:web-dependency-locator-screenshot03.png[alt=Importmap]
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/web.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ You can find more information in the xref:http-reference#serving-static-resource
However, if you want to insert scripts, styles, and libraries in your web pages, you have 3 options:

a. Consume libraries from public CDNs such as cdnjs, unpkg, jsDelivr and more, or copy them to your `META-INF/resources` directory.
b. Use runtime web dependencies such as mvnpm.org or webjars, when added to your pom.xml or build.gradle they can be directly xref:http-reference#mvnpm[accessed from your web pages].
b. Use runtime web dependencies such as https://mvnpm.org[mvnpm] or https://www.webjars.org[WebJars], when added to your pom.xml or build.gradle they can be directly xref:web-dependency-locator.adoc[accessed from your web pages].
c. Package your scripts (js, ts), styles (css, scss), and web dependencies together using a bundler (see xref:#bundling[below]).

NOTE: *We recommend using a bundler for production* as it offers better control, consistency, security, and performance. The good news is that Quarkus makes it really easy and fast with the https://docs.quarkiverse.io/quarkus-web-bundler/dev/[Quarkus Web Bundler extension].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.AuthenticationRedirectException;
import io.quarkus.vertx.core.deployment.CoreVertxBuildItem;
import io.quarkus.vertx.http.deployment.DefaultRouteBuildItem;
import io.quarkus.vertx.http.deployment.FilterBuildItem;
import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RequireVirtualHttpBuildItem;
Expand Down Expand Up @@ -89,7 +88,6 @@ public void staticInit(ResteasyStandaloneRecorder recorder,
public void boot(ShutdownContextBuildItem shutdown,
ResteasyStandaloneRecorder recorder,
BuildProducer<FeatureBuildItem> feature,
BuildProducer<DefaultRouteBuildItem> defaultRoutes,
BuildProducer<RouteBuildItem> routes,
BuildProducer<FilterBuildItem> filterBuildItemBuildProducer,
CoreVertxBuildItem vertx,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,15 @@ public class WebDependencyLocatorConfig {
@ConfigItem
public Map<String, String> importMappings;

/**
* The directory in the resources which serves as root for the web assets
*/
@ConfigItem(defaultValue = "web")
public String webRoot;

/**
* The directory in the resources which serves as root for the app assets
*/
@ConfigItem(defaultValue = "app")
public String appRoot;
}
Loading

0 comments on commit b00e49d

Please sign in to comment.