Using Eclipse with openhab-webui

I noticed it is quicker too, but for me it was only like 10-15 seconds faster, npm ci takes only 15-20 seconds for me.

We can put it there when building with Maven, but this shouldn’t be the default. However when putting it there through some config option I don’t see a problem with it. I will look into this.

I think a considerable part of the time is deleting the existing files. It takes time also when Maven clean does it, because of the sheer number of files/folders. It might be related to the type of file system/the OS, because the storage I use is a NVMe SSD that’s very fast. But, this is Windows with NTFS, and it might have some “more complicated procedure” for deletion that e.g Linux (I’ve noticed in general that Windows spends much more time on deleting files).

edit: When thinking about the delete speed, my guess is that the fact that Windows use file locking might have a lot to do with it. Windows, unlike macOS and Linux, has to look up and make sure that each file isn’t locked before deleting. That probably takes as much or more time as the deletion itself.

1 Like

From my latest testing, it seems like we can do without build-helper-maven-plugin or any replacement plugin, if we write the WebPack output directly to target/classes/app instead of target/www. When I inspect the result of what the plugin does, it seems to be just to copy the files there, and it seems like target/classes is the “root folder” for what becomes the JAR archive.

So, while it feels a bit “hackish” to write directly to the target/classes folder, the resulting JAR and MainUI run from it, seem to work fine. The benefit of dropping the plugin is that this folder is no longer marked as a “source folder”, and the files still ends up where they should.

Non-Maven builds could then work with src/www and these two folders would be “independent of each other”.

I’ve incorporated everything discussed this far and is testing it now. This far it seems to work:

 bundles/org.openhab.ui/pom.xml                     | 41 +++++++++-------------
 bundles/org.openhab.ui/web/build/build.js          |  3 +-
 bundles/org.openhab.ui/web/build/webpack.config.js | 12 ++++---
 bundles/org.openhab.ui/web/package.json            |  3 +-
 4 files changed, 28 insertions(+), 31 deletions(-)

diff --git a/bundles/org.openhab.ui/pom.xml b/bundles/org.openhab.ui/pom.xml
index 98d73cec..16518d64 100644
--- a/bundles/org.openhab.ui/pom.xml
+++ b/bundles/org.openhab.ui/pom.xml
@@ -32,6 +32,17 @@
 
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-clean-plugin</artifactId>
+        <configuration>
+          <filesets>
+            <fileset>
+              <directory>${basedir}/web/node_modules</directory>
+            </fileset>
+          </filesets>
+        </configuration>
+      </plugin>
       <plugin>
         <groupId>com.github.eirslett</groupId>
         <artifactId>frontend-maven-plugin</artifactId>
@@ -52,42 +63,24 @@
           </execution>
 
           <execution>
-            <id>npm ci</id>
+            <id>npm install</id>
             <goals>
               <goal>npm</goal>
             </goals>
+            <phase>generate-resources</phase>
             <configuration>
-              <arguments>ci</arguments>
+              <arguments>install --save false</arguments>
             </configuration>
           </execution>
 
           <execution>
-            <id>npm run build-prod</id>
+            <id>npm run build-mvn</id>
             <goals>
               <goal>npm</goal>
             </goals>
+            <phase>prepare-package</phase>
             <configuration>
-              <arguments>run build-prod ${project.version}</arguments>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>build-helper-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>add-resource</goal>
-            </goals>
-            <phase>generate-resources</phase>
-            <configuration>
-              <resources>
-                <resource>
-                  <directory>web/www</directory>
-                  <targetPath>app</targetPath>
-                </resource>
-              </resources>
+              <arguments>run build-mvn ${project.version}</arguments>
             </configuration>
           </execution>
         </executions>
diff --git a/bundles/org.openhab.ui/web/build/build.js b/bundles/org.openhab.ui/web/build/build.js
index 662ac079..60fd81c9 100644
--- a/bundles/org.openhab.ui/web/build/build.js
+++ b/bundles/org.openhab.ui/web/build/build.js
@@ -10,12 +10,13 @@ const config = require('./webpack.config.js');
 
 const env = process.env.NODE_ENV || 'development';
 const target = process.env.TARGET || 'web';
+const maven = process.env.MAVEN || false;
 
 const spinner = ora(env === 'production' ? chalk.cyan('Building for production...') : chalk.cyan('Building development version...'));
 spinner.start();
 
 exec(`npm run generate-build-info ${process.argv[2]}`).then(() => {
-  return rm('./www/')
+  return maven ? rm('../target/classes/app') : rm('./www/')
 }).then(() => {
   webpack(config, (err, stats) => {
     if (err) throw err;
diff --git a/bundles/org.openhab.ui/web/build/webpack.config.js b/bundles/org.openhab.ui/web/build/webpack.config.js
index 99646abb..22fad60f 100644
--- a/bundles/org.openhab.ui/web/build/webpack.config.js
+++ b/bundles/org.openhab.ui/web/build/webpack.config.js
@@ -19,6 +19,8 @@ function resolvePath(dir) {
 const env = process.env.NODE_ENV || 'development'
 const target = process.env.TARGET || 'web'
 const buildSourceMaps = process.env.SOURCE_MAPS || false
+const maven = process.env.MAVEN || false
+const basePath = maven ? '../target/classes/app' : 'www'
 
 const apiBaseUrl = process.env.OH_APIBASE || 'http://localhost:8080'
 
@@ -31,7 +33,7 @@ module.exports = {
     './src/js/app.js'
   ],
   output: {
-    path: resolvePath('www'),
+    path: resolvePath(basePath),
     filename: 'js/app.[contenthash].js',
     publicPath: '/',
     hotUpdateChunkFilename: 'hot/[id].[fullhash].hot-update.js',
@@ -65,7 +67,7 @@ module.exports = {
       }
     },
     static: [
-      path.resolve(__dirname, 'www'),
+      path.resolve(__dirname, basePath),
     ],
     allowedHosts: "all",
     historyApiFallback: true,
@@ -263,15 +265,15 @@ module.exports = {
       patterns: [
         {
           from: resolvePath('src/res'),
-          to: resolvePath('www/res')
+          to: resolvePath(basePath + '/res')
         },
         {
           from: resolvePath('src/manifest.json'),
-          to: resolvePath('www/manifest.json')
+          to: resolvePath(basePath + '/manifest.json')
         },
         {
           from: resolvePath('src/robots.txt'),
-          to: resolvePath('www/robots.txt')
+          to: resolvePath(basePath + '/robots.txt')
         }
       ]
     }),
diff --git a/bundles/org.openhab.ui/web/package.json b/bundles/org.openhab.ui/web/package.json
index 2fd9bf95..831385ba 100644
--- a/bundles/org.openhab.ui/web/package.json
+++ b/bundles/org.openhab.ui/web/package.json
@@ -1,6 +1,6 @@
 {
   "name": "openhab",
-  "version": "4.2.0",
+  "version": "5.0.0",
   "description": "openHAB",
   "repository": "https://github.com/openhab/openhab-webui",
   "license": "EPL-2.0",
@@ -25,6 +25,7 @@
   "scripts": {
     "generate-build-info": "node build/generate-build-info.mjs",
     "build-prod": "cross-env NODE_ENV=production node ./build/build.js",
+    "build-mvn": "cross-env NODE_ENV=production cross-env MAVEN=1 node ./build/build.js",
     "webpack-analyzer": "cross-env NODE_ENV=production cross-env WEBPACK_ANALYZER=1 node ./build/build.js",
     "webpack-analyzer-report": "cross-env NODE_ENV=production cross-env WEBPACK_ANALYZER=1 WEBPACK_ANALYZER_REPORT=1 node ./build/build.js",
     "webpack-analyzer-report-stats": "cross-env NODE_ENV=production cross-env WEBPACK_ANALYZER=1 WEBPACK_ANALYZER_REPORT=1 WEBPACK_ANALYZER_REPORT_STATS=1 node ./build/build.js",

edit: I removed running the unit tests from Maven as it’s not needed anyway, because for some reason they were also run as part of the Eclipse automatic build, making it even slower.

@Nadahar I have created Main UI mvn build: Run tests/lint, Only clean in clean goal & Build to mvn target dir by florian-h05 · Pull Request #3116 · openhab/openhab-webui · GitHub. Can you please give it a try?

I’ve given comments directly in the PR (in case you aren’t notified).

@florian-h05 I got an endless build loop simply by having a trailing space in one of the .js files.

It seems that the linter is run anyway for production builds, and since the linter errors if there’s a trailing space, the build fails. Eclipse refreshes and tries to build again, but this never stops until the space is removed. It’s not very obvious what happens, you don’t get a clear message that’s what happening (in fact, I had to dig into logs to figure it out).

You could say that this is a more general problem in that if the “webpack build” fails in any way, Eclipse will keep relaunching it. I’m not sure how to prevent that, but it would help if the linter wasn’t a part of the Maven build (as at least it won’t fail for simple syntax stuff).

This seems to prevent the linter from running:

 bundles/org.openhab.ui/web/build/webpack.config.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bundles/org.openhab.ui/web/build/webpack.config.js b/bundles/org.openhab.ui/web/build/webpack.config.js
index e08ef61f..8115a14c 100644
--- a/bundles/org.openhab.ui/web/build/webpack.config.js
+++ b/bundles/org.openhab.ui/web/build/webpack.config.js
@@ -238,13 +238,13 @@ module.exports = {
       'process.env.TARGET': JSON.stringify(target)
     }),
     new VueLoaderPlugin(),
-    ...(env === 'production' ? [
+    ...(maven ? [] : (env === 'production' ? [
       new ESLintPlugin({
         extensions: ['js', 'vue']
       })
     ] : [
       // Development only plugins
-    ]),
+    ])),
     new HtmlWebpackPlugin({
       filename: './index.html',
       template: './src/index.html',