!!!Java und NodeJS Oft möchte man ein [NodeJS] Modul in ein Java-Projekt integrieren, beispielsweise mit dem Ziel einen Server für die Web-Applikation zur Verfügung zu stellen (Webpack serve etc. sind oft nicht die optimalen Produktivumgebungen). !!Maven Build of NodeJS Module Mit dem Plugin "frontend-maven-plugin" kann ein WAR-File gebaut werden: {{{ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.intersult</groupId> <artifactId>reactjs-test</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>${project.artifactId}</name> <description>ReactJS Test</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.12.1</version> <executions> <execution> <id>install-node-and-npm</id> <goals> <goal>install-node-and-npm</goal> </goals> </execution> <execution> <id>npm-install</id> <goals> <goal>npm</goal> </goals> </execution> <execution> <id>npm-build</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>run build</arguments> </configuration> </execution> </executions> <configuration> <nodeVersion>v18.8.0</nodeVersion> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <webResources> <resource> <directory>build</directory> </resource> </webResources> </configuration> </plugin> </plugins> </build> </project> }}} !!Bestehendes NodeJS-Modul integrieren Besser ist ein bestehendes NodeJS-Modul zu integrieren. NodeJS hat eine eigene Repository-Infrastruktur. Als Gateway gibt es das jnpm-maven-plugin: {{{ <plugin> <groupId>org.orienteer.jnpm</groupId> <artifactId>jnpm-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <?m2e execute onConfiguration?> <phase>generate-resources</phase> <goals> <goal>install</goal> </goals> <configuration> <registryUrl>https://registry.npmjs.org/</registryUrl> <strategy>ONE_DUMP</strategy> <outputDirectory>${project.build.directory}/generated-resources/jnpm/</outputDirectory> <pathPrefix>META-INF/resources</pathPrefix> <serverId>npmjs</serverId> <packages> <package>hello-world-server</package> </packages> <useCache>false</useCache> </configuration> </execution> </executions> </plugin> }}} !!!Jenkins Build mit NodeJS Jenkins kann auch native NodeJS Befehle ausführen. Das Plugin NodeJS unterstützt sowohl Standard-Builds als auch die Build-Pipeline. # Zunächst unter Jenkins verwalten -> Plugins verwalten gehen [NodeJS/jenkins verwalten.png] # Dort kann das NodeJS Plugin installiert werden [NodeJS/nodejs plugin.png] # Dann zurück auf Jenkins verwalten -> Konfiguration der Hilfsprogramme. Dort findet man (relativ weit unten) NodeJS Installationen und wiederum einen Knopf NodeJS hinzufügen. Dieser Knopf klappt die Sektion zur Installation von NodeJS und NPM auf. Darin eine entsprechende Konfiguration vornehmen [NodeJS/nodejs installationen.png] __Hinweis:__ Nach dem Speichern der Konfiguration scheint erst einmal gar nichts passiert zu sein. Die Installation von NodeJS und NPM ist jedoch Bestandteil eines entsprechenden Build-Prozesses und findet später an dieser Stelle statt. !!Jenkins Standard Build Nach der oben genannten Installation kann NodeJS und NPM nun im Build-Prozess verwendet werden. Es ist zu beanten, dass der Haken bei "Provide Node & npm bin/ folder to PATH" gesetzt wird. [NodeJS/jenkins build standard.png] !!Jenkins Pipeline Build NodeJS und NPM kann auch bei Pipeline-Builds verwendet werden. Das Plugin stellt dort den zusätzlichen Befehl "nodejs" zur Verfügung [NodeJS/jenkins build pipeline.png] {{{ pipeline { agent any stages { stage('Checkout') { steps { script { currentRevision = checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[cancelProcessOnExternalsFail: true, credentialsId: 'dynarocks.com', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: 'https://dynarocks.com/svn/com.intersult/trunk/com.intersult/internal/work/reactts-test']], quietOperation: true, workspaceUpdater: [$class: 'UpdateUpdater']]) } } } stage('Install') { steps { nodejs(nodeJSInstallationName: 'NodeJS') { sh 'npm install' } } } stage('Generate Sources') { steps { nodejs(nodeJSInstallationName: 'NodeJS') { sh 'npm run generate' } } } stage('Build') { steps { nodejs(nodeJSInstallationName: 'NodeJS') { sh 'npm run build' } } } } } }}} !!!Jenkins Build mit Docker Um Befehle auf Docker auszuführen, etwa Imgages Downloaden oder Container starten, is ein Zugang zu Docker erforderlich. # Läuft der Jenkins auf dem Host-System, kann direkt auf /var/run/docker.sock zugegriffen werden # Läuft Jenkins selbst als Docker Container kann dies durch ein Volume Mapping von /var/run/docker.sock erfolgen # In anderen Fällen kann DOCKER_HOST im ENV gesetzt werden Zunächst muss das Plugin "Docker Pipeline" installiert sein. [NodeJS/jenkins docker pipeline.png] In Jenkins verwalten -> Konfiguration der Hilfsprogramme wird das Plugin konfiguriert. [NodeJS/jenkins docker config.png] Zuletzt kann eine Pipeline wie folgt erzeugt werden: {{{ pipeline { agent { docker { image 'node:18.8.0-alpine3.16' } } stages { stage('Test') { steps { sh 'node --version' } } } } }}} [https://www.jenkins.io/doc/book/pipeline/docker/] !!!Authentication Generieren eines Passworts für die ~/.npmrc: {{{ echo -n 'admin:admin123' | openssl base64 }}} Die Zeile in .npmrc sieht dann so aus: {{{ registry=[...] _auth=YWRtaW46YWRtaW4xMjMNCg== }}} [https://help.sonatype.com/repomanager2/node-packaged-modules-and-npm-registries] !!!Express Alternativ zum Webpack Devserver gibt es noch den Express Server. Dieser kann auch verwendet werden, um eine Anwendung zu debuggen. Das erfolgt über die webpack-dev-middleware: {{{ import express from "express"; import webpack from "webpack"; import middleware from "webpack-dev-middleware"; import options from "./webpack.config"; const host = "localhost", port = 8090; const compiler = webpack(options); const server = express(); server.use("/", middleware(compiler)); server.use("/hello/**", (req, res) => { res.send("Hello Service!"); }); server.listen(port, () => { console.log("Server listening at http://" + host + ":" + port + contextPath); }); }}}