From dccc44041d601973dd86fd493420d3effc1aedc8 Mon Sep 17 00:00:00 2001 From: Peter Muessig Date: Thu, 23 May 2024 08:38:41 +0200 Subject: [PATCH] feat(ui5-middleware-servestatic): support npm package paths (#1006) --- packages/ui5-middleware-servestatic/README.md | 10 +++++- .../lib/serveStatic.js | 35 +++++++++++++++++-- showcases/ui5-app/ui5.yaml | 12 +++++++ .../webapp/controller/Main.controller.js | 18 +++++++++- 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/packages/ui5-middleware-servestatic/README.md b/packages/ui5-middleware-servestatic/README.md index b2eff7af4..9787dddd0 100644 --- a/packages/ui5-middleware-servestatic/README.md +++ b/packages/ui5-middleware-servestatic/README.md @@ -19,8 +19,16 @@ npm install ui5-middleware-servestatic --save-dev ## Configuration options (in `$yourapp/ui5.yaml`) +- debug: `boolean` + debug logging - rootPath: `string` - the root path to the static resources on your system + the root path to the static resources on your system (absolute or relative path to app) +- npmPackagePath: `string` + the npm package path pointing to the root path for the static resources (e.g. "`@scope/packageName/path`", "`packageName/path`", "`packageName`") + +> Hints: +> * If a `rootPath` is given, the `npmPackagePath` will be ignored +> * Values for `rootPath` or `npmPackagePath` can be also provided by environment variables by using the prefix `env.` e.g. `rootPath: env.MY_ENV_VAR` ## Usage diff --git a/packages/ui5-middleware-servestatic/lib/serveStatic.js b/packages/ui5-middleware-servestatic/lib/serveStatic.js index dfcbe8e1a..dde999c65 100644 --- a/packages/ui5-middleware-servestatic/lib/serveStatic.js +++ b/packages/ui5-middleware-servestatic/lib/serveStatic.js @@ -1,5 +1,6 @@ /* eslint-disable no-unused-vars */ const path = require("path"); +const fs = require("fs"); const serveStatic = require("serve-static"); require("dotenv").config(); @@ -36,12 +37,42 @@ const parseConfigOption = (optionValue) => { * @returns {Function} Middleware function to use */ module.exports = function ({ log, options }) { - let rootPath = parseConfigOption(options.configuration.rootPath); + const effectiveConfig = Object.assign({}, options?.configuration); + + // determine the root path + let rootPath = parseConfigOption(effectiveConfig.rootPath); + + // if no rootPath is given, we first check if an npm package path is given + if (!rootPath) { + // derive the scope and package name from the package name + const npmPackageScopeRegEx = /^(?:(@[^/]+)\/)?([^/]+)\/(.*)$/; + let npmPackagePath = parseConfigOption(effectiveConfig.npmPackagePath); + const parts = npmPackageScopeRegEx.exec(npmPackagePath); + if (parts) { + const scope = parts[1]; + const packageName = parts[2]; + const packagePath = parts[3]; + try { + const packageRoot = require.resolve(`${scope ? `${scope}/` : ""}${packageName}/package.json`); + rootPath = path.join(path.dirname(packageRoot), packagePath); + } catch (error) { + log.error(`Could not resolve npm package path ${npmPackagePath}`); + } + } + } + + // if still no rootPath is given, we throw an error if (!rootPath) { - throw new Error(`No Value for 'rootPath' supplied`); + throw new Error(`No value for 'rootPath' supplied! Please provide a 'rootPath' or 'npmPackagePath' in the configuration!`); + } + // if the rootPath does not exist, we throw an error + if (!fs.existsSync(rootPath)) { + throw new Error(`The 'rootPath' ${rootPath} does not exist!`); } + // resolve the rootPath to be absolute (should happen in serveStatic already, but used for logging) rootPath = path.resolve(rootPath); + // some logging to see the root path in case of issues options.configuration.debug ? log.info(`Starting static serve from ${rootPath}`) : null; return serveStatic(rootPath); diff --git a/showcases/ui5-app/ui5.yaml b/showcases/ui5-app/ui5.yaml index e840a773b..769e26e6c 100644 --- a/showcases/ui5-app/ui5.yaml +++ b/showcases/ui5-app/ui5.yaml @@ -108,6 +108,18 @@ server: configuration: debug: true rootPath: ../../docs + - name: ui5-middleware-servestatic + mountPath: "/sst/@ui5/webcomponents-icons" + afterMiddleware: compression + configuration: + debug: true + npmPackagePath: "@ui5/webcomponents-icons/dist/generated/assets" + - name: ui5-middleware-servestatic + mountPath: /sst/tui-image-editor + afterMiddleware: compression + configuration: + debug: true + npmPackagePath: "tui-image-editor/dist/svg" - name: ui5-middleware-simpleproxy mountPath: /versioninfo afterMiddleware: compression diff --git a/showcases/ui5-app/webapp/controller/Main.controller.js b/showcases/ui5-app/webapp/controller/Main.controller.js index 5f11fcfda..5bc1f433e 100644 --- a/showcases/ui5-app/webapp/controller/Main.controller.js +++ b/showcases/ui5-app/webapp/controller/Main.controller.js @@ -72,7 +72,23 @@ sap.ui.define( try { const helloResponse = await fetch("/proxy/local/hello.txt"); const helloContent = await helloResponse.text(); - console.log(helloContent); + console.log("simpleproxy", "local", helloContent); + } catch (err) { + console.error(err); + } + + try { + const webcResponse = await fetch("/sst/@ui5/webcomponents-icons/v5/SAP-icons.json"); + const webcContent = await webcResponse.json(); + console.log("servestatic", "@ui5/webcomponents-icons", webcContent); + } catch (err) { + console.error(err); + } + + try { + const tuiResponse = await fetch("/sst/tui-image-editor/icon-a.svg"); + const tuiContent = await tuiResponse.text(); + console.log("servestatic", "tui-image-editor", tuiContent.substring(0, 50) + "..."); } catch (err) { console.error(err); }