flow: JavaScript annotation doesn't work with context:// URLs in npm mode
I have the @JavaScript("context://js/test.js") attached to my route, in hopes to load JavaScript files as plain JS (not as a module) from src/main/webapp/js/test.js.
However, Vaadin tries to look up the javascript file from the node_modules and fails.
Minimal reproducible example
- The Skeleton Starter project: Add
@JavaScript("context://js/test.js")annotation to theMainViewclass. - Run the Skeleton Starter.
Expected behavior
The produced HTML page should load a script from src/main/webapp/js/test.js.
Actual behavior
The webpack compilation fails with
Failed to find the following imports in the `node_modules` tree:
- context://js/test.js
If the build fails, check that npm packages are installed.
Versions:
- Vaadin / Flow version: 4.1.27 / 2.1.9
- Java version: 8
- OS version:
- Browser version (if applicable):
- Application Server (if applicable):
- IDE (if applicable): Intellij
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 26 (23 by maintainers)
Commits related to this issue
- Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
- Treat URLs with "context" and "base" schemas as external (#8556) * Consider context/base schemas as external URLs Fixes #8290 — committed to vaadin/flow by deleted user 4 years ago
@AB-xdev I’m very sorry, you’re right. I think the commits were pushed to our cherry-pick branch for 2.3, but someone accidentally deleted it and created new one for picking changes into without this change. This is our mistake, we’ll do a new 2.3.7 release ASAP and push the changes there. Sorry for the mess.
@AB-xdev Hi thanks for the heads up - we simply missed picking this. I’ve pushed it to the cherry-pick branch and it should then be in 2.3.5 and another 14.3 release in two weeks or so.
The idea is that the server-side URI resolver will translate
context://foo.jsintofoo.js(or maybe the equivalent./foo.js) which is included assrcfor the script tag. This means that the file needs to be put in a location from where static files are served by the servlet container, e.g.src/main/webapp/foo.jsif deploying as a.war, rather than included in thefrontend/directory.@knoobie , your suggestion is far away from the original issue. It may be a separate ticket because of
locationandorder. These add a new feature which is completely absent at the moment. So I would suggest do not mix these things here.typelooks reasonable. But then we have a problem (as always) with compatibility:typeis NPM thenvalueshould be used as a location of a file to bundle itscripttag.We have to keep backward compatibility and this limits us in the decisions .
I would really go with
typeto avoid any confusion withJavaScriptbut then I don’t understand what to do with the special case.When the developer adds JavaScript - he should be able to decide what Vaadin does with the file. He knows the best how the code has to be inserted, interpreted and executed. As stated above, some files aren’t in npm.
Proposal: Change JavaScript or JsModule to something like this:
This isn’t really perfect - just a rough idea to work with. This could help with the current situation, because flow doesn’t have to „guess“ what the user wants - the user says it. Totally transparent without magic.
context://refers to a file deployed to the servlet context path. I’m not 100% sure what an “internal” URL is but it certainly does not sound like one. Why would we want to ignore it instead of making it work?@denis-anisimov I’d expect
context://-based URLs to still work even in npm mode. Imagine that you have a bunch of old javascript files that you need to keep around for compatibility reasons (e.g. https://www.tiny.cloud/ which is not distributed via npm and doesn’t support webcomponents); the most obvious way is to place those insrc/main/webapp/jsand load them via@JavaScript("context://js/test.js"), especially sincePage.addJavaScript("context://js/test.js")works also in npm mode.Documenting that
@JavaScriptdoesn’t support context:// (but leaving Page.addJavaScript() as-is which does supportcontext://and is perceived as an imperative alias for@JavaScript) would create confusion amongst the programmers. Therefore I insist on fixing this bug.I don’t intuitively perceive
@JavaScriptis an alias for@JsModulesince@JavaScriptreferences plain global javascript files while@JsModuleuses the new ES6 module mumbo-jumbo whatever.