From 3f0bdfb4dc2fa769abde468a27bd9a10ce2ffb86 Mon Sep 17 00:00:00 2001 From: Peter Donker Date: Sun, 7 Dec 2025 22:25:45 +0100 Subject: [PATCH 1/6] Move servers PB module to RS Build --- .../ClientSide/Servers.Web/package.json | 35 +- .../ClientSide/Servers.Web/rsbuild.config.ts | 100 +++++ .../ClientSide/Servers.Web/webpack.config.js | 113 ------ yarn.lock | 352 ++++++++++++++++-- 4 files changed, 433 insertions(+), 167 deletions(-) create mode 100644 Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts delete mode 100644 Dnn.AdminExperience/ClientSide/Servers.Web/webpack.config.js diff --git a/Dnn.AdminExperience/ClientSide/Servers.Web/package.json b/Dnn.AdminExperience/ClientSide/Servers.Web/package.json index b1ce3ad1953..6fb7434b3a7 100644 --- a/Dnn.AdminExperience/ClientSide/Servers.Web/package.json +++ b/Dnn.AdminExperience/ClientSide/Servers.Web/package.json @@ -3,51 +3,30 @@ "version": "10.1.0", "private": true, "scripts": { - "build": "set NODE_ENV=production&&webpack --mode production", - "debug": "set NODE_ENV=debug&&webpack --mode production", - "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch", - "analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer", + "build": "set NODE_ENV=production&&rsbuild build", + "debug": "set NODE_ENV=debug&&rsbuild build", + "watch": "set NODE_ENV=debug & rsbuild dev", "lint": "eslint --fix" }, "devDependencies": { - "@babel/core": "^7.28.4", - "@babel/plugin-proposal-object-rest-spread": "^7.20.7", - "@babel/preset-env": "^7.28.3", - "@babel/preset-react": "^7.27.1", - "@babel/preset-typescript": "^7.28.5", "@dnnsoftware/dnn-react-common": "10.1.0", - "@svgr/webpack": "^8.1.0", + "@rsbuild/core": "^1.6.3", + "@rsbuild/plugin-less": "^1.5.0", + "@rsbuild/plugin-react": "^1.4.2", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.2", "@types/redux": "^3.6.31", - "babel-loader": "10.0.0", - "babel-plugin-transform-object-assign": "6.22.0", - "babel-plugin-transform-object-rest-spread": "6.26.0", - "babel-plugin-transform-react-remove-prop-types": "0.4.24", - "babel-polyfill": "6.26.0", "create-react-class": "^15.7.0", - "css-loader": "^7.1.2", "dayjs": "^1.11.18", "eslint": "9.38.0", "eslint-plugin-react": "7.37.5", - "eslint-webpack-plugin": "^5.0.2", - "file-loader": "6.2.0", "globals": "^16.4.0", "less": "4.4.2", - "less-loader": "12.3.0", - "null-loader": "^4.0.1", "prop-types": "^15.8.1", - "raw-loader": "4.0.2", "react": "^16.14.0", "react-dom": "^16.14.0", "react-hot-loader": "4.13.1", - "style-loader": "^4.0.0", - "typescript": "^5.9.3", - "url-loader": "4.1.1", - "webpack": "5.102.1", - "webpack-bundle-size-analyzer": "3.1.0", - "webpack-cli": "6.0.1", - "webpack-dev-server": "5.2.2" + "typescript": "^5.9.3" }, "dependencies": { "dompurify": "^3.3.0", diff --git a/Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts b/Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts new file mode 100644 index 00000000000..a90d8b8e25f --- /dev/null +++ b/Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts @@ -0,0 +1,100 @@ +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { pluginLess } from "@rsbuild/plugin-less"; +import path from "path"; +import { createRequire } from "module"; + +const requireModule = createRequire(__filename); +const webpackExternals = requireModule( + "@dnnsoftware/dnn-react-common/WebpackExternals" +); + +const resolveWebsitePath = () => { + try { + const settings = requireModule("../../../settings.local.json"); + if (settings?.WebsitePath) { + return settings.WebsitePath; + } + } catch { + // ignore missing local settings + } + return ""; +}; + +const websitePath = resolveWebsitePath(); +const isProduction = process.env.NODE_ENV === "production"; +const useWebsitePath = !isProduction && websitePath; + +export default defineConfig({ + source: { + entry: { + main: path.resolve(__dirname, "src/main.jsx"), + }, + }, + output: { + target: "web", + filenameHash: false, + cleanDistPath: false, + distPath: { + root: useWebsitePath + ? path.join( + websitePath, + "DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Servers/" + ) + : "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Servers/", + js: "scripts/bundles/", + css: "css/", + html: "", + }, + filename: { + js: "servers-bundle.js", + css: "Servers.css", + }, + legalComments: "none", + }, + performance: { + chunkSplit: { + strategy: "all-in-one", + }, + }, + tools: { + rspack: { + externals: (data) => { + const { request } = data; + // Handle exact matches + if (webpackExternals[request]) { + return webpackExternals[request]; + } + // Handle React submodules (e.g., react/jsx-runtime, react-dom/client) + if (request?.startsWith('react/') || request?.startsWith('react-dom/')) { + const baseModule = request.split('/')[0]; + if (webpackExternals[baseModule]) { + // For submodules, return the base module + return webpackExternals[baseModule]; + } + } + return undefined; + }, + resolve: { + modules: [ + path.resolve(__dirname, "./src"), + path.resolve(__dirname, "./node_modules"), + path.resolve(__dirname, "../../../node_modules"), + ], + }, + }, + }, + dev: { + writeToDisk: true, + hmr: false, + liveReload: false, + }, + plugins: [ + pluginReact({ + swcReactOptions: { + runtime: "classic", + }, + }), + pluginLess(), + ], +}); diff --git a/Dnn.AdminExperience/ClientSide/Servers.Web/webpack.config.js b/Dnn.AdminExperience/ClientSide/Servers.Web/webpack.config.js deleted file mode 100644 index cf53e85030a..00000000000 --- a/Dnn.AdminExperience/ClientSide/Servers.Web/webpack.config.js +++ /dev/null @@ -1,113 +0,0 @@ -const webpack = require("webpack"); -const ESLintPlugin = require("eslint-webpack-plugin"); -const packageJson = require("./package.json"); -const path = require("path"); -const webpackExternals = require("@dnnsoftware/dnn-react-common/WebpackExternals"); -const settings = require("../../../settings.local.json"); - -module.exports = (env, argv) => { - const isProduction = argv.mode === "production"; - return { - entry: "./src/main.jsx", - optimization: { - minimize: isProduction, - }, - output: { - path: - isProduction || settings.WebsitePath === "" - ? path.resolve( - "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Servers/scripts/bundles/" - ) - : path.join( - settings.WebsitePath, - "DesktopModules\\Admin\\Dnn.PersonaBar\\Modules\\Dnn.Servers\\scripts\\bundles\\" - ), - publicPath: isProduction ? "" : "http://localhost:8080/dist/", - filename: "servers-bundle.js", - }, - devServer: { - disableHostCheck: !isProduction, - }, - resolve: { - extensions: ["*", ".js", ".json", ".jsx", ".ts", ".tsx"], - modules: [ - path.resolve("./src"), // Look in src first - path.resolve("./node_modules"), // Try local node_modules - path.resolve("../../../node_modules"), // Last fallback to workspaces node_modules - ], - }, - module: { - rules: [ - { - test: /\.less$/, - use: [ - { - loader: "style-loader", // creates style nodes from JS strings - }, - { - loader: "css-loader", - options: { - importLoaders: 1, - sourceMap: true, - modules: { - auto: true, - mode: "global", - localIdentName: "[name]__[local]___[hash:base64:5]", - }, - esModule: false, - }, - }, - { - loader: "less-loader", // compiles Less to CSS - }, - ], - }, - { - test: /\.(js|jsx|ts|tsx)$/, - exclude: /node_modules/, - use: { - loader: "babel-loader", - options: { - presets: ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"], - }, - }, - }, - { - test: /\.(ttf|woff)$/, - use: { - loader: "url-loader?limit=8192", - }, - }, - { - test: /\.(d.ts)$/, - use: ["null-loader"], - }, - { - test: /\.svg$/i, - issuer: /\.[jt]sx?$/, - use: ["@svgr/webpack"], - }, - ], - }, - externals: webpackExternals, - plugins: - [ - isProduction - ? new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - "process.env": { - NODE_ENV: JSON.stringify("production"), - }, - }) - : new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - }), - new webpack.SourceMapDevToolPlugin({ - filename: "servers-bundle.js.map", - append: "\n//# sourceMappingURL=/DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Servers/scripts/bundles/servers-bundle.js.map" - }), - new ESLintPlugin({fix: true}), - ], - devtool: false, - }; -}; diff --git a/yarn.lock b/yarn.lock index a1d6012f4ef..eff1a11a3b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1971,6 +1971,16 @@ __metadata: languageName: node linkType: hard +"@emnapi/core@npm:^1.5.0": + version: 1.7.1 + resolution: "@emnapi/core@npm:1.7.1" + dependencies: + "@emnapi/wasi-threads": "npm:1.1.0" + tslib: "npm:^2.4.0" + checksum: 10/260841f6dd2a7823a964d9de6da3a5e6f565dac8d21a5bd8f6215b87c45c22a4dc371b9ad877961579ee3cca8a76e55e3dd033ae29cba1998999cda6d794bdab + languageName: node + linkType: hard + "@emnapi/runtime@npm:^1.1.0, @emnapi/runtime@npm:^1.4.3": version: 1.5.0 resolution: "@emnapi/runtime@npm:1.5.0" @@ -1980,6 +1990,15 @@ __metadata: languageName: node linkType: hard +"@emnapi/runtime@npm:^1.5.0": + version: 1.7.1 + resolution: "@emnapi/runtime@npm:1.7.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/6fc83f938e3c70e32e84c1fbe5cab6cb9340b8107cee4048384ad5b8f2998a06502b4bed342acaf6e44f473f2c14c4ab1e3fd5083bd7823fc63abfca9eff0175 + languageName: node + linkType: hard + "@emnapi/wasi-threads@npm:1.1.0": version: 1.1.0 resolution: "@emnapi/wasi-threads@npm:1.1.0" @@ -3261,6 +3280,61 @@ __metadata: languageName: node linkType: hard +"@module-federation/error-codes@npm:0.21.6": + version: 0.21.6 + resolution: "@module-federation/error-codes@npm:0.21.6" + checksum: 10/6ded1ecab780f1f9ec46a59adb200e75cdf11580d70aa79dd75d71fbbf276615690da277ea67aa1ceb5bc88386f5708cc1d2ba5526be5c9ff02397a6123e36bf + languageName: node + linkType: hard + +"@module-federation/runtime-core@npm:0.21.6": + version: 0.21.6 + resolution: "@module-federation/runtime-core@npm:0.21.6" + dependencies: + "@module-federation/error-codes": "npm:0.21.6" + "@module-federation/sdk": "npm:0.21.6" + checksum: 10/85efa2042d6f3a7cf0e4971b991472d4339d88f6f15684afb6d451f19ed934e225b2510c86b7bb4d2c5f64253ed7b0175f08c17f95bfc2b9929930a8a03fff1e + languageName: node + linkType: hard + +"@module-federation/runtime-tools@npm:0.21.6": + version: 0.21.6 + resolution: "@module-federation/runtime-tools@npm:0.21.6" + dependencies: + "@module-federation/runtime": "npm:0.21.6" + "@module-federation/webpack-bundler-runtime": "npm:0.21.6" + checksum: 10/36e7ccab948e11f310e87397a1a2185b56064e5691e553b34173686e2bc7372ec710e5ad48c026eb28c85b168765788b743aa2111513f3b57118b47636312dd1 + languageName: node + linkType: hard + +"@module-federation/runtime@npm:0.21.6": + version: 0.21.6 + resolution: "@module-federation/runtime@npm:0.21.6" + dependencies: + "@module-federation/error-codes": "npm:0.21.6" + "@module-federation/runtime-core": "npm:0.21.6" + "@module-federation/sdk": "npm:0.21.6" + checksum: 10/93fd9bb284630933cab7e4bc070d648b56272f3636038c05eec7d1e3eeb189be3ccebe5f8ecc450197ee992d2616ed282d54e673ec0acd63adee4faddf80b144 + languageName: node + linkType: hard + +"@module-federation/sdk@npm:0.21.6": + version: 0.21.6 + resolution: "@module-federation/sdk@npm:0.21.6" + checksum: 10/effc4aa932e2f06742bda8f02aaec84e138f5512b50f18c38b051490020b20d3d8edf7ece853fccffc1f78a0b43dec78e69bf02150e7e2801d5ce03c3ee367b9 + languageName: node + linkType: hard + +"@module-federation/webpack-bundler-runtime@npm:0.21.6": + version: 0.21.6 + resolution: "@module-federation/webpack-bundler-runtime@npm:0.21.6" + dependencies: + "@module-federation/runtime": "npm:0.21.6" + "@module-federation/sdk": "npm:0.21.6" + checksum: 10/a5ceb72ee3867acad5d7d3c654eb568068b1d5288f60ce9301bdc9f56effa5a4c26a732a2cec7176a81b87139566cd51dd8dfbc6112da05d47b870fa3ad3ba1f + languageName: node + linkType: hard + "@napi-rs/wasm-runtime@npm:0.2.4": version: 0.2.4 resolution: "@napi-rs/wasm-runtime@npm:0.2.4" @@ -3272,6 +3346,17 @@ __metadata: languageName: node linkType: hard +"@napi-rs/wasm-runtime@npm:1.0.7": + version: 1.0.7 + resolution: "@napi-rs/wasm-runtime@npm:1.0.7" + dependencies: + "@emnapi/core": "npm:^1.5.0" + "@emnapi/runtime": "npm:^1.5.0" + "@tybys/wasm-util": "npm:^0.10.1" + checksum: 10/6bc32d32d486d07b83220a9b7b2b715e39acacbacef0011ebca05c00b41d80a0535123da10fea7a7d6d7e206712bb50dc50ac3cf88b770754d44378570fb5c05 + languageName: node + linkType: hard + "@napi-rs/wasm-runtime@npm:^0.2.11": version: 0.2.12 resolution: "@napi-rs/wasm-runtime@npm:0.2.12" @@ -4198,6 +4283,195 @@ __metadata: languageName: node linkType: hard +"@rsbuild/core@npm:^1.6.3": + version: 1.6.13 + resolution: "@rsbuild/core@npm:1.6.13" + dependencies: + "@rspack/core": "npm:1.6.6" + "@rspack/lite-tapable": "npm:~1.1.0" + "@swc/helpers": "npm:^0.5.17" + core-js: "npm:~3.47.0" + jiti: "npm:^2.6.1" + bin: + rsbuild: bin/rsbuild.js + checksum: 10/e85aaf8b87d6e84bcf2e9c75e4253924bd837410be813a8cda7c48d52f607b8bf3c6d4834e98a3a94bb7e0c79c5af104129d31631c23d627ca53c5e1d3fe6e4c + languageName: node + linkType: hard + +"@rsbuild/plugin-less@npm:^1.5.0": + version: 1.5.0 + resolution: "@rsbuild/plugin-less@npm:1.5.0" + dependencies: + deepmerge: "npm:^4.3.1" + reduce-configs: "npm:^1.1.1" + peerDependencies: + "@rsbuild/core": 1.x + checksum: 10/2d5d28b9f38a7e5e3dc38441840b4de3a1c0e7ca18b435336f44150a317259b6d86837bcea4c3172758e602b42458870c5f366a357af214563e568e2685a1c93 + languageName: node + linkType: hard + +"@rsbuild/plugin-react@npm:^1.4.2": + version: 1.4.2 + resolution: "@rsbuild/plugin-react@npm:1.4.2" + dependencies: + "@rspack/plugin-react-refresh": "npm:^1.5.2" + react-refresh: "npm:^0.18.0" + peerDependencies: + "@rsbuild/core": 1.x + checksum: 10/5726a9fba7ddf358ab12764c042273ad400715d853d18dd4fe83b29254504d12db9c39da5a51054f7efc5a3947a8622fc5de7d186e231d6d53a0ec68ca19f6a8 + languageName: node + linkType: hard + +"@rspack/binding-darwin-arm64@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-darwin-arm64@npm:1.6.6" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rspack/binding-darwin-x64@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-darwin-x64@npm:1.6.6" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rspack/binding-linux-arm64-gnu@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-linux-arm64-gnu@npm:1.6.6" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rspack/binding-linux-arm64-musl@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-linux-arm64-musl@npm:1.6.6" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rspack/binding-linux-x64-gnu@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-linux-x64-gnu@npm:1.6.6" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rspack/binding-linux-x64-musl@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-linux-x64-musl@npm:1.6.6" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rspack/binding-wasm32-wasi@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-wasm32-wasi@npm:1.6.6" + dependencies: + "@napi-rs/wasm-runtime": "npm:1.0.7" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@rspack/binding-win32-arm64-msvc@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-win32-arm64-msvc@npm:1.6.6" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rspack/binding-win32-ia32-msvc@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-win32-ia32-msvc@npm:1.6.6" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rspack/binding-win32-x64-msvc@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding-win32-x64-msvc@npm:1.6.6" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rspack/binding@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/binding@npm:1.6.6" + dependencies: + "@rspack/binding-darwin-arm64": "npm:1.6.6" + "@rspack/binding-darwin-x64": "npm:1.6.6" + "@rspack/binding-linux-arm64-gnu": "npm:1.6.6" + "@rspack/binding-linux-arm64-musl": "npm:1.6.6" + "@rspack/binding-linux-x64-gnu": "npm:1.6.6" + "@rspack/binding-linux-x64-musl": "npm:1.6.6" + "@rspack/binding-wasm32-wasi": "npm:1.6.6" + "@rspack/binding-win32-arm64-msvc": "npm:1.6.6" + "@rspack/binding-win32-ia32-msvc": "npm:1.6.6" + "@rspack/binding-win32-x64-msvc": "npm:1.6.6" + dependenciesMeta: + "@rspack/binding-darwin-arm64": + optional: true + "@rspack/binding-darwin-x64": + optional: true + "@rspack/binding-linux-arm64-gnu": + optional: true + "@rspack/binding-linux-arm64-musl": + optional: true + "@rspack/binding-linux-x64-gnu": + optional: true + "@rspack/binding-linux-x64-musl": + optional: true + "@rspack/binding-wasm32-wasi": + optional: true + "@rspack/binding-win32-arm64-msvc": + optional: true + "@rspack/binding-win32-ia32-msvc": + optional: true + "@rspack/binding-win32-x64-msvc": + optional: true + checksum: 10/37b69398a0679c25e0479b6eb11ea2c110a8b57367af2c808a473d19d58c9dd09e7763b3dfbec06284d6863e7a301d71509128fe22da2b0c57c06b718f67e66a + languageName: node + linkType: hard + +"@rspack/core@npm:1.6.6": + version: 1.6.6 + resolution: "@rspack/core@npm:1.6.6" + dependencies: + "@module-federation/runtime-tools": "npm:0.21.6" + "@rspack/binding": "npm:1.6.6" + "@rspack/lite-tapable": "npm:1.1.0" + peerDependencies: + "@swc/helpers": ">=0.5.1" + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: 10/e706c19085729f52f3e80c6945edc32def2091270fc9a15d6aea336754719d0bdce93e62dae3a675c412b5e433cc2fc093591d74e731722196d0de2ff269b198 + languageName: node + linkType: hard + +"@rspack/lite-tapable@npm:1.1.0, @rspack/lite-tapable@npm:~1.1.0": + version: 1.1.0 + resolution: "@rspack/lite-tapable@npm:1.1.0" + checksum: 10/41ff73fe5e1b8dccaad746c9c1bd36dd67649e1ad35776f311b5ba94333a397704e11158579e25a6a7e677c51abe35e66987b1b000faef48d4e4ad2470fea150 + languageName: node + linkType: hard + +"@rspack/plugin-react-refresh@npm:^1.5.2": + version: 1.5.3 + resolution: "@rspack/plugin-react-refresh@npm:1.5.3" + dependencies: + error-stack-parser: "npm:^2.1.4" + html-entities: "npm:^2.6.0" + peerDependencies: + react-refresh: ">=0.10.0 <1.0.0" + webpack-hot-middleware: 2.x + peerDependenciesMeta: + webpack-hot-middleware: + optional: true + checksum: 10/3886a13dca3d42e9245480283ab839c16015a48eceda0d7352114de26968e319e8f110c5ec4dbe4c20d4a8457b368401840c736ce49f774edd450cf3ba193f62 + languageName: node + linkType: hard + "@rtsao/scc@npm:^1.1.0": version: 1.1.0 resolution: "@rtsao/scc@npm:1.1.0" @@ -4914,6 +5188,15 @@ __metadata: languageName: node linkType: hard +"@swc/helpers@npm:^0.5.17": + version: 0.5.17 + resolution: "@swc/helpers@npm:0.5.17" + dependencies: + tslib: "npm:^2.8.0" + checksum: 10/1fc8312a78f1f99c8ec838585445e99763eeebff2356100738cdfdb8ad47d2d38df678ee6edd93a90fe319ac52da67adc14ac00eb82b606c5fb8ebc5d06ec2a2 + languageName: node + linkType: hard + "@swc/types@npm:^0.1.25": version: 0.1.25 resolution: "@swc/types@npm:0.1.25" @@ -4981,7 +5264,7 @@ __metadata: languageName: node linkType: hard -"@tybys/wasm-util@npm:^0.10.0": +"@tybys/wasm-util@npm:^0.10.0, @tybys/wasm-util@npm:^0.10.1": version: 0.10.1 resolution: "@tybys/wasm-util@npm:0.10.1" dependencies: @@ -8972,6 +9255,13 @@ __metadata: languageName: node linkType: hard +"core-js@npm:~3.47.0": + version: 3.47.0 + resolution: "core-js@npm:3.47.0" + checksum: 10/c02dc6a091c7e6799e3527dc06a428c44bbcff7f8f6ee700ff818b90aa2ebaf1f17b0234146e692811da97cda5a39a6095ecadec9fd1a74b1135103eb0e96cb1 + languageName: node + linkType: hard + "core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" @@ -10418,6 +10708,15 @@ __metadata: languageName: node linkType: hard +"error-stack-parser@npm:^2.1.4": + version: 2.1.4 + resolution: "error-stack-parser@npm:2.1.4" + dependencies: + stackframe: "npm:^1.3.4" + checksum: 10/23db33135bfc6ba701e5eee45e1bb9bd2fe33c5d4f9927440d9a499c7ac538f91f455fcd878611361269893c56734419252c40d8105eb3b023cf8b0fc2ebb64e + languageName: node + linkType: hard + "es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0": version: 1.24.0 resolution: "es-abstract@npm:1.24.0" @@ -12570,7 +12869,7 @@ __metadata: languageName: node linkType: hard -"html-entities@npm:^2.1.0": +"html-entities@npm:^2.1.0, html-entities@npm:^2.6.0": version: 2.6.0 resolution: "html-entities@npm:2.6.0" checksum: 10/06d4e7a3ba6243bba558af176e56f85e09894b26d911bc1ef7b2b9b3f18b46604360805b32636f080e954778e9a34313d1982479a05a5aa49791afd6a4229346 @@ -18402,6 +18701,13 @@ __metadata: languageName: node linkType: hard +"react-refresh@npm:^0.18.0": + version: 0.18.0 + resolution: "react-refresh@npm:0.18.0" + checksum: 10/504c331c19776bf8320c23bad7f80b3a28de03301ed7523b0dd21d3f02bf2b53bbdd5aa52469b187bc90f358614b2ba303c088a0765c95f4f0a68c43a7d67b1d + languageName: node + linkType: hard + "react-router-dom@npm:^6.26.0": version: 6.30.2 resolution: "react-router-dom@npm:6.30.2" @@ -18760,6 +19066,13 @@ __metadata: languageName: node linkType: hard +"reduce-configs@npm:^1.1.1": + version: 1.1.1 + resolution: "reduce-configs@npm:1.1.1" + checksum: 10/aa11df7e3d3efb949b0286e641487f3b8c3e90edddb6483559a6d3dbbcb32ad259b38ffceff16e1db1f6753e192dffd0803b6dd291f66c2d437c510fed79a091 + languageName: node + linkType: hard + "redux-devtools-dock-monitor@npm:1.2.0, redux-devtools-dock-monitor@npm:^1.2.0": version: 1.2.0 resolution: "redux-devtools-dock-monitor@npm:1.2.0" @@ -20064,47 +20377,27 @@ __metadata: version: 0.0.0-use.local resolution: "servers@workspace:Dnn.AdminExperience/ClientSide/Servers.Web" dependencies: - "@babel/core": "npm:^7.28.4" - "@babel/plugin-proposal-object-rest-spread": "npm:^7.20.7" - "@babel/preset-env": "npm:^7.28.3" - "@babel/preset-react": "npm:^7.27.1" - "@babel/preset-typescript": "npm:^7.28.5" "@dnnsoftware/dnn-react-common": "npm:10.1.0" - "@svgr/webpack": "npm:^8.1.0" + "@rsbuild/core": "npm:^1.6.3" + "@rsbuild/plugin-less": "npm:^1.5.0" + "@rsbuild/plugin-react": "npm:^1.4.2" "@types/react": "npm:^19.2.2" "@types/react-dom": "npm:^19.2.2" "@types/redux": "npm:^3.6.31" - babel-loader: "npm:10.0.0" - babel-plugin-transform-object-assign: "npm:6.22.0" - babel-plugin-transform-object-rest-spread: "npm:6.26.0" - babel-plugin-transform-react-remove-prop-types: "npm:0.4.24" - babel-polyfill: "npm:6.26.0" create-react-class: "npm:^15.7.0" - css-loader: "npm:^7.1.2" dayjs: "npm:^1.11.18" dompurify: "npm:^3.3.0" eslint: "npm:9.38.0" eslint-plugin-react: "npm:7.37.5" - eslint-webpack-plugin: "npm:^5.0.2" - file-loader: "npm:6.2.0" globals: "npm:^16.4.0" html-react-parser: "npm:^5.2.10" less: "npm:4.4.2" - less-loader: "npm:12.3.0" - null-loader: "npm:^4.0.1" prop-types: "npm:^15.8.1" - raw-loader: "npm:4.0.2" react: "npm:^16.14.0" react-custom-scrollbars: "npm:^4.2.1" react-dom: "npm:^16.14.0" react-hot-loader: "npm:4.13.1" - style-loader: "npm:^4.0.0" typescript: "npm:^5.9.3" - url-loader: "npm:4.1.1" - webpack: "npm:5.102.1" - webpack-bundle-size-analyzer: "npm:3.1.0" - webpack-cli: "npm:6.0.1" - webpack-dev-server: "npm:5.2.2" languageName: unknown linkType: soft @@ -20778,6 +21071,13 @@ __metadata: languageName: node linkType: hard +"stackframe@npm:^1.3.4": + version: 1.3.4 + resolution: "stackframe@npm:1.3.4" + checksum: 10/29ca71c1fd17974c1c178df0236b1407bc65f6ea389cc43dec000def6e42ff548d4453de9a85b76469e2ae2b2abdd802c6b6f3db947c05794efbd740d1cf4121 + languageName: node + linkType: hard + "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -21817,7 +22117,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0": +"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10/3e2e043d5c2316461cb54e5c7fe02c30ef6dccb3384717ca22ae5c6b5bc95232a6241df19c622d9c73b809bea33b187f6dbc73030963e29950c2141bc32a79f7 From 80809a56754141efc0e58eefb45b3d01cb7e21ea Mon Sep 17 00:00:00 2001 From: Peter Donker Date: Sun, 7 Dec 2025 22:34:27 +0100 Subject: [PATCH 2/6] Do not output html --- Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts b/Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts index a90d8b8e25f..d0b116301a7 100644 --- a/Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts +++ b/Dnn.AdminExperience/ClientSide/Servers.Web/rsbuild.config.ts @@ -83,6 +83,7 @@ export default defineConfig({ ], }, }, + htmlPlugin: false, }, dev: { writeToDisk: true, From e436c8b253e602ec6d6c2f387cf11cfae691b97c Mon Sep 17 00:00:00 2001 From: Peter Donker Date: Sun, 7 Dec 2025 23:18:49 +0100 Subject: [PATCH 3/6] Move seo project to rsbuild --- .../ClientSide/Seo.Web/package.json | 31 ++--- .../ClientSide/Seo.Web/rsbuild.config.ts | 111 ++++++++++++++++++ .../ClientSide/Seo.Web/webpack.config.js | 106 ----------------- yarn.lock | 22 +--- 4 files changed, 121 insertions(+), 149 deletions(-) create mode 100644 Dnn.AdminExperience/ClientSide/Seo.Web/rsbuild.config.ts delete mode 100644 Dnn.AdminExperience/ClientSide/Seo.Web/webpack.config.js diff --git a/Dnn.AdminExperience/ClientSide/Seo.Web/package.json b/Dnn.AdminExperience/ClientSide/Seo.Web/package.json index f5328bc21ec..18774ffa301 100644 --- a/Dnn.AdminExperience/ClientSide/Seo.Web/package.json +++ b/Dnn.AdminExperience/ClientSide/Seo.Web/package.json @@ -3,46 +3,29 @@ "version": "10.1.0", "private": true, "scripts": { - "build": "set NODE_ENV=production&&webpack --mode production", - "debug": "set NODE_ENV=debug&&webpack --mode production", - "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch", - "analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer", + "build": "set NODE_ENV=production&&rsbuild build", + "debug": "set NODE_ENV=debug&&rsbuild build", + "watch": "set NODE_ENV=debug & rsbuild dev", "lint": "eslint --fix" }, "devDependencies": { - "@babel/core": "^7.28.4", - "@babel/plugin-proposal-object-rest-spread": "^7.20.7", - "@babel/preset-env": "^7.28.3", - "@babel/preset-react": "^7.27.1", "@dnnsoftware/dnn-react-common": "10.1.0", + "@rsbuild/core": "^1.6.3", + "@rsbuild/plugin-less": "^1.5.0", + "@rsbuild/plugin-react": "^1.4.2", "array.prototype.find": "2.2.3", "array.prototype.findindex": "2.2.4", - "babel-loader": "10.0.0", - "babel-plugin-transform-object-assign": "6.22.0", - "babel-plugin-transform-object-rest-spread": "6.26.0", - "babel-plugin-transform-react-remove-prop-types": "0.4.24", - "babel-polyfill": "6.26.0", "create-react-class": "^15.7.0", - "css-loader": "^7.1.2", "es6-object-assign": "1.1.0", "eslint": "9.38.0", "eslint-plugin-react": "7.37.5", "eslint-webpack-plugin": "^5.0.2", - "file-loader": "6.2.0", "globals": "^16.4.0", "less": "4.4.2", - "less-loader": "12.3.0", "prop-types": "^15.8.1", - "raw-loader": "4.0.2", "react": "^16.14.0", "react-dom": "^16.14.0", "react-hot-loader": "4.13.1", - "react-modal": "3.16.3", - "style-loader": "^4.0.0", - "url-loader": "4.1.1", - "webpack": "5.102.1", - "webpack-bundle-size-analyzer": "3.1.0", - "webpack-cli": "6.0.1", - "webpack-dev-server": "5.2.2" + "react-modal": "3.16.3" } } diff --git a/Dnn.AdminExperience/ClientSide/Seo.Web/rsbuild.config.ts b/Dnn.AdminExperience/ClientSide/Seo.Web/rsbuild.config.ts new file mode 100644 index 00000000000..90162ffd302 --- /dev/null +++ b/Dnn.AdminExperience/ClientSide/Seo.Web/rsbuild.config.ts @@ -0,0 +1,111 @@ +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { pluginLess } from "@rsbuild/plugin-less"; +import path from "path"; +import { createRequire } from "module"; + +const requireModule = createRequire(__filename); +const webpackExternals = requireModule( + "@dnnsoftware/dnn-react-common/WebpackExternals" +); + +const resolveWebsitePath = () => { + try { + const settings = requireModule("../../../settings.local.json"); + if (settings?.WebsitePath) { + return settings.WebsitePath; + } + } catch { + // ignore missing local settings + } + return ""; +}; + +const websitePath = resolveWebsitePath(); +const isProduction = process.env.NODE_ENV === "production"; +const useWebsitePath = !isProduction && websitePath; + +export default defineConfig({ + source: { + entry: { + main: path.resolve(__dirname, "src/main.jsx"), + }, + }, + output: { + target: "web", + filenameHash: false, + cleanDistPath: false, + cssModules: { + auto: true, + localIdentName: "[local]", + }, + distPath: { + root: useWebsitePath + ? path.join( + websitePath, + "DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Seo/" + ) + : "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Seo/", + js: "scripts/bundles/", + css: "css/", + html: "", + }, + filename: { + js: "seo-bundle.js", + css: "Seo.css", + }, + legalComments: "none", + }, + performance: { + chunkSplit: { + strategy: "all-in-one", + }, + }, + tools: { + rspack: { + externals: (data) => { + const { request } = data; + // Handle exact matches + if (webpackExternals[request]) { + return webpackExternals[request]; + } + // Handle React submodules (e.g., react/jsx-runtime, react-dom/client) + if (request?.startsWith('react/') || request?.startsWith('react-dom/')) { + const baseModule = request.split('/')[0]; + if (webpackExternals[baseModule]) { + // For submodules, return the base module + return webpackExternals[baseModule]; + } + } + return undefined; + }, + resolve: { + modules: [ + path.resolve(__dirname, "./src"), + path.resolve(__dirname, "./node_modules"), + path.resolve(__dirname, "../../../node_modules"), + ], + }, + }, + htmlPlugin: false, + }, + dev: { + writeToDisk: true, + hmr: false, + liveReload: false, + }, + plugins: [ + pluginReact({ + swcReactOptions: { + runtime: "classic", + }, + }), + pluginLess({ + lessLoaderOptions: { + lessOptions: { + javascriptEnabled: true, + }, + }, + }), + ], +}); diff --git a/Dnn.AdminExperience/ClientSide/Seo.Web/webpack.config.js b/Dnn.AdminExperience/ClientSide/Seo.Web/webpack.config.js deleted file mode 100644 index 509d5ab7434..00000000000 --- a/Dnn.AdminExperience/ClientSide/Seo.Web/webpack.config.js +++ /dev/null @@ -1,106 +0,0 @@ -const webpack = require("webpack"); -const ESLintPlugin = require("eslint-webpack-plugin"); -const packageJson = require("./package.json"); -const path = require("path"); -const webpackExternals = require("@dnnsoftware/dnn-react-common/WebpackExternals"); -const settings = require("../../../settings.local.json"); - -module.exports = (env, argv) => { - const isProduction = argv.mode === "production"; - return { - entry: "./src/main.jsx", - optimization: { - minimize: isProduction, - }, - output: { - path: - // eslint-disable-next-line eqeqeq -- Types as any, so let's be safe, could just be undefined or null. - isProduction || settings.WebsitePath == "" - ? path.resolve( - "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Seo/scripts/bundles/" - ) - : path.join( - settings.WebsitePath, - "DesktopModules\\Admin\\Dnn.PersonaBar\\Modules\\Dnn.Seo\\scripts\\bundles\\" - ), - publicPath: isProduction ? "" : "http://localhost:8080/dist/", - filename: "seo-bundle.js", - }, - devServer: { - disableHostCheck: !isProduction, - }, - resolve: { - extensions: ["*", ".js", ".json", ".jsx"], - modules: [ - path.resolve("./src"), // Look in src first - path.resolve("./node_modules"), // Try local node_modules - path.resolve("../../../node_modules"), // Last fallback to workspaces node_modules - ], - }, - module: { - rules: [ - { - test: /\.less$/, - use: [ - { - loader: "style-loader", // creates style nodes from JS strings - }, - { - loader: "css-loader", - options: { - importLoaders: 1, - sourceMap: true, - modules: { - auto: true, - mode: "global", - localIdentName: "[name]__[local]___[hash:base64:5]", - }, - esModule: false, - }, - }, - { - loader: "less-loader", // compiles Less to CSS - }, - ], - }, - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - use: { - loader: "babel-loader", - options: { - presets: ["@babel/preset-env", "@babel/preset-react"], - }, - }, - }, - { - test: /\.(ttf|woff)$/, - use: { - loader: "url-loader?limit=8192", - }, - }, - ], - }, - externals: webpackExternals, - - plugins: - [ - isProduction - ? new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - "process.env": { - NODE_ENV: JSON.stringify("production"), - }, - }) - : new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - }), - new webpack.SourceMapDevToolPlugin({ - filename: "seo-bundle.js.map", - append: "\n//# sourceMappingURL=/DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Seo/scripts/bundles/seo-bundle.js.map" - }), - new ESLintPlugin({fix: true}), - ], - devtool: false, - }; -}; diff --git a/yarn.lock b/yarn.lock index eff1a11a3b4..e9da49adaf2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20286,40 +20286,24 @@ __metadata: version: 0.0.0-use.local resolution: "seo@workspace:Dnn.AdminExperience/ClientSide/Seo.Web" dependencies: - "@babel/core": "npm:^7.28.4" - "@babel/plugin-proposal-object-rest-spread": "npm:^7.20.7" - "@babel/preset-env": "npm:^7.28.3" - "@babel/preset-react": "npm:^7.27.1" "@dnnsoftware/dnn-react-common": "npm:10.1.0" + "@rsbuild/core": "npm:^1.6.3" + "@rsbuild/plugin-less": "npm:^1.5.0" + "@rsbuild/plugin-react": "npm:^1.4.2" array.prototype.find: "npm:2.2.3" array.prototype.findindex: "npm:2.2.4" - babel-loader: "npm:10.0.0" - babel-plugin-transform-object-assign: "npm:6.22.0" - babel-plugin-transform-object-rest-spread: "npm:6.26.0" - babel-plugin-transform-react-remove-prop-types: "npm:0.4.24" - babel-polyfill: "npm:6.26.0" create-react-class: "npm:^15.7.0" - css-loader: "npm:^7.1.2" es6-object-assign: "npm:1.1.0" eslint: "npm:9.38.0" eslint-plugin-react: "npm:7.37.5" eslint-webpack-plugin: "npm:^5.0.2" - file-loader: "npm:6.2.0" globals: "npm:^16.4.0" less: "npm:4.4.2" - less-loader: "npm:12.3.0" prop-types: "npm:^15.8.1" - raw-loader: "npm:4.0.2" react: "npm:^16.14.0" react-dom: "npm:^16.14.0" react-hot-loader: "npm:4.13.1" react-modal: "npm:3.16.3" - style-loader: "npm:^4.0.0" - url-loader: "npm:4.1.1" - webpack: "npm:5.102.1" - webpack-bundle-size-analyzer: "npm:3.1.0" - webpack-cli: "npm:6.0.1" - webpack-dev-server: "npm:5.2.2" languageName: unknown linkType: soft From 2fdb5f58588efb4f1c312568e5db4cdc05e1239a Mon Sep 17 00:00:00 2001 From: Peter Donker Date: Mon, 8 Dec 2025 22:42:32 +0100 Subject: [PATCH 4/6] Add security module --- .../ClientSide/Security.Web/.babelrc | 18 --- .../ClientSide/Security.Web/package.json | 33 ++--- .../ClientSide/Security.Web/rsbuild.config.ts | 113 ++++++++++++++++++ .../src/components/ipFilters/index.jsx | 6 +- .../ipFilters/ipFilterRow/index.jsx | 12 +- .../components/securityBulletins/index.jsx | 4 +- .../ClientSide/Security.Web/webpack.config.js | 108 ----------------- yarn.lock | 49 ++++---- 8 files changed, 160 insertions(+), 183 deletions(-) delete mode 100644 Dnn.AdminExperience/ClientSide/Security.Web/.babelrc create mode 100644 Dnn.AdminExperience/ClientSide/Security.Web/rsbuild.config.ts delete mode 100644 Dnn.AdminExperience/ClientSide/Security.Web/webpack.config.js diff --git a/Dnn.AdminExperience/ClientSide/Security.Web/.babelrc b/Dnn.AdminExperience/ClientSide/Security.Web/.babelrc deleted file mode 100644 index abf8266fb83..00000000000 --- a/Dnn.AdminExperience/ClientSide/Security.Web/.babelrc +++ /dev/null @@ -1,18 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-react" - ], - "plugins": [ - "@babel/plugin-transform-react-jsx", - "@babel/plugin-proposal-object-rest-spread", - "react-hot-loader/babel" - ], - "env": { - "production": { - "plugins": [ - "transform-react-remove-prop-types" - ] - } - } -} \ No newline at end of file diff --git a/Dnn.AdminExperience/ClientSide/Security.Web/package.json b/Dnn.AdminExperience/ClientSide/Security.Web/package.json index 76130e6aacd..2e13a398420 100644 --- a/Dnn.AdminExperience/ClientSide/Security.Web/package.json +++ b/Dnn.AdminExperience/ClientSide/Security.Web/package.json @@ -3,34 +3,24 @@ "version": "10.1.0", "private": true, "scripts": { - "build": "set NODE_ENV=production&&webpack --mode production", - "debug": "set NODE_ENV=debug&&webpack --mode development", - "watch": "set NODE_ENV=debug && webpack --mode=development --progress --watch", - "analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer", + "build": "set NODE_ENV=production&&rsbuild build", + "debug": "set NODE_ENV=debug&&rsbuild build", + "watch": "set NODE_ENV=debug & rsbuild dev", "lint": "eslint --fix" }, "devDependencies": { - "@babel/core": "^7.28.4", - "@babel/plugin-proposal-object-rest-spread": "^7.20.7", - "@babel/plugin-transform-react-jsx": "^7.27.1", - "@babel/preset-env": "^7.28.3", - "@babel/preset-react": "^7.27.1", - "@babel/preset-typescript": "^7.28.5", "@dnnsoftware/dnn-react-common": "10.1.0", - "@svgr/webpack": "^8.1.0", - "babel-loader": "10.0.0", - "babel-plugin-transform-react-remove-prop-types": "0.4.24", + "@rsbuild/core": "^1.6.3", + "@rsbuild/plugin-less": "^1.5.0", + "@rsbuild/plugin-react": "^1.4.2", + "@rsbuild/plugin-svgr": "^1.2.2", "create-react-class": "^15.7.0", - "css-loader": "^7.1.2", "eslint": "9.38.0", "eslint-plugin-react": "7.37.5", "eslint-webpack-plugin": "^5.0.2", - "file-loader": "6.2.0", "globals": "^16.4.0", "less": "4.4.2", - "less-loader": "12.3.0", "prop-types": "^15.8.1", - "raw-loader": "4.0.2", "react": "^16.14.0", "react-dom": "^16.14.0", "react-hot-loader": "4.13.1", @@ -38,14 +28,7 @@ "react-redux": "^8.1.1", "redux": "^4.2.1", "redux-immutable-state-invariant": "^2.1.0", - "redux-thunk": "^2.4.2", - "style-loader": "^4.0.0", - "typescript": "^5.9.3", - "url-loader": "4.1.1", - "webpack": "5.102.1", - "webpack-bundle-size-analyzer": "3.1.0", - "webpack-cli": "6.0.1", - "webpack-dev-server": "5.2.2" + "redux-thunk": "^2.4.2" }, "dependencies": { "dompurify": "^3.3.0", diff --git a/Dnn.AdminExperience/ClientSide/Security.Web/rsbuild.config.ts b/Dnn.AdminExperience/ClientSide/Security.Web/rsbuild.config.ts new file mode 100644 index 00000000000..fbc33c45779 --- /dev/null +++ b/Dnn.AdminExperience/ClientSide/Security.Web/rsbuild.config.ts @@ -0,0 +1,113 @@ +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { pluginLess } from "@rsbuild/plugin-less"; +import { pluginSvgr } from '@rsbuild/plugin-svgr'; +import path from "path"; +import { createRequire } from "module"; + +const requireModule = createRequire(__filename); +const webpackExternals = requireModule( + "@dnnsoftware/dnn-react-common/WebpackExternals" +); + +const resolveWebsitePath = () => { + try { + const settings = requireModule("../../../settings.local.json"); + if (settings?.WebsitePath) { + return settings.WebsitePath; + } + } catch { + // ignore missing local settings + } + return ""; +}; + +const websitePath = resolveWebsitePath(); +const isProduction = process.env.NODE_ENV === "production"; +const useWebsitePath = !isProduction && websitePath; + +export default defineConfig({ + source: { + entry: { + main: path.resolve(__dirname, "src/main.jsx"), + }, + }, + output: { + target: "web", + filenameHash: false, + cleanDistPath: false, + cssModules: { + auto: true, + localIdentName: "[local]", + }, + distPath: { + root: useWebsitePath + ? path.join( + websitePath, + "DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Security/" + ) + : "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Security/", + js: "scripts/bundles/", + css: "css/", + html: "", + }, + filename: { + js: "security-settings-bundle.js", + css: "Security.css", + }, + legalComments: "none", + }, + performance: { + chunkSplit: { + strategy: "all-in-one", + }, + }, + tools: { + rspack: { + externals: (data) => { + const { request } = data; + // Handle exact matches + if (webpackExternals[request]) { + return webpackExternals[request]; + } + // Handle React submodules (e.g., react/jsx-runtime, react-dom/client) + if (request?.startsWith('react/') || request?.startsWith('react-dom/')) { + const baseModule = request.split('/')[0]; + if (webpackExternals[baseModule]) { + // For submodules, return the base module + return webpackExternals[baseModule]; + } + } + return undefined; + }, + resolve: { + modules: [ + path.resolve(__dirname, "./src"), + path.resolve(__dirname, "./node_modules"), + path.resolve(__dirname, "../../../node_modules"), + ], + }, + }, + htmlPlugin: false, + }, + dev: { + writeToDisk: true, + hmr: false, + liveReload: false, + }, + plugins: [ + pluginReact({ + swcReactOptions: { + runtime: "classic", + }, + }), + pluginLess({ + lessLoaderOptions: { + lessOptions: { + javascriptEnabled: true, + }, + }, + }), + pluginSvgr(), + ], +}); diff --git a/Dnn.AdminExperience/ClientSide/Security.Web/src/components/ipFilters/index.jsx b/Dnn.AdminExperience/ClientSide/Security.Web/src/components/ipFilters/index.jsx index f284b9a375b..520574325ac 100644 --- a/Dnn.AdminExperience/ClientSide/Security.Web/src/components/ipFilters/index.jsx +++ b/Dnn.AdminExperience/ClientSide/Security.Web/src/components/ipFilters/index.jsx @@ -7,9 +7,9 @@ import IpFilterEditor from "./ipfilterEditor"; import util from "../../utils"; import resx from "../../resources"; import { SvgIcons } from "@dnnsoftware/dnn-react-common"; -import WarningIcon from "./../svg/error.svg"; +import WarningIcon from "./../svg/error.svg?react"; import styles from "./style.module.less"; - + let tableFields = []; @@ -84,7 +84,7 @@ class IpFiltersPanelBody extends Component { }); } - + renderedIpFilters() { let i = 0; return this.props.ipFilters.map((item, index) => { diff --git a/Dnn.AdminExperience/ClientSide/Security.Web/src/components/ipFilters/ipFilterRow/index.jsx b/Dnn.AdminExperience/ClientSide/Security.Web/src/components/ipFilters/ipFilterRow/index.jsx index 7991614c2aa..a95d11999ff 100644 --- a/Dnn.AdminExperience/ClientSide/Security.Web/src/components/ipFilters/ipFilterRow/index.jsx +++ b/Dnn.AdminExperience/ClientSide/Security.Web/src/components/ipFilters/ipFilterRow/index.jsx @@ -3,10 +3,10 @@ import PropTypes from "prop-types"; import { Collapsible } from "@dnnsoftware/dnn-react-common"; import "./style.less"; import resx from "../../../resources"; -import AllowIcon from "./../../svg/checkbox.svg"; -import DenyIcon from "./../../svg/cross_out.svg"; -import EditIcon from "./../../svg/edit.svg"; -import DeleteIcon from "./../../svg/trash.svg"; +import AllowIcon from "./../../svg/checkbox.svg?react"; +import DenyIcon from "./../../svg/cross_out.svg?react"; +import EditIcon from "./../../svg/edit.svg?react"; +import DeleteIcon from "./../../svg/trash.svg?react"; class IpFilterRow extends Component { constructor() { @@ -28,7 +28,7 @@ class IpFilterRow extends Component { } } - + getRuleTypeDisplay() { const {props} = this; if (props.id !== "add") { @@ -54,7 +54,7 @@ class IpFilterRow extends Component { } } - + render() { const {props} = this; let opened = (this.props.openId !== "" && this.props.id === this.props.openId); diff --git a/Dnn.AdminExperience/ClientSide/Security.Web/src/components/securityBulletins/index.jsx b/Dnn.AdminExperience/ClientSide/Security.Web/src/components/securityBulletins/index.jsx index 66bddfeffa8..d85a7047666 100644 --- a/Dnn.AdminExperience/ClientSide/Security.Web/src/components/securityBulletins/index.jsx +++ b/Dnn.AdminExperience/ClientSide/Security.Web/src/components/securityBulletins/index.jsx @@ -5,7 +5,7 @@ import { security as SecurityActions } from "../../actions"; import BulletinItemRow from "./bulletinItemRow"; import resx from "../../resources"; import styles from "./style.module.less"; -import WarningIcon from "./../svg/error.svg"; +import WarningIcon from "./../svg/error.svg?react"; class SecurityBulletinsPanelBody extends Component { constructor() { @@ -75,7 +75,7 @@ class SecurityBulletinsPanelBody extends Component { } } - + render() { const {props, state} = this; if (state.error) { diff --git a/Dnn.AdminExperience/ClientSide/Security.Web/webpack.config.js b/Dnn.AdminExperience/ClientSide/Security.Web/webpack.config.js deleted file mode 100644 index c9dc16159d5..00000000000 --- a/Dnn.AdminExperience/ClientSide/Security.Web/webpack.config.js +++ /dev/null @@ -1,108 +0,0 @@ -const webpack = require("webpack"); -const ESLintPlugin = require("eslint-webpack-plugin"); -const packageJson = require("./package.json"); -const path = require("path"); -const settings = require("../../../settings.local.json"); - -const webpackExternals = require("@dnnsoftware/dnn-react-common/WebpackExternals"); - -module.exports = (env, argv) => { - const isProduction = argv.mode === "production"; - return { - entry: "./src/main.jsx", - optimization: { - minimize: isProduction, - }, - output: { - path: - isProduction || settings.WebsitePath === "" - ? path.resolve( - "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Security/scripts/bundles/" - ) - : path.join( - settings.WebsitePath, - "DesktopModules\\Admin\\Dnn.PersonaBar\\Modules\\Dnn.Security\\scripts\\bundles\\" - ), - publicPath: isProduction ? "" : "http://localhost:8080/dist/", - filename: "security-settings-bundle.js", - }, - devServer: { - disableHostCheck: !isProduction, - }, - resolve: { - extensions: ["*", ".js", ".json", ".jsx", ".ts", ".tsx"], - modules: [ - path.resolve("./src"), // Look in src first - path.resolve("./node_modules"), // Try local node_modules - path.resolve("../../../node_modules"), // Last fallback to workspaces node_modules - ], - }, - module: { - rules: [ - { - test: /\.less$/, - use: [ - { - loader: "style-loader", // creates style nodes from JS strings - }, - { - loader: "css-loader", - options: { - importLoaders: 1, - sourceMap: true, - modules: { - auto: true, - mode: "global", - localIdentName: "[name]__[local]___[hash:base64:5]", - }, - esModule: false, - }, - }, - { - loader: "less-loader", // compiles Less to CSS - }, - ], - }, - { - test: /\.(js|jsx|ts|tsx)$/, - exclude: /node_modules/, - use: { - loader: "babel-loader", - options: { - presets: ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"], - }, - }, - }, - { - test: /\.(ttf|woff)$/, - use: ["url-loader?limit=8192"], - }, - { - test: /\.svg$/i, - issuer: /\.[jt]sx?$/, - use: ["@svgr/webpack"], - }, - ], - }, - externals: webpackExternals, - plugins: - [ - isProduction - ? new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - "process.env": { - NODE_ENV: JSON.stringify("production"), - }, - }) - : new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - }), - new webpack.SourceMapDevToolPlugin({ - filename: "security-settings-bundle.js.map", - append: "\n//# sourceMappingURL=/DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Security/scripts/bundles/security-settings-bundle.js.map", - }), - new ESLintPlugin({fix: true}), - ], - devtool: false, - }; -}; diff --git a/yarn.lock b/yarn.lock index e9da49adaf2..3b5003413fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4310,7 +4310,7 @@ __metadata: languageName: node linkType: hard -"@rsbuild/plugin-react@npm:^1.4.2": +"@rsbuild/plugin-react@npm:^1.1.0, @rsbuild/plugin-react@npm:^1.4.2": version: 1.4.2 resolution: "@rsbuild/plugin-react@npm:1.4.2" dependencies: @@ -4322,6 +4322,22 @@ __metadata: languageName: node linkType: hard +"@rsbuild/plugin-svgr@npm:^1.2.2": + version: 1.2.2 + resolution: "@rsbuild/plugin-svgr@npm:1.2.2" + dependencies: + "@rsbuild/plugin-react": "npm:^1.1.0" + "@svgr/core": "npm:8.1.0" + "@svgr/plugin-jsx": "npm:8.1.0" + "@svgr/plugin-svgo": "npm:8.1.0" + deepmerge: "npm:^4.3.1" + loader-utils: "npm:^3.3.1" + peerDependencies: + "@rsbuild/core": 1.x + checksum: 10/130cc98176dbb9048428f86f1122693be1973e4dc41648eed931f7a420ea80201c6c0bfcafdd98a176d010743def3de85d91699e18a5b6c28718dc1d1bae75eb + languageName: node + linkType: hard + "@rspack/binding-darwin-arm64@npm:1.6.6": version: 1.6.6 resolution: "@rspack/binding-darwin-arm64@npm:1.6.6" @@ -15151,6 +15167,13 @@ __metadata: languageName: node linkType: hard +"loader-utils@npm:^3.3.1": + version: 3.3.1 + resolution: "loader-utils@npm:3.3.1" + checksum: 10/3f994a948ded4248569773f065b1f6d7c95da059888c8429153e203f9bdadfb1691ca517f9eac6548a8af2fe5c724a8e09cbb79f665db4209426606a57ec7650 + languageName: node + linkType: hard + "localization@npm:^1.0.2": version: 1.0.2 resolution: "localization@npm:1.0.2" @@ -20146,29 +20169,20 @@ __metadata: version: 0.0.0-use.local resolution: "security-settings@workspace:Dnn.AdminExperience/ClientSide/Security.Web" dependencies: - "@babel/core": "npm:^7.28.4" - "@babel/plugin-proposal-object-rest-spread": "npm:^7.20.7" - "@babel/plugin-transform-react-jsx": "npm:^7.27.1" - "@babel/preset-env": "npm:^7.28.3" - "@babel/preset-react": "npm:^7.27.1" - "@babel/preset-typescript": "npm:^7.28.5" "@dnnsoftware/dnn-react-common": "npm:10.1.0" - "@svgr/webpack": "npm:^8.1.0" - babel-loader: "npm:10.0.0" - babel-plugin-transform-react-remove-prop-types: "npm:0.4.24" + "@rsbuild/core": "npm:^1.6.3" + "@rsbuild/plugin-less": "npm:^1.5.0" + "@rsbuild/plugin-react": "npm:^1.4.2" + "@rsbuild/plugin-svgr": "npm:^1.2.2" create-react-class: "npm:^15.7.0" - css-loader: "npm:^7.1.2" dompurify: "npm:^3.3.0" eslint: "npm:9.38.0" eslint-plugin-react: "npm:7.37.5" eslint-webpack-plugin: "npm:^5.0.2" - file-loader: "npm:6.2.0" globals: "npm:^16.4.0" html-react-parser: "npm:^5.2.10" less: "npm:4.4.2" - less-loader: "npm:12.3.0" prop-types: "npm:^15.8.1" - raw-loader: "npm:4.0.2" react: "npm:^16.14.0" react-dom: "npm:^16.14.0" react-hot-loader: "npm:4.13.1" @@ -20177,13 +20191,6 @@ __metadata: redux: "npm:^4.2.1" redux-immutable-state-invariant: "npm:^2.1.0" redux-thunk: "npm:^2.4.2" - style-loader: "npm:^4.0.0" - typescript: "npm:^5.9.3" - url-loader: "npm:4.1.1" - webpack: "npm:5.102.1" - webpack-bundle-size-analyzer: "npm:3.1.0" - webpack-cli: "npm:6.0.1" - webpack-dev-server: "npm:5.2.2" languageName: unknown linkType: soft From 221ea84564a43d0f6f476f58aa6d89d5282b9bda Mon Sep 17 00:00:00 2001 From: Peter Donker Date: Tue, 9 Dec 2025 17:44:51 +0100 Subject: [PATCH 5/6] Convert roles module to rsbuild --- .../ClientSide/Roles.Web/.babelrc | 18 --- .../ClientSide/Roles.Web/package.json | 32 ++--- .../ClientSide/Roles.Web/rsbuild.config.ts | 113 ++++++++++++++++++ .../src/components/roles/RoleRow/index.jsx | 4 +- .../roles/UsersInRole/UserRow/index.jsx | 2 +- .../ClientSide/Roles.Web/webpack.config.js | 105 ---------------- yarn.lock | 24 +--- 7 files changed, 128 insertions(+), 170 deletions(-) delete mode 100644 Dnn.AdminExperience/ClientSide/Roles.Web/.babelrc create mode 100644 Dnn.AdminExperience/ClientSide/Roles.Web/rsbuild.config.ts delete mode 100644 Dnn.AdminExperience/ClientSide/Roles.Web/webpack.config.js diff --git a/Dnn.AdminExperience/ClientSide/Roles.Web/.babelrc b/Dnn.AdminExperience/ClientSide/Roles.Web/.babelrc deleted file mode 100644 index ba562891416..00000000000 --- a/Dnn.AdminExperience/ClientSide/Roles.Web/.babelrc +++ /dev/null @@ -1,18 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-react" - ], - "plugins": [ - "@babel/plugin-transform-react-jsx", - "@babel/plugin-proposal-object-rest-spread", - "react-hot-loader/babel" - ], - "env": { - "production": { - "plugins": [ - "transform-react-remove-prop-types" - ] - } - } -} \ No newline at end of file diff --git a/Dnn.AdminExperience/ClientSide/Roles.Web/package.json b/Dnn.AdminExperience/ClientSide/Roles.Web/package.json index 489c525535a..0e26b1a20fa 100644 --- a/Dnn.AdminExperience/ClientSide/Roles.Web/package.json +++ b/Dnn.AdminExperience/ClientSide/Roles.Web/package.json @@ -3,48 +3,32 @@ "version": "10.1.0", "private": true, "scripts": { - "build": "set NODE_ENV=production&&webpack --mode production", - "debug": "set NODE_ENV=debug&&webpack --mode production", - "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch", + "build": "set NODE_ENV=production&&rsbuild build", + "debug": "set NODE_ENV=debug&&rsbuild build", + "watch": "set NODE_ENV=debug & rsbuild dev", "analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer", "lint": "eslint --fix" }, "devDependencies": { - "@babel/core": "^7.28.4", - "@babel/preset-env": "^7.28.3", - "@babel/preset-react": "^7.27.1", "@dnnsoftware/dnn-react-common": "10.1.0", - "@svgr/webpack": "^8.1.0", + "@rsbuild/core": "^1.6.3", + "@rsbuild/plugin-less": "^1.5.0", + "@rsbuild/plugin-react": "^1.4.2", + "@rsbuild/plugin-svgr": "^1.2.2", "array.prototype.find": "^2.2.3", "array.prototype.findindex": "^2.2.4", - "babel-loader": "^10.0.0", - "babel-plugin-transform-object-assign": "6.22.0", - "babel-plugin-transform-object-rest-spread": "6.26.0", - "babel-plugin-transform-react-remove-prop-types": "0.4.24", - "babel-polyfill": "6.26.0", "create-react-class": "^15.7.0", - "css-loader": "^7.1.2", "es6-object-assign": "^1.1.0", "eslint": "9.38.0", "eslint-plugin-react": "7.37.5", - "eslint-webpack-plugin": "^5.0.2", - "file-loader": "6.2.0", "globals": "^16.4.0", "less": "4.4.2", - "less-loader": "12.3.0", "prop-types": "^15.8.1", - "raw-loader": "^4.0.2", "react": "^16.14.0", "react-click-outside": "^3.0.1", "react-dom": "^16.14.0", "react-hot-loader": "4.13.1", - "style-loader": "4.0.0", - "throttle-debounce": "5.0.2", - "url-loader": "4.1.1", - "webpack": "5.102.1", - "webpack-bundle-size-analyzer": "3.1.0", - "webpack-cli": "6.0.1", - "webpack-dev-server": "5.2.2" + "throttle-debounce": "5.0.2" }, "dependencies": { "react-widgets": "^5.8.4" diff --git a/Dnn.AdminExperience/ClientSide/Roles.Web/rsbuild.config.ts b/Dnn.AdminExperience/ClientSide/Roles.Web/rsbuild.config.ts new file mode 100644 index 00000000000..37ab80e9830 --- /dev/null +++ b/Dnn.AdminExperience/ClientSide/Roles.Web/rsbuild.config.ts @@ -0,0 +1,113 @@ +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { pluginLess } from "@rsbuild/plugin-less"; +import { pluginSvgr } from '@rsbuild/plugin-svgr'; +import path from "path"; +import { createRequire } from "module"; + +const requireModule = createRequire(__filename); +const webpackExternals = requireModule( + "@dnnsoftware/dnn-react-common/WebpackExternals" +); + +const resolveWebsitePath = () => { + try { + const settings = requireModule("../../../settings.local.json"); + if (settings?.WebsitePath) { + return settings.WebsitePath; + } + } catch { + // ignore missing local settings + } + return ""; +}; + +const websitePath = resolveWebsitePath(); +const isProduction = process.env.NODE_ENV === "production"; +const useWebsitePath = !isProduction && websitePath; + +export default defineConfig({ + source: { + entry: { + main: path.resolve(__dirname, "src/main.jsx"), + }, + }, + output: { + target: "web", + filenameHash: false, + cleanDistPath: false, + cssModules: { + auto: true, + localIdentName: "[local]", + }, + distPath: { + root: useWebsitePath + ? path.join( + websitePath, + "DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Roles/" + ) + : "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Roles/", + js: "scripts/bundles/", + css: "css/", + html: "", + }, + filename: { + js: "roles-bundle.js", + css: "Roles.css", + }, + legalComments: "none", + }, + performance: { + chunkSplit: { + strategy: "all-in-one", + }, + }, + tools: { + rspack: { + externals: (data) => { + const { request } = data; + // Handle exact matches + if (webpackExternals[request]) { + return webpackExternals[request]; + } + // Handle React submodules (e.g., react/jsx-runtime, react-dom/client) + if (request?.startsWith('react/') || request?.startsWith('react-dom/')) { + const baseModule = request.split('/')[0]; + if (webpackExternals[baseModule]) { + // For submodules, return the base module + return webpackExternals[baseModule]; + } + } + return undefined; + }, + resolve: { + modules: [ + path.resolve(__dirname, "./src"), + path.resolve(__dirname, "./node_modules"), + path.resolve(__dirname, "../../../node_modules"), + ], + }, + }, + htmlPlugin: false, + }, + dev: { + writeToDisk: true, + hmr: false, + liveReload: false, + }, + plugins: [ + pluginReact({ + swcReactOptions: { + runtime: "classic", + }, + }), + pluginLess({ + lessLoaderOptions: { + lessOptions: { + javascriptEnabled: true, + }, + }, + }), + pluginSvgr(), + ], +}); diff --git a/Dnn.AdminExperience/ClientSide/Roles.Web/src/components/roles/RoleRow/index.jsx b/Dnn.AdminExperience/ClientSide/Roles.Web/src/components/roles/RoleRow/index.jsx index 452e4cb4747..0e241f6661d 100644 --- a/Dnn.AdminExperience/ClientSide/Roles.Web/src/components/roles/RoleRow/index.jsx +++ b/Dnn.AdminExperience/ClientSide/Roles.Web/src/components/roles/RoleRow/index.jsx @@ -4,7 +4,7 @@ import "./style.less"; import { Collapsible, GridCell, IconButton } from "@dnnsoftware/dnn-react-common"; import resx from "resources"; import util from "utils"; -import CheckIcon from "../../../img/common/checkmark.svg"; +import CheckIcon from "../../../img/common/checkmark.svg?react"; let canEdit = false; @@ -32,7 +32,7 @@ class RoleRow extends Component { document.removeEventListener("click", this.handleClick); this._isMounted = false; } - + handleClick(event) { // Note: this workaround is needed in IE. The remove event listener in the componentWillUnmount is called // before the handleClick handler is called, but in spite of that, the handleClick is executed. To avoid diff --git a/Dnn.AdminExperience/ClientSide/Roles.Web/src/components/roles/UsersInRole/UserRow/index.jsx b/Dnn.AdminExperience/ClientSide/Roles.Web/src/components/roles/UsersInRole/UserRow/index.jsx index c09c994de6c..1da5ce89249 100644 --- a/Dnn.AdminExperience/ClientSide/Roles.Web/src/components/roles/UsersInRole/UserRow/index.jsx +++ b/Dnn.AdminExperience/ClientSide/Roles.Web/src/components/roles/UsersInRole/UserRow/index.jsx @@ -6,7 +6,7 @@ import { GridCell, DatePicker, IconButton } from "@dnnsoftware/dnn-react-common import util from "../../../../utils"; import resx from "../../../../resources"; import { roleUsers as RoleUsersActions } from "../../../../actions"; -import XIcon from "../../../../img/common/x.svg"; +import XIcon from "../../../../img/common/x.svg?react"; class UserRow extends Component { diff --git a/Dnn.AdminExperience/ClientSide/Roles.Web/webpack.config.js b/Dnn.AdminExperience/ClientSide/Roles.Web/webpack.config.js deleted file mode 100644 index 0642ec1c330..00000000000 --- a/Dnn.AdminExperience/ClientSide/Roles.Web/webpack.config.js +++ /dev/null @@ -1,105 +0,0 @@ -const webpack = require("webpack"); -const ESLintPlugin = require("eslint-webpack-plugin"); -const packageJson = require("./package.json"); -const path = require("path"); -const settings = require("../../../settings.local.json"); - -module.exports = (env, argv) => { - const isProduction = argv.mode === "production"; - return { - entry: "./src/main.jsx", - optimization: { - minimize: isProduction, - }, - output: { - path: - isProduction || settings.WebsitePath === "" - ? path.resolve( - "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Roles/scripts/bundles/" - ) - : path.join( - settings.WebsitePath, - "DesktopModules\\Admin\\Dnn.PersonaBar\\Modules\\Dnn.Roles\\scripts\\bundles\\" - ), - filename: "roles-bundle.js", - publicPath: isProduction ? "" : "http://localhost:8080/dist/", - }, - devServer: { - disableHostCheck: !isProduction, - }, - module: { - rules: [ - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - use: ["babel-loader"], - }, - { - test: /\.(less|css)$/, - use: [ - { loader: "style-loader" }, - { - loader: "css-loader", - options: { - importLoaders: 1, - sourceMap: true, - modules: { - auto: true, - mode: "global", - localIdentName: "[name]__[local]___[hash:base64:5]", - }, - esModule: false, - }, - }, - { loader: "less-loader" }, - ], - }, - { test: /\.(ttf|woff)$/, use: ["url-loader?limit=8192"] }, - { test: /\.(gif|png)$/, use: ["url-loader?mimetype=image/png"] }, - { - test: /\.woff(2)?(\?v=[0-9].[0-9].[0-9])?$/, - use: ["url-loader?mimetype=application/font-woff"], - }, - { - test: /\.(ttf|eot|)(\?v=[0-9].[0-9].[0-9])?$/, - use: ["file-loader?name=[name].[ext]"], - }, - { - test: /\.svg$/i, - issuer: /\.[jt]sx?$/, - use: ["@svgr/webpack"], - }, - ], - }, - resolve: { - extensions: [".js", ".json", ".jsx"], - modules: [ - path.resolve("./src"), // Look in src first - path.resolve("./node_modules"), // Try local node_modules - path.resolve("../../../node_modules"), // Last fallback to workspaces node_modules - ], - }, - - externals: require("@dnnsoftware/dnn-react-common/WebpackExternals"), - - plugins: - [ - isProduction - ? new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - "process.env": { - NODE_ENV: JSON.stringify("production"), - }, - }) - : new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - }), - new webpack.SourceMapDevToolPlugin({ - filename: "roles-bundle.js.map", - append: "\n//# sourceMappingURL=/DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Roles/scripts/bundles/roles-bundle.js.map", - }), - new ESLintPlugin({fix: true}), - ], - devtool: false, - }; -}; diff --git a/yarn.lock b/yarn.lock index 3b5003413fa..5a240a4379a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19603,42 +19603,26 @@ __metadata: version: 0.0.0-use.local resolution: "roles@workspace:Dnn.AdminExperience/ClientSide/Roles.Web" dependencies: - "@babel/core": "npm:^7.28.4" - "@babel/preset-env": "npm:^7.28.3" - "@babel/preset-react": "npm:^7.27.1" "@dnnsoftware/dnn-react-common": "npm:10.1.0" - "@svgr/webpack": "npm:^8.1.0" + "@rsbuild/core": "npm:^1.6.3" + "@rsbuild/plugin-less": "npm:^1.5.0" + "@rsbuild/plugin-react": "npm:^1.4.2" + "@rsbuild/plugin-svgr": "npm:^1.2.2" array.prototype.find: "npm:^2.2.3" array.prototype.findindex: "npm:^2.2.4" - babel-loader: "npm:^10.0.0" - babel-plugin-transform-object-assign: "npm:6.22.0" - babel-plugin-transform-object-rest-spread: "npm:6.26.0" - babel-plugin-transform-react-remove-prop-types: "npm:0.4.24" - babel-polyfill: "npm:6.26.0" create-react-class: "npm:^15.7.0" - css-loader: "npm:^7.1.2" es6-object-assign: "npm:^1.1.0" eslint: "npm:9.38.0" eslint-plugin-react: "npm:7.37.5" - eslint-webpack-plugin: "npm:^5.0.2" - file-loader: "npm:6.2.0" globals: "npm:^16.4.0" less: "npm:4.4.2" - less-loader: "npm:12.3.0" prop-types: "npm:^15.8.1" - raw-loader: "npm:^4.0.2" react: "npm:^16.14.0" react-click-outside: "npm:^3.0.1" react-dom: "npm:^16.14.0" react-hot-loader: "npm:4.13.1" react-widgets: "npm:^5.8.4" - style-loader: "npm:4.0.0" throttle-debounce: "npm:5.0.2" - url-loader: "npm:4.1.1" - webpack: "npm:5.102.1" - webpack-bundle-size-analyzer: "npm:3.1.0" - webpack-cli: "npm:6.0.1" - webpack-dev-server: "npm:5.2.2" languageName: unknown linkType: soft From b77ab1e9f9ecdd4481c07d05b6186fcb25578bec Mon Sep 17 00:00:00 2001 From: Peter Donker Date: Tue, 9 Dec 2025 20:08:01 +0100 Subject: [PATCH 6/6] Migrate prompt module --- .../ClientSide/Prompt.Web/.babelrc | 10 - .../ClientSide/Prompt.Web/package.json | 37 +- .../ClientSide/Prompt.Web/rsbuild.config.ts | 113 +++++ .../Prompt.Web/src/components/Prompt.less | 449 +++++++++--------- .../ClientSide/Prompt.Web/webpack.config.js | 103 ---- yarn.lock | 91 +--- 6 files changed, 356 insertions(+), 447 deletions(-) delete mode 100644 Dnn.AdminExperience/ClientSide/Prompt.Web/.babelrc create mode 100644 Dnn.AdminExperience/ClientSide/Prompt.Web/rsbuild.config.ts delete mode 100644 Dnn.AdminExperience/ClientSide/Prompt.Web/webpack.config.js diff --git a/Dnn.AdminExperience/ClientSide/Prompt.Web/.babelrc b/Dnn.AdminExperience/ClientSide/Prompt.Web/.babelrc deleted file mode 100644 index 1af592d5fba..00000000000 --- a/Dnn.AdminExperience/ClientSide/Prompt.Web/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-react" - ], - "plugins": [ - "transform-object-assign", - "@babel/plugin-proposal-object-rest-spread" - ] -} \ No newline at end of file diff --git a/Dnn.AdminExperience/ClientSide/Prompt.Web/package.json b/Dnn.AdminExperience/ClientSide/Prompt.Web/package.json index 14983799e55..beef18c06bf 100644 --- a/Dnn.AdminExperience/ClientSide/Prompt.Web/package.json +++ b/Dnn.AdminExperience/ClientSide/Prompt.Web/package.json @@ -4,46 +4,30 @@ "description": "DNN Prompt", "private": true, "scripts": { - "build": "set NODE_ENV=production&&webpack --mode production", - "debug": "set NODE_ENV=debug&&webpack --mode production", - "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch", - "analyze": "set NODE_ENV=analyze&&webpack-dev-server -d --port 8100 --hot --inline --content-base dist/ --history-api-fallback", - "test": "jest", + "build": "set NODE_ENV=production&&rsbuild build", + "debug": "set NODE_ENV=debug&&rsbuild build", + "watch": "set NODE_ENV=debug & rsbuild dev", "lint": "eslint --fix" }, "devDependencies": { - "@babel/core": "^7.28.4", - "@babel/preset-env": "^7.28.3", - "@babel/preset-react": "^7.27.1", - "@babel/preset-typescript": "^7.28.5", "@dnnsoftware/dnn-react-common": "10.1.0", + "@rsbuild/core": "^1.6.3", + "@rsbuild/plugin-less": "^1.5.0", + "@rsbuild/plugin-react": "^1.4.2", + "@rsbuild/plugin-svgr": "^1.2.2", "array.prototype.find": "2.2.3", "array.prototype.findindex": "2.2.4", - "babel-eslint": "^10.1.0", - "babel-jest": "^30.2.0", - "babel-loader": "^10.0.0", - "babel-plugin-transform-object-assign": "6.22.0", - "babel-plugin-transform-object-rest-spread": "6.26.0", - "babel-plugin-transform-react-remove-prop-types": "0.4.24", - "babel-polyfill": "6.26.0", "create-react-class": "^15.7.0", - "css-loader": "^7.1.2", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.8", "es6-object-assign": "1.1.0", "eslint": "9.38.0", "eslint-plugin-react": "7.37.5", - "eslint-webpack-plugin": "^5.0.2", - "extract-text-webpack-plugin": "^3.0.2", - "file-loader": "6.2.0", "globals": "^16.4.0", - "i18n-webpack-plugin": "1.0.0", "jest": "^30.2.0", "less": "4.4.2", - "less-loader": "12.3.0", "localization": "^1.0.2", "prop-types": "^15.8.1", - "raw-loader": "4.0.2", "react": "^16.14.0", "react-click-outside": "^3.0.1", "react-dom": "^16.14.0", @@ -57,13 +41,8 @@ "redux-immutable-state-invariant": "2.1.0", "redux-mock-store": "^1.5.4", "redux-thunk": "2.4.2", - "style-loader": "^4.0.0", "throttle-debounce": "^5.0.2", - "typescript": "^5.9.3", - "url-loader": "4.1.1", - "webpack": "5.102.1", - "webpack-cli": "6.0.1", - "webpack-dev-server": "5.2.2" + "typescript": "^5.9.3" }, "dependencies": { "dompurify": "^3.3.0", diff --git a/Dnn.AdminExperience/ClientSide/Prompt.Web/rsbuild.config.ts b/Dnn.AdminExperience/ClientSide/Prompt.Web/rsbuild.config.ts new file mode 100644 index 00000000000..1fd17a361c7 --- /dev/null +++ b/Dnn.AdminExperience/ClientSide/Prompt.Web/rsbuild.config.ts @@ -0,0 +1,113 @@ +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { pluginLess } from "@rsbuild/plugin-less"; +import { pluginSvgr } from '@rsbuild/plugin-svgr'; +import path from "path"; +import { createRequire } from "module"; + +const requireModule = createRequire(__filename); +const webpackExternals = requireModule( + "@dnnsoftware/dnn-react-common/WebpackExternals" +); + +const resolveWebsitePath = () => { + try { + const settings = requireModule("../../../settings.local.json"); + if (settings?.WebsitePath) { + return settings.WebsitePath; + } + } catch { + // ignore missing local settings + } + return ""; +}; + +const websitePath = resolveWebsitePath(); +const isProduction = process.env.NODE_ENV === "production"; +const useWebsitePath = !isProduction && websitePath; + +export default defineConfig({ + source: { + entry: { + main: path.resolve(__dirname, "src/main.jsx"), + }, + }, + output: { + target: "web", + filenameHash: false, + cleanDistPath: false, + cssModules: { + auto: true, + localIdentName: "[local]", + }, + distPath: { + root: useWebsitePath + ? path.join( + websitePath, + "DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Prompt/" + ) + : "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Prompt/", + js: "scripts/bundles/", + css: "css/", + html: "", + }, + filename: { + js: "prompt-bundle.js", + css: "Prompt.css", + }, + legalComments: "none", + }, + performance: { + chunkSplit: { + strategy: "all-in-one", + }, + }, + tools: { + rspack: { + externals: (data) => { + const { request } = data; + // Handle exact matches + if (webpackExternals[request]) { + return webpackExternals[request]; + } + // Handle React submodules (e.g., react/jsx-runtime, react-dom/client) + if (request?.startsWith('react/') || request?.startsWith('react-dom/')) { + const baseModule = request.split('/')[0]; + if (webpackExternals[baseModule]) { + // For submodules, return the base module + return webpackExternals[baseModule]; + } + } + return undefined; + }, + resolve: { + modules: [ + path.resolve(__dirname, "./src"), + path.resolve(__dirname, "./node_modules"), + path.resolve(__dirname, "../../../node_modules"), + ], + }, + }, + htmlPlugin: false, + }, + dev: { + writeToDisk: true, + hmr: false, + liveReload: false, + }, + plugins: [ + pluginReact({ + swcReactOptions: { + runtime: "classic", + }, + }), + pluginLess({ + lessLoaderOptions: { + lessOptions: { + javascriptEnabled: true, + }, + }, + }), + pluginSvgr(), + ], +}); diff --git a/Dnn.AdminExperience/ClientSide/Prompt.Web/src/components/Prompt.less b/Dnn.AdminExperience/ClientSide/Prompt.Web/src/components/Prompt.less index 2e765b522e9..1e38f786fa8 100644 --- a/Dnn.AdminExperience/ClientSide/Prompt.Web/src/components/Prompt.less +++ b/Dnn.AdminExperience/ClientSide/Prompt.Web/src/components/Prompt.less @@ -1,233 +1,242 @@ @import "~@dnnsoftware/dnn-react-common/styles/index"; #dnnPrompt-container { - .dnnPrompt-app { - &.personaBar-mainContainer { - * { - font-size: 16px !important; - box-sizing: border-box; - } - - .wrapper { - display: block; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - background: @blackPearl; - border: solid 1px @alabaster; - box-shadow: 0 0 3px @thunder, 0 0 8px @thunder inset; + .dnnPrompt-app { + &.personaBar-mainContainer { + * { + font-size: 16px !important; + box-sizing: border-box; + } - .dnn-prompt { - background: @blackPearl; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - padding: 5px; - padding-bottom: 1em; - margin: 2px; - /* keep status bar from covering prompt input */ - overflow: auto; - z-index: 2000; - width: ~"calc(100% - 25px)"; - box-shadow: none; - } + .wrapper { + display: block; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + background: @blackPearl; + border: solid 1px @alabaster; + box-shadow: 0 0 3px @thunder, 0 0 8px @thunder inset; - .dnn-prompt-output { - & > div { - margin:10px 0; - } - .dnn-prompt-cmd { - /*pending*/ - } - } - .dnn-prompt-input-wrapper { - position: relative; - } - .dnn-prompt-input { - display: inline-block; - width: 98%; - background: transparent; - border: none; - color: #8AE234; - margin: 0; - padding: 0; - outline: none; - /* Get rid of Chrome focus border */ - position: absolute; - left: 17px; + .dnn-prompt { + * { + font: 16px/16px Lucida Console, Consolas, Courier New !important; + } - &.hidden-text { - opacity: 0; - } - } - .dnn-prompt-input-wrapper { - &::before { - content: ">"; - color: #8AE234; - margin-left: 3px; - display: inline-block; - } + background: @blackPearl; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + padding: 5px; + padding-bottom: 1em; + margin: 2px; + /* keep status bar from covering prompt input */ + overflow: auto; + z-index: 2000; + width: ~"calc(100% - 25px)"; + box-shadow: none; + } - &.hidden-cursor { - &::before { - content: " "; - } - } - } + .dnn-prompt-output { + & > div { + margin: 10px 0; + } + .dnn-prompt-cmd { + /*pending*/ + } + } + .dnn-prompt-input-wrapper { + position: relative; + } + .dnn-prompt-input { + display: inline-block; + width: 98%; + background: transparent; + border: none; + color: #8ae234; + margin: 0; + padding: 0; + outline: none; + /* Get rid of Chrome focus border */ + position: absolute; + left: 17px; - /* remove MS Edge clear button */ - .dnn-prompt-input::-ms-clear { - display: none; - } - /* Output text - ----------------------------------*/ - .dnn-prompt-cmd { - color: #AAA; - } - .dnn-prompt-error { - margin-top: 10px; - color: #F00; - } - .dnn-prompt-ok { - color: #0FF; - } - /* Table */ - .dnn-prompt-tbl { - color: #8AE234; - } - .dnn-prompt-tbl thead th { - color: #03ade0; - border-bottom: 1px dashed; - } - .dnn-prompt-tbl td, .dnn-prompt-tbl th { - padding: 2px 5px; - margin: 2px 5px; - } - .dnn-prompt-tbl td:first-child, .dnn-prompt-tbl th:first-child { - padding-left: 0; - margin-left: 0; - } - .dnn-prompt-lbl { - color: #FFF; - } - .dnn-prompt-val { - color: #D3D7CF; - } - a.dnn-prompt-cmd-insert, a.dnn-prompt-cmd-insert:link, a.dnn-prompt-cmd-insert:visited, a.dnn-prompt-cmd-insert:active { - color: #03ade0; - } - /* Busy/Loading Indicator */ - .dnn-prompt-busy { - width: 24px; - height: 24px; - border-radius: 50%; - border-top: 2px solid #03ade0; - border-right: 2px solid transparent; - margin: 4px 0; - animation: spin .6s linear infinite; - } - @keyframes spin { - to { - transform: rotate(360deg); - } - } - /* Persona Bar Styling for Help */ - section.dnn-prompt-inline-help { - color: #AAA; - margin-top: 0.8em !important; - } - section.dnn-prompt-inline-help em { - font-style: italic !important; - font-size: 1em !important; - } - section.dnn-prompt-inline-help strong { - font-weight: bold !important; - font-size: 1em !important; - color: #DDD; - } - section.dnn-prompt-inline-help .text-danger { - color: red; - } - section.dnn-prompt-inline-help h4 { - color: #FFF; - margin: 15px auto 10px auto !important; - font-size: 1.3em !important; - } - section.dnn-prompt-inline-help h3 { - color: #03ade0 !important; - background-color: azure; - font-size: 1.5em !important; - margin: 10px auto !important; - padding: .5em; - } - section.dnn-prompt-inline-help p { - margin: 10px auto; - line-height: 1.2em !important; - } - section.dnn-prompt-inline-help p.lead { - font-size: 1.1em !important; - } - section.dnn-prompt-inline-help blockquote { - line-height: 1.2em !important; - border: 1px solid rgba(0, 255, 0, .4); - border-left: 10px solid rgba(0, 255, 0, .4); - padding: 10px; - font-size: 0.85em !important; - } - section.dnn-prompt-inline-help .mono { - color: rgb(255, 140, 0); - } - section.dnn-prompt-inline-help li { - margin-left: 2.2em; - margin-bottom: .6em; - } - section.dnn-prompt-inline-help code.block { - display: inline-block; - padding: 8px; - border: 1px solid rgba(255, 140, 0, .1); - background: rgba(255, 140, 0, .08); - color: rgb(255, 140, 0); - margin: 5px auto; - } - section.dnn-prompt-inline-help table.table { - // border: 1px solid rgba(255, 255, 255, .4); - } - section.dnn-prompt-inline-help table thead th { - background: rgba(255, 255, 255, .4); - color: #FFF; - padding: 8px; - } - section.dnn-prompt-inline-help table.table td { - padding: 5px; - } - section.dnn-prompt-inline-help table.table tr td:first-child { - white-space: nowrap; - } - section.dnn-prompt-inline-help table.command-result-tbl { - margin-top: 10px; - margin-bottom: 10px; - } - section.dnn-prompt-inline-help table.command-result-tbl td { - font-size: .85em !important; - } - section.dnn-prompt-inline-help table.command-result-tbl tr td:first-child { - white-space: nowrap; - } - section.dnn-prompt-inline-help table tr.divider td { - text-transform: uppercase; - font-size: 1.3em !important; - text-align: center; - padding: 1em !important; - color: #DDD; - } + &.hidden-text { + opacity: 0; + } + } + .dnn-prompt-input-wrapper { + &::before { + content: ">"; + color: #8ae234; + margin-left: 3px; + display: inline-block; + } + &.hidden-cursor { + &::before { + content: " "; + } + } + } - } /* .wrapper */ + /* remove MS Edge clear button */ + .dnn-prompt-input::-ms-clear { + display: none; + } + /* Output text + ----------------------------------*/ + .dnn-prompt-cmd { + color: #aaa; + } + .dnn-prompt-error { + margin-top: 10px; + color: #f00; + } + .dnn-prompt-ok { + color: #0ff; + } + /* Table */ + .dnn-prompt-tbl { + color: #8ae234; + } + .dnn-prompt-tbl thead th { + color: #03ade0; + border-bottom: 1px dashed; + } + .dnn-prompt-tbl td, + .dnn-prompt-tbl th { + padding: 2px 5px; + margin: 2px 5px; + } + .dnn-prompt-tbl td:first-child, + .dnn-prompt-tbl th:first-child { + padding-left: 0; + margin-left: 0; + } + .dnn-prompt-lbl { + color: #fff; + } + .dnn-prompt-val { + color: #d3d7cf; + } + a.dnn-prompt-cmd-insert, + a.dnn-prompt-cmd-insert:link, + a.dnn-prompt-cmd-insert:visited, + a.dnn-prompt-cmd-insert:active { + color: #03ade0; + } + /* Busy/Loading Indicator */ + .dnn-prompt-busy { + width: 24px; + height: 24px; + border-radius: 50%; + border-top: 2px solid #03ade0; + border-right: 2px solid transparent; + margin: 4px 0; + animation: spin 0.6s linear infinite; } + @keyframes spin { + to { + transform: rotate(360deg); + } + } + /* Persona Bar Styling for Help */ + section.dnn-prompt-inline-help { + color: #aaa; + margin-top: 0.8em !important; + } + section.dnn-prompt-inline-help em { + font-style: italic !important; + font-size: 1em !important; + } + section.dnn-prompt-inline-help strong { + font-weight: bold !important; + font-size: 1em !important; + color: #ddd; + } + section.dnn-prompt-inline-help .text-danger { + color: red; + } + section.dnn-prompt-inline-help h4 { + color: #fff; + margin: 15px auto 10px auto !important; + font-size: 1.3em !important; + } + section.dnn-prompt-inline-help h3 { + color: #03ade0 !important; + background-color: azure; + font-size: 1.5em !important; + margin: 10px auto !important; + padding: 0.5em; + } + section.dnn-prompt-inline-help p { + margin: 10px auto; + line-height: 1.2em !important; + } + section.dnn-prompt-inline-help p.lead { + font-size: 1.1em !important; + } + section.dnn-prompt-inline-help blockquote { + line-height: 1.2em !important; + border: 1px solid rgba(0, 255, 0, 0.4); + border-left: 10px solid rgba(0, 255, 0, 0.4); + padding: 10px; + font-size: 0.85em !important; + } + section.dnn-prompt-inline-help .mono { + color: rgb(255, 140, 0); + } + section.dnn-prompt-inline-help li { + margin-left: 2.2em; + margin-bottom: 0.6em; + } + section.dnn-prompt-inline-help code.block { + display: inline-block; + padding: 8px; + border: 1px solid rgba(255, 140, 0, 0.1); + background: rgba(255, 140, 0, 0.08); + color: rgb(255, 140, 0); + margin: 5px auto; + } + section.dnn-prompt-inline-help table thead th { + background: rgba(255, 255, 255, 0.4); + color: #fff; + padding: 8px; + } + section.dnn-prompt-inline-help table.table td { + padding: 5px; + } + section.dnn-prompt-inline-help table.table tr td:first-child { + white-space: nowrap; + } + section.dnn-prompt-inline-help table.command-result-tbl { + margin-top: 10px; + margin-bottom: 10px; + } + section.dnn-prompt-inline-help table.command-result-tbl td { + font-size: 0.85em !important; + } + section.dnn-prompt-inline-help + table.command-result-tbl + tr + td:first-child { + white-space: nowrap; + } + section.dnn-prompt-inline-help table tr.divider td { + text-transform: uppercase; + font-size: 1.3em !important; + text-align: center; + padding: 1em !important; + color: #ddd; + } + } /* .wrapper */ } + } } -#showsite { margin-right: 25px; } \ No newline at end of file +#showsite { + margin-right: 25px; +} diff --git a/Dnn.AdminExperience/ClientSide/Prompt.Web/webpack.config.js b/Dnn.AdminExperience/ClientSide/Prompt.Web/webpack.config.js deleted file mode 100644 index 29dc6739c93..00000000000 --- a/Dnn.AdminExperience/ClientSide/Prompt.Web/webpack.config.js +++ /dev/null @@ -1,103 +0,0 @@ -const webpack = require("webpack"); -const ESLintPlugin = require("eslint-webpack-plugin"); -const packageJson = require("./package.json"); -const path = require("path"); -const settings = require("../../../settings.local.json"); - -module.exports = (env, argv) => { - const isProduction = argv.mode === "production"; - return { - entry: "./src/main.jsx", - optimization: { - minimize: isProduction, - }, - output: { - path: - isProduction || settings.WebsitePath === "" - ? path.resolve( - "../../Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.Prompt/scripts/bundles/" - ) - : path.join( - settings.WebsitePath, - "DesktopModules\\Admin\\Dnn.PersonaBar\\Modules\\Dnn.Prompt\\scripts\\bundles\\" - ), - publicPath: isProduction ? "" : "http://localhost:8100/dist/", - filename: "prompt-bundle.js", - }, - devServer: { - disableHostCheck: !isProduction, - }, - resolve: { - extensions: ["*", ".js", ".json", ".jsx", ".ts", ".tsx"], - modules: [ - path.resolve("./src"), // Look in src first - path.resolve("./node_modules"), // Try local node_modules - path.resolve("../../../node_modules"), // Last fallback to workspaces node_modules - ], - }, - module: { - rules: [ - { - test: /\.less$/, - use: [ - { - loader: "style-loader", // creates style nodes from JS strings - }, - { - loader: "css-loader", - options: { - importLoaders: 1, - sourceMap: true, - modules: { - auto: true, - mode: "global", - localIdentName: "[name]__[local]___[hash:base64:5]", - }, - esModule: false, - }, - }, - { - loader: "less-loader", // compiles Less to CSS - }, - ], - }, - { - test: /\.(js|jsx|ts|tsx)$/, - exclude: /node_modules/, - use: { - loader: "babel-loader", - options: { - presets: ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"], - }, - }, - }, - { - test: /\.(ttf|woff)$/, - use: { - loader: "url-loader?limit=8192", - }, - }, - ], - }, - externals: require("@dnnsoftware/dnn-react-common/WebpackExternals"), - plugins: - [ - isProduction - ? new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - "process.env": { - NODE_ENV: JSON.stringify("production"), - }, - }) - : new webpack.DefinePlugin({ - VERSION: JSON.stringify(packageJson.version), - }), - new webpack.SourceMapDevToolPlugin({ - filename: "prompt-bundle.js.map", - append: "\r\n//# sourceMappingURL=/DesktopModules/Admin/Dnn.PersonaBar/Modules/Dnn.Prompt/scripts/bundles/prompt-bundle.js.map", - }), - new ESLintPlugin({fix: true}), - ], - devtool: false, - }; -}; diff --git a/yarn.lock b/yarn.lock index 5a240a4379a..b56e994dde8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6691,18 +6691,6 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^5.0.0": - version: 5.5.2 - resolution: "ajv@npm:5.5.2" - dependencies: - co: "npm:^4.6.0" - fast-deep-equal: "npm:^1.0.0" - fast-json-stable-stringify: "npm:^2.0.0" - json-schema-traverse: "npm:^0.3.0" - checksum: 10/944526c6f61e859d2d0e0f54c9a6c046b207410ddde601dc5d0bb65d20fb116cc493a604d02e5a354f6112813d679e46058c876639c8802674b6de8e7dadb31c - languageName: node - linkType: hard - "ajv@npm:^6.1.0, ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" @@ -7175,7 +7163,7 @@ __metadata: languageName: node linkType: hard -"async@npm:^2.4.1, async@npm:^2.6.0": +"async@npm:^2.6.0": version: 2.6.4 resolution: "async@npm:2.6.4" dependencies: @@ -11719,27 +11707,6 @@ __metadata: languageName: unknown linkType: soft -"extract-text-webpack-plugin@npm:^3.0.2": - version: 3.0.2 - resolution: "extract-text-webpack-plugin@npm:3.0.2" - dependencies: - async: "npm:^2.4.1" - loader-utils: "npm:^1.1.0" - schema-utils: "npm:^0.3.0" - webpack-sources: "npm:^1.0.1" - peerDependencies: - webpack: ^3.1.0 - checksum: 10/973a53579cedf4a73bc5af9b6c00fc28a97e946983b16ff8a0ad25c0d2db97cfd41be4e72306c8322d4276931d281bf91cce78dbd6f6d3c2e6f0be8ebfafdd01 - languageName: node - linkType: hard - -"fast-deep-equal@npm:^1.0.0": - version: 1.1.0 - resolution: "fast-deep-equal@npm:1.1.0" - checksum: 10/69b4c9534d9805f13a341aa72f69641d0b9ae3cc8beb25c64e68a257241c7bb34370266db27ae4fc3c4da0518448c01a5f587a096a211471c86a38facd9a1486 - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -14680,13 +14647,6 @@ __metadata: languageName: node linkType: hard -"json-schema-traverse@npm:^0.3.0": - version: 0.3.1 - resolution: "json-schema-traverse@npm:0.3.1" - checksum: 10/a685c36222023471c25c86cddcff506306ecb8f8941922fd356008419889c41c38e1c16d661d5499d0a561b34f417693e9bb9212ba2b2b2f8f8a345a49e4ec1a - languageName: node - linkType: hard - "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" @@ -15145,17 +15105,6 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^1.1.0": - version: 1.4.2 - resolution: "loader-utils@npm:1.4.2" - dependencies: - big.js: "npm:^5.2.2" - emojis-list: "npm:^3.0.0" - json5: "npm:^1.0.1" - checksum: 10/2ae94cc88ad9cf2991e322b9ddf547cff80cf6fc0f9c77546b258c5ed9f77b0827f64c2625cb0baa06432f1f441bb4744c9ab1e1412ee6f8e97d31f8e9c730d6 - languageName: node - linkType: hard - "loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.3": version: 2.0.4 resolution: "loader-utils@npm:2.0.4" @@ -18086,40 +18035,26 @@ __metadata: version: 0.0.0-use.local resolution: "prompt@workspace:Dnn.AdminExperience/ClientSide/Prompt.Web" dependencies: - "@babel/core": "npm:^7.28.4" - "@babel/preset-env": "npm:^7.28.3" - "@babel/preset-react": "npm:^7.27.1" - "@babel/preset-typescript": "npm:^7.28.5" "@dnnsoftware/dnn-react-common": "npm:10.1.0" + "@rsbuild/core": "npm:^1.6.3" + "@rsbuild/plugin-less": "npm:^1.5.0" + "@rsbuild/plugin-react": "npm:^1.4.2" + "@rsbuild/plugin-svgr": "npm:^1.2.2" array.prototype.find: "npm:2.2.3" array.prototype.findindex: "npm:2.2.4" - babel-eslint: "npm:^10.1.0" - babel-jest: "npm:^30.2.0" - babel-loader: "npm:^10.0.0" - babel-plugin-transform-object-assign: "npm:6.22.0" - babel-plugin-transform-object-rest-spread: "npm:6.26.0" - babel-plugin-transform-react-remove-prop-types: "npm:0.4.24" - babel-polyfill: "npm:6.26.0" create-react-class: "npm:^15.7.0" - css-loader: "npm:^7.1.2" dompurify: "npm:^3.3.0" enzyme: "npm:^3.11.0" enzyme-adapter-react-16: "npm:^1.15.8" es6-object-assign: "npm:1.1.0" eslint: "npm:9.38.0" eslint-plugin-react: "npm:7.37.5" - eslint-webpack-plugin: "npm:^5.0.2" - extract-text-webpack-plugin: "npm:^3.0.2" - file-loader: "npm:6.2.0" globals: "npm:^16.4.0" html-react-parser: "npm:^5.2.7" - i18n-webpack-plugin: "npm:1.0.0" jest: "npm:^30.2.0" less: "npm:4.4.2" - less-loader: "npm:12.3.0" localization: "npm:^1.0.2" prop-types: "npm:^15.8.1" - raw-loader: "npm:4.0.2" react: "npm:^16.14.0" react-click-outside: "npm:^3.0.1" react-dom: "npm:^16.14.0" @@ -18133,13 +18068,8 @@ __metadata: redux-immutable-state-invariant: "npm:2.1.0" redux-mock-store: "npm:^1.5.4" redux-thunk: "npm:2.4.2" - style-loader: "npm:^4.0.0" throttle-debounce: "npm:^5.0.2" typescript: "npm:^5.9.3" - url-loader: "npm:4.1.1" - webpack: "npm:5.102.1" - webpack-cli: "npm:6.0.1" - webpack-dev-server: "npm:5.2.2" languageName: unknown linkType: soft @@ -20099,15 +20029,6 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^0.3.0": - version: 0.3.0 - resolution: "schema-utils@npm:0.3.0" - dependencies: - ajv: "npm:^5.0.0" - checksum: 10/441fa4bd4900afb19eb9da1d8d6271056b71ce3d8b1b73bbece791de1d4c90ac7e97ffc9787607aa53611aaf2996711af7c18ba8669f06b084b218cab1e701e3 - languageName: node - linkType: hard - "schema-utils@npm:^1.0.0": version: 1.0.0 resolution: "schema-utils@npm:1.0.0" @@ -23117,7 +23038,7 @@ __metadata: languageName: node linkType: hard -"webpack-sources@npm:^1.0.1, webpack-sources@npm:^1.4.0": +"webpack-sources@npm:^1.4.0": version: 1.4.3 resolution: "webpack-sources@npm:1.4.3" dependencies: