URL in CSS no longer works in Vaadin 14.6 - vaadin-flow

After upgrading from Vaadin 14.5 to 14.6 I'm facing problems with CSS that contains URL's that point to content.
For example, the following CSS no longer works:
:host([part="my-part"]) [part="reveal-button"]::before {
content: url("../images/my-image.svg");
}
It fails to "compile" when running the build-frontend goal of the Vaadin Maven plugin with the following error:
ERROR in ../node_modules/#vaadin/flow-frontend/styles/components/my-component.css
Module build failed (from ../node_modules/css-loader/dist/cjs.js):
Error: Can't resolve '../images/my-image.svg' in '<Project Path>\node_modules\#vaadin\flow-frontend\styles\components'
The same error appears in the browser if I try to run the project. This CSS has worked fine in all previous versions of Vaadin 14.
Has anyone encountered anything similar, or have any ideas as to what has changed that might cause this?

With the new custom theme feature the .css loader has changed from raw-loader to css-loader but it shouldn't touch urls outside of frontend/themes/[theme-name] or node_modules
Is the styles/components/my-component.css located in src/main/resources/META-INF/frontend, src/main/resources/META-INF/resources/frontend or src/main/resources/META-INF/resources to be packaged as an add-on jar or compatibility mode?
As in that case the css would end up inside node_modules which might make a difference to the resolving.
As a workaround if you are not building an add-on you should be able to move the css and image to {project_root}/frontend and it should build fine.
Until release of 14.6.2 you can add the raw-loader dependency to a java class with
#NpmPackage(value = "raw-loader", version = "3.1.0")
and then add to webpack.config.js the lines
if(flowDefaults.module.rules[2].test.toString().includes('.css')) {
flowDefaults.module.rules[2].use = [ {loader: 'raw-loader' }];
} else if(flowDefaults.module.rules[1].test.toString().includes('.css')) {
flowDefaults.module.rules[1].use = [ {loader: 'raw-loader' }];
}

Did you change the css structure to follow the new theme structure introduced in 14.6? It is not needed, but it is important context. I think it is at least related to your issue.
The path seems a little weird in your error messages, ending up in a node_modules folder. Could you share where this file is in, and what loads the file to your project?
With the new theme structure, I've used the following css to import images in css:
background: url('./images/fire.png');
And that was placed in a file: frontend/themes/mythemename/mythemefile.css

Related

What is the purpose of buildResources folder in electron-builder building process?

I'm reading through electron and electron-builder docs, but I still do not quite understand what is the purpose of the buildResources folder?
Here's what a configuration doc for electron-builder says:
buildResources = build String - The path to build resources.
Kind of self-explanatory... But how or when they are involved in the build process, especially having that:
...build resources is not packed into the app. If you need to use some
files, e.g. as tray icon, please include required files explicitly
Can we simply put those icon files in an arbitrary folder and then copy over into the app/ manually (since we need to include buildResources manually anyway)?
TL;DR:
As far as I can tell from a quick glance at the source code, the buildResources folder is used to hold additional scripts, plugins, etc. that can be used by the package building software. Electron-builder doesn't generate the packages itself, it uses tools like NSIS.
Explanation:
I've had the same question and unfortunately find an answer for this isn't very straight-forward. The docs entry is pretty useless. I found out that someone asked about it in the GitHub issues but never got an answer.
I decided to dig in the code a bit myself to find out what it does. In NsisTargets.ts, you can see that the buildResources folder can contain custom includes and plugins for NSIS.
// NsisTargets.ts
taskManager.add(async () => {
const userPluginDir = path.join(packager.info.buildResourcesDir, pluginArch)
const stat = await statOrNull(userPluginDir)
if (stat != null && stat.isDirectory()) {
scriptGenerator.addPluginDir(pluginArch, userPluginDir)
}
})
// [...]
taskManager.add(async () => {
const customInclude = await packager.getResource(this.options.include, "installer.nsh")
if (customInclude != null) {
scriptGenerator.addIncludeDir(packager.info.buildResourcesDir)
scriptGenerator.include(customInclude)
}
})
and in pkg.ts it's used to load additional scripts to the pkg builder:
// pkg.ts
if (options.scripts != null) {
args.push("--scripts", path.resolve(this.packager.info.buildResourcesDir, options.scripts))
}
It appears as though buildResources can contain assets/scripts specifically used for the build process. That also explains why the contents of buildResources aren't included in the resulting app.asar file.
So, I'm going to say straight away that the documentation for this option is just awful.
Files included in buildResources will appear in the asar file which you can find documentation about on electron's website.
The option files will include files such as pictures which are not accessible in the asar file.
I.E.
given I have a folder called assets in my build folder I want to include with my app.
"files": [
"./build/**/*"
],
"directories": {
"buildResources": "assets"
}
This will put all folders inside build into the asar file, which you can then unpack by including,
"asarUnpack": "**/assets/*"
This will put the folder assets into the build folder in the app directory.

Angular 4+ 3rd party module import 404 error with base tag

I am putting an angular portion into my MVC app. As such, I have added a tag to my layout view to find the Angular source code, and this is working great.
My issue arises in trying to add a 3rd party module to my project. I added it through the package.json with no problem, and added the module to my app.module.ts as follows:
import { FileUploadModule } from 'primeng/fileupload';
The reference is found, Visual Studio is happy, everything is fine. However, when I run the project locally, I get the following 404 error:
GET http://localhost:59911/src/primeng/fileupload 404 (Not Found)
It seems to me likely that the tag is causing the issue, but I can't remove it without killing the rest of the Angular functionality. Any hints? Can I add an override to the imports call?
Thanks, Mike
On PrimeNG's official website they suggested using import { FileUploadModule } from 'primeng/fileupload'; but it doesn't work any more. I guess they didn't update the docs.
You need { FileUploadModule } from 'primeng/primeng';
The structure is
In the primeng.d.ts file PrimeNG re-exported all modules.
export * from './components/fileupload/fileupload';
For now, no matter which PrimeNG module is used, it is all from primeng/primeng. Here's the imported modules in my project:
import {
ButtonModule,
CodeHighlighterModule,
ConfirmDialogModule,
FieldsetModule,
FileUploadModule,
GrowlModule,
MessagesModule
} from 'primeng/primeng';
The version I use is "primeng": "^4.2.1"
The issue was that primeng was not in the mapping, so it was looking for it in src.
I added the following to systemjs.config.js:
in maps:
'primeng': 'npm:primeng',
in packages:
primeng: {
defaultExtension: 'js'
}
Thanks for the help everyone!

Using StealJS to load Bower components lacking a bower.json file

I am using the StealJS + Bower integration in my application, but a couple of my Bower components (including es6-collections) do not contain a bower.json file. Because es6-collections is one of the dependencies in my project's bower.json file, StealJS tries to load the es6-collections component's bower.json file, cannot find it because it does not exist, and complains: Unable to load the bower.json for es6-collections. I tried using System.config({ path: { 'es6-collections': '...' } }) to notify StealJS of the path to the script to use when loading es6-collections, but that does not help. What can I do to get StealJS to load this component?
Assumptions
So I am going to make a few assumptions:
you are using steal from bower
you are "bower install"'ing es6-collections from github directly
you are implicitly using the system-bower plugin by using the HTML <script src="bower_components/steal/steal.js" main="main"></script> to load your "main" file
If these things seem mostly true-ish then you may just have to add some configuration in your bower.json file to silence the error/warning and have everything work as expected.
Explanation:
So because the system-bower plugin (which you are using implicitly because steal detects it is being loaded from a bower_components directory) uses the components bower.json files to determine entry points, so in this case the error/warning comes from not being able to find es6-collections bower.json file.
Solution:
So we just need to tell System (used by steal) where to find that module and that it can stop looking for it's bower.json file.
We can do that by adding a "system" property to the bower.json and adding some configuration data like this...
"system": {
"paths": {
"es6-collections": "bower_components/es6-collections/index.js"
},
"bowerIgnore": ["es6-collections"],
"meta": {
"es6-collections": {
"format": "global"
}
}
}
The paths configuration there, tells System where to find the module
The bowerIgnore array tells system-bower to not look for the bower.json for that module
and the meta config is there to tell System to treat this module like it's a script that is going to add to the global object (window in the browser), which you should probably do for this particular module because of the way es6-collections was written: it exports an empty object if it has nothing to pollyfill so you can't use the exported object, best to just use it as if it was a global module.
For more information on all these things...
http://stealjs.com/docs/bower.html
https://github.com/systemjs/systemjs/wiki/Meta-Configuration
http://stealjs.com/docs/steal.html
Just to have a working example here https://gist.github.com/BigAB/c108bb0860c9cfee3d6a are three files you can copy-paste/clone and then do a bower install and see it working.

In AngularDart, how should I reference my templates in templateUrl so they work for both Dartium and dart2js?

I currently have this directory layout:
project
web
app.html
main.dart
templates
app.html
alerts.html
menu.html
components
AppComponent.dart
AlertsComponent.dart
MenuComponent.dart
resources
css
bootstrap.css
My components look like:
#Component(
selector: 'app',
templateUrl: 'templates/app.html'
)
class AppComponent { ... }
My application's index.html (in another project) is served from /client, and project/web is served from /project. The above works in Dartium, but I get errors from pub build:
[Warning from _Serial on project|web/main.dart with input project|web/components/AppComponent.dart]:
line 3, column 1 of web/components/AppComponent.dart: Unable to find templates/app.html at project|templates/app.html
#Component(
^^^^^^^^^^^
and
[Warning from _Serial]:
Unable to find webatara|web/main.dart from html_files in pubspec.yaml.
and
[Warning from TemplateCacheGenerator]:
Can't find asset web/web/templates/app.html.
depending on what combination of paths I use in templateUrl and html_files (for Angular's transformer).
What, exactly, should go where and how should it be referenced in templateUrl and pubspec.yaml?
Update: I can get rid of my build errors by moving my templates to the lib directory and using templateUrl: 'packages/project/templates/app.html', but then Dartium tries to load that as /packages/project/templates/app.html, and not /project/packages/project/templates/app.html, which would be correct. I don't see any way to tell it what the base URL is.
but then Dartium tries to load that as
/packages/project/templates/app.html, and not
/project/packages/project/templates/app.html, which would be correct.
I don't see any way to tell it what the base URL is.
I believe you are using angulardart 1.1.1 or 1.1.2? We had the same issue in our project after switching from 1.1.0 to 1.1.2. This is weird behaviour that was added since version 1.1.1.
For some reason default package root in AngularDart now is '/packages/'. This causes generation of root-relative URLs. In your case it generates
/packages/project/templates/app.html
instead of
packages/project/templates/app.html
It's OK while you app is in the root of your domain. But in your case what you need to do is to add following to your initialization method in main.dart:
bind(ResourceResolverConfig, toValue: new ResourceResolverConfig
.resolveRelativeUrls(true, packageRoot: 'packages/'));
This will override angular's default packages root and will make it generate correct relative URLs.
Hope it helps.

TableTools code giving DataTables warning message when application built with r.js

I am having a problem building an application that includes TableTools. I am using r.js and the build line is
E:\Software\nodejs\node r.js -o build.js
The build.js is
({
baseUrl: ".",
paths: {
'jquery' : 'jquery-1.9.1',
'jquery-ui' : 'jquery-ui-1.10.3.custom',
'jquery.dataTables': 'jquery.dataTables',
'jquery.tableTools' : 'TableTools'
},
name: "build_main",
out: "external.min.js",
optimize: "none"
})
Note that I have flattened all of the directories to make it easier to investigate.
When I load my test application, I get the message
Warning: TableTools 2 requires DataTables 1.9.0 or newer ...
I am pretty sure that DataTables is correctly specified in the build. It would seem that when the check in the TableTools code is done DataTables doesn't seem to have been fully loaded/initialised. If I put a break point at the line
if ( typeof $.fn.dataTable == "function" &&
in external.min.js and then step through, it won't popup the warning. Datatables looks to have been correctly initialised just by putting in a breakpoint and stepping through. If I remove TableTools then everything loads fine - DataTables is there.
This can happen due to several reason as mentioned below,
You are using previous versions of Data-tables.
Not mentioning data tables in the build.
Older browser version or browser not supporting data-tables.
Slow internet.

Resources