Skip to content

Commit 5f1b9cd

Browse files
caaladormshabarov
andauthored
feat!: NPM assets available under assets (#22647)
* feat: NPM assets available under assets Copy all npm assets to sub folder assets in VAADIN/static and accept redirect for /assets/{filepath} to prepend VAADIN/static to the requested file. Fixes #22515 * Remove mistaken flush and sleep fix javadoc * Remove security context assets as assets folder is under VAADIN * Revert "Remove security context assets as assets folder is under VAADIN" This reverts commit 9ae2190. * assets folder should be a public resource * Add test in security module fix missing test expectation * format * Drop test logging to INFO level * Add getUrlMapping as test is used in multiple modules. * openResource also needs possible url base * oenResource to have correct use of / with or without urlmapping * Fix dev mode bundle asset sharing * add styles.css as public resource --------- Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com>
1 parent 142b0a7 commit 5f1b9cd

File tree

23 files changed

+112
-35
lines changed

23 files changed

+112
-35
lines changed

flow-server/src/main/java/com/vaadin/flow/server/HandlerHelper.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,11 @@ public String getIdentifier() {
155155
resources.add("/" + PwaConfiguration.DEFAULT_OFFLINE_PATH);
156156
resources.add("/" + PwaHandler.DEFAULT_OFFLINE_STUB_PATH);
157157
resources.add("/" + PwaConfiguration.DEFAULT_ICON);
158+
resources.add("/" + FrontendUtils.DEFAULT_STYLES_CSS);
158159
resources.add("/themes/**");
159160
resources.add("/aura/**");
160161
resources.add("/lumo/**");
162+
resources.add("/assets/**");
161163
resources.addAll(getIconVariants(PwaConfiguration.DEFAULT_ICON));
162164
publicResources = resources.toArray(new String[resources.size()]);
163165

@@ -563,9 +565,9 @@ public static List<String> getIconVariants(String iconPath) {
563565
*/
564566
public static String[] getPublicResourcesRequiringSecurityContext() {
565567
return new String[] { //
566-
"/VAADIN/**", // This contains static bundle files which
567-
// typically do not need a security
568-
// context but also uploads go here
568+
"/VAADIN/**" // This contains static bundle files which
569+
// typically do not need a security
570+
// context but also uploads go here
569571
};
570572
}
571573

flow-server/src/main/java/com/vaadin/flow/server/StaticFileServer.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ public class StaticFileServer implements StaticFileHandler {
8888
public static final Pattern APP_THEME_ASSETS_PATTERN = Pattern
8989
.compile("^\\/themes\\/([\\s\\S]+?)\\/");
9090

91+
// Matches paths to npm asset files copies for NpmPackage(assets)
92+
public static final Pattern NPM_ASSETS_PATTERN = Pattern
93+
.compile("^\\/assets\\/");
94+
9195
// Mapped uri is for the jar file
9296
static final Map<URI, Integer> openFileSystems = new HashMap<>();
9397
static final Set<URI> externalFileSystem = new HashSet<>();
@@ -311,6 +315,14 @@ public boolean serveStaticResource(HttpServletRequest request,
311315
resourceUrl = findAssetInFrontendThemesOrDevBundle(
312316
vaadinService,
313317
filenameWithPath.replace(VAADIN_MAPPING, ""));
318+
} else if (resourceUrl == null
319+
&& NPM_ASSETS_PATTERN.matcher(filenameWithPath).find()) {
320+
String assetInDevBundle = "/webapp/VAADIN/static/"
321+
+ filenameWithPath.replaceFirst("^/", "");
322+
resourceUrl = DevBundleUtils.findBundleFile(
323+
deploymentConfiguration.getProjectFolder(),
324+
deploymentConfiguration.getBuildFolder(),
325+
assetInDevBundle);
314326
}
315327
} else if (deploymentConfiguration
316328
.getMode() == Mode.PRODUCTION_PRECOMPILED_BUNDLE
@@ -319,7 +331,8 @@ public boolean serveStaticResource(HttpServletRequest request,
319331
.getThemeResourceFromPrecompiledProductionBundle(
320332
filenameWithPath.replace(VAADIN_MAPPING, "")
321333
.replaceFirst("^/", ""));
322-
} else if (APP_THEME_ASSETS_PATTERN.matcher(filenameWithPath).find()) {
334+
} else if (APP_THEME_ASSETS_PATTERN.matcher(filenameWithPath).find()
335+
|| NPM_ASSETS_PATTERN.matcher(filenameWithPath).find()) {
323336
resourceUrl = vaadinService.getClassLoader()
324337
.getResource(VAADIN_WEBAPP_RESOURCES + "VAADIN/static/"
325338
+ filenameWithPath.replaceFirst("^/", ""));
@@ -581,6 +594,7 @@ String getRequestFilename(HttpServletRequest request) {
581594
} else if (request.getPathInfo().startsWith("/" + VAADIN_MAPPING)
582595
|| APP_THEME_ASSETS_PATTERN.matcher(request.getPathInfo())
583596
.find()
597+
|| NPM_ASSETS_PATTERN.matcher(request.getPathInfo()).find()
584598
|| request.getPathInfo().startsWith("/sw.js")) {
585599
return request.getPathInfo();
586600
}

flow-server/src/main/java/com/vaadin/flow/server/frontend/FrontendUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ public class FrontendUtils {
149149
*/
150150
public static final String SERVICE_WORKER_SRC_JS = "sw.js";
151151

152+
/**
153+
* The styles.css file that is the suggested style sheet for theming.
154+
*/
155+
public static final String DEFAULT_STYLES_CSS = "styles.css";
156+
152157
/**
153158
* The folder inside the 'generated' folder where frontend resources from
154159
* jars are copied.

flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskCopyNpmAssetsFiles.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import org.slf4j.LoggerFactory;
3636

3737
import static com.vaadin.flow.server.Constants.VAADIN_WEBAPP_RESOURCES;
38-
import static com.vaadin.flow.shared.ApplicationConstants.VAADIN_STATIC_FILES_PATH;
38+
import static com.vaadin.flow.shared.ApplicationConstants.VAADIN_STATIC_ASSETS_PATH;
3939

4040
/**
4141
* Copies JavaScript and CSS files from JAR files into a given folder.
@@ -63,7 +63,7 @@ public class TaskCopyNpmAssetsFiles
6363
staticOutput = new File(
6464
DevBundleUtils.getDevBundleFolder(options.getNpmFolder(),
6565
options.getBuildDirectoryName()),
66-
"webapp/" + VAADIN_STATIC_FILES_PATH);
66+
"webapp/" + VAADIN_STATIC_ASSETS_PATH);
6767
} else {
6868
String webappResources;
6969
if (options.getWebappResourcesDirectory() == null) {
@@ -77,7 +77,7 @@ public class TaskCopyNpmAssetsFiles
7777
.getPath();
7878
}
7979

80-
staticOutput = new File(webappResources, VAADIN_STATIC_FILES_PATH);
80+
staticOutput = new File(webappResources, VAADIN_STATIC_ASSETS_PATH);
8181
}
8282
}
8383

flow-server/src/main/java/com/vaadin/flow/shared/ApplicationConstants.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ public class ApplicationConstants implements Serializable {
7070
* The prefix used for all internal static files, relative to context root.
7171
*/
7272
public static final String VAADIN_STATIC_FILES_PATH = "VAADIN/static/";
73+
74+
/**
75+
* The prefix used for all internal static files, relative to context root.
76+
*/
77+
public static final String VAADIN_STATIC_ASSETS_PATH = VAADIN_STATIC_FILES_PATH
78+
+ "assets/";
79+
7380
/**
7481
* The name of the javascript containing push support.
7582
*/

flow-server/src/test/java/com/vaadin/flow/server/HandlerHelperTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,11 @@ public void publicResources() {
434434
expected.add("/icons/icon-1334x750.png");
435435
expected.add("/icons/icon-640x1136.png");
436436
expected.add("/icons/icon-1136x640.png");
437+
expected.add("/styles.css");
437438
expected.add("/themes/**");
438439
expected.add("/aura/**");
439440
expected.add("/lumo/**");
441+
expected.add("/assets/**");
440442

441443
Set<String> actual = new HashSet<>();
442444
Collections.addAll(actual, HandlerHelper.getPublicResources());

flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskCopyNpmAssetsFilesTest.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import com.vaadin.flow.server.frontend.scanner.ClassFinder;
4040
import com.vaadin.flow.server.frontend.scanner.FrontendDependenciesScanner;
4141

42-
import static com.vaadin.flow.shared.ApplicationConstants.VAADIN_STATIC_FILES_PATH;
42+
import static com.vaadin.flow.shared.ApplicationConstants.VAADIN_STATIC_ASSETS_PATH;
4343

4444
public class TaskCopyNpmAssetsFilesTest {
4545

@@ -105,10 +105,10 @@ public void assertFolderIsCopied() throws IOException {
105105
Set<String> filesInDirectory = getFilesInDirectory(
106106
webappResourcesDirectory);
107107
Assert.assertEquals(2, filesInDirectory.size());
108-
Assert.assertTrue(
109-
filesInDirectory.contains("VAADIN/static/button/image.jpg"));
110-
Assert.assertTrue(
111-
filesInDirectory.contains("VAADIN/static/button/image.gif"));
108+
Assert.assertTrue(filesInDirectory
109+
.contains("VAADIN/static/assets/button/image.jpg"));
110+
Assert.assertTrue(filesInDirectory
111+
.contains("VAADIN/static/assets/button/image.gif"));
112112
}
113113

114114
@Test
@@ -123,7 +123,7 @@ public void singleAssertFromFolderIsCopied() throws IOException {
123123
Set<String> filesInDirectory = getFilesInDirectory(
124124
webappResourcesDirectory);
125125
Assert.assertEquals(1, filesInDirectory.size());
126-
Assert.assertEquals("VAADIN/static/copy/image.jpg",
126+
Assert.assertEquals("VAADIN/static/assets/copy/image.jpg",
127127
filesInDirectory.iterator().next());
128128
}
129129

@@ -139,12 +139,12 @@ public void allAssetsAreCopied() throws IOException {
139139
Set<String> filesInDirectory = getFilesInDirectory(
140140
webappResourcesDirectory);
141141
Assert.assertEquals(3, filesInDirectory.size());
142-
Assert.assertTrue(
143-
filesInDirectory.contains("VAADIN/static/button/image.jpg"));
144-
Assert.assertTrue(
145-
filesInDirectory.contains("VAADIN/static/button/image.gif"));
146142
Assert.assertTrue(filesInDirectory
147-
.contains("VAADIN/static/button/button.template"));
143+
.contains("VAADIN/static/assets/button/image.jpg"));
144+
Assert.assertTrue(filesInDirectory
145+
.contains("VAADIN/static/assets/button/image.gif"));
146+
Assert.assertTrue(filesInDirectory
147+
.contains("VAADIN/static/assets/button/button.template"));
148148
}
149149

150150
@Test
@@ -161,7 +161,7 @@ public void devBundleCopiesAssetsToCorrectFolder() throws IOException {
161161
File devBundleTarget = new File(
162162
DevBundleUtils.getDevBundleFolder(options.getNpmFolder(),
163163
options.getBuildDirectoryName()),
164-
"webapp/" + VAADIN_STATIC_FILES_PATH);
164+
"webapp/" + VAADIN_STATIC_ASSETS_PATH);
165165

166166
Set<String> filesInDirectory = getFilesInDirectory(devBundleTarget);
167167
Assert.assertEquals(1, filesInDirectory.size());

flow-tests/test-themes/src/main/java/com/vaadin/flow/uitest/ui/theme/ThemeView.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public ThemeView() {
6161
faText.setId(FONTAWESOME_ID);
6262

6363
// Test npm asset
64-
Image snowFlake = new Image("VAADIN/static/npm/icons/snowflake.svg",
64+
Image snowFlake = new Image("assets/npm/icons/snowflake.svg",
6565
"snowflake");
6666
snowFlake.setHeight("1em");
6767
snowFlake.setId(SNOWFLAKE_ID);

flow-tests/test-themes/src/test/java/com/vaadin/flow/uitest/ui/theme/ThemeIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ public void staticModuleAsset_servedFromAppTheme() {
197197

198198
Assert.assertEquals(
199199
"Node assets should have been copied to 'themes/app-theme'",
200-
getRootURL() + "/path/VAADIN/static/npm/icons/snowflake.svg",
200+
getRootURL() + "/path/assets/npm/icons/snowflake.svg",
201201
$(ImageElement.class).id(SNOWFLAKE_ID).getAttribute("src"));
202202

203203
open(getRootURL() + "/path/"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
server.port=8888
2-
logging.level.org.springframework.security=DEBUG
2+
logging.level.org.springframework.security=INFO
33
server.servlet.context-path=/context
44
server.servlet.session.persistent=false
55
vaadin.frontend.hotdeploy=true

0 commit comments

Comments
 (0)