Consolidate redundant frontend modules

Pushed-by: Konstantin Schaper<konstantin.schaper@cloudogu.com>
Committed-by: Konstantin Schaper<konstantin.schaper@cloudogu.com>
Co-authored-by: Konstantin Schaper<konstantin.schaper@cloudogu.com>
This commit is contained in:
Konstantin Schaper
2023-10-13 08:15:27 +02:00
parent 92b24a76ec
commit 0bfc5183cc
35 changed files with 666 additions and 765 deletions

View File

@@ -141,7 +141,7 @@ class RunTask extends DefaultTask {
private Closure<Void> createFrontend() {
def frontend = project.tasks.create('boot-frontend', NodeTask) {
script = new File(project.rootProject.projectDir, 'scm-ui/ui-scripts/bin/turbo-runner.js')
script = new File(project.rootProject.projectDir, 'scripts/turbo-runner.js')
args = ['run', 'serve', '--filter=@scm-manager/ui-webapp']
environment = [
'NODE_ENV': 'development',

View File

@@ -14,8 +14,8 @@
"typecheck": "turbo run typecheck --filter=\"@scm-manager/ui-*\"",
"lint": "turbo run lint --filter=\"@scm-manager/ui-*\"",
"predeploy": "turbo run build --filter=\"@scm-manager/ui-*\"",
"deploy": "ui-scripts publish",
"set-version": "ui-scripts version"
"deploy": "node ./scripts/publish.js",
"set-version": "node ./scripts/version.js"
},
"dependencies": {
"@scm-manager/eslint-config": "2.17.0"

View File

@@ -33,3 +33,4 @@
"extends": "@scm-manager/eslint-config"
}
}

View File

@@ -1,39 +0,0 @@
{
"name": "@scm-manager/ui-modules",
"version": "2.47.1-SNAPSHOT",
"private": true,
"main": "build/index.js",
"module": "build/index.mjs",
"types": "build/index.d.ts",
"files": [
"build"
],
"scripts": {
"build": "tsup ./src/index.ts -d build --format esm,cjs --dts",
"typecheck": "tsc",
"lint": "eslint src",
"test": "jest --passWithNoTests"
},
"devDependencies": {
"@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/jest-preset": "^2.13.0",
"@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/eslint-config": "^2.17.0",
"tsup": "^5.12.6"
},
"babel": {
"presets": [
"@scm-manager/babel-preset"
]
},
"jest": {
"preset": "@scm-manager/jest-preset"
},
"prettier": "@scm-manager/prettier-config",
"eslintConfig": {
"extends": "@scm-manager/eslint-config"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -1,6 +0,0 @@
{
"extends": "@scm-manager/tsconfig",
"include": [
"./src"
]
}

View File

@@ -1,66 +0,0 @@
#!/usr/bin/env node
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* eslint-disable no-console */
const { spawnSync } = require("child_process");
const commands = ["postinstall"];
const args = process.argv.slice(2);
const commandIndex = args.findIndex(arg => {
return commands.includes(arg);
});
const command = commandIndex === -1 ? args[0] : args[commandIndex];
const nodeArgs = commandIndex > 0 ? args.slice(0, commandIndex) : [];
if (commands.includes(command)) {
const result = spawnSync(
"node",
nodeArgs.concat(require.resolve("../src/commands/" + command)).concat(args.slice(commandIndex + 1)),
{ stdio: "inherit" }
);
if (result.signal) {
if (result.signal === "SIGKILL") {
console.log(
"The build failed because the process exited too early. " +
"This probably means the system ran out of memory or someone called " +
"`kill -9` on the process."
);
} else if (result.signal === "SIGTERM") {
console.log(
"The build failed because the process exited too early. " +
"Someone might have called `kill` or `killall`, or the system could " +
"be shutting down."
);
}
process.exit(1);
}
process.exit(result.status);
} else {
console.log(`Unknown script "${command}".`);
console.log("Perhaps you need to update ui-plugins?");
}

View File

@@ -1,10 +1,8 @@
{
"name": "@scm-manager/ui-plugins",
"description": "Defines the versions of SCM-Manager plugin dependencies provided by the core webapp. Exclusively used by the postinstall command of @scm-manager/plugin-scripts.",
"version": "2.47.1-SNAPSHOT",
"license": "MIT",
"bin": {
"ui-plugins": "./bin/ui-plugins.js"
},
"dependencies": {
"react": "17",
"react-dom": "17",
@@ -33,7 +31,6 @@
"@scm-manager/plugin-scripts": "^1.2.2",
"@scm-manager/prettier-config": "^2.10.1",
"@scm-manager/tsconfig": "^2.13.0",
"@scm-manager/ui-scripts": "2.47.1-SNAPSHOT",
"@scm-manager/ui-tests": "2.47.1-SNAPSHOT",
"@scm-manager/ui-types": "2.47.1-SNAPSHOT",
"@types/classnames": "^2.2.9",

View File

@@ -1,72 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* eslint-disable no-console */
const path = require("path");
const fs = require("fs");
const { spawnSync } = require("child_process");
const packageJsonPath = path.join(process.cwd(), "package.json");
const packageJSON = JSON.parse(fs.readFileSync(packageJsonPath, "UTF-8"));
const reference = require("../../package.json");
const sync = (left, right, key) => {
if (!right[key]) {
right[key] = {};
}
let changed = false;
const keys = Object.keys(left[key]);
keys.forEach(name => {
if (right[key][name] !== left[key][name]) {
console.log(name, "has changed from", right[key][name], "to", left[key][name]);
right[key][name] = left[key][name];
changed = true;
}
});
return changed;
};
const update = () => {
let dep = sync(reference, packageJSON, "dependencies");
let devDep = sync(reference, packageJSON, "devDependencies");
return dep || devDep;
};
if (update()) {
console.log("dependencies changed, install new dependencies");
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJSON, null, " "), { encoding: "UTF-8" });
const result = spawnSync("yarn", ["install"], { stdio: "inherit" });
if (result.error) {
console.log("could not start yarn command:", result.error);
process.exit(2);
} else if (result.status !== 0) {
console.log("yarn process ends with status code:", result.status);
process.exit(3);
}
}

View File

@@ -1,14 +0,0 @@
{
"name": "@scm-manager/ui-polyfill",
"version": "2.47.1-SNAPSHOT",
"description": "Polyfills for SCM-Manager UI",
"main": "src/index.js",
"author": "Sebastian Sdorra <sebastian.sdorra@cloudogu.com>",
"license": "MIT",
"private": true,
"prettier": "@scm-manager/prettier-config",
"dependencies": {
"@babel/polyfill": "^7.6.0",
"whatwg-fetch": "^3.0.0"
}
}

View File

@@ -1,25 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import "@babel/polyfill";
import "whatwg-fetch";

View File

@@ -1,56 +0,0 @@
#!/usr/bin/env node
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
const fs = require("fs");
const path = require("path");
const commandDir = path.join(__dirname, "../src/commands");
const commands = fs
.readdirSync(commandDir)
.map(script => {
if (script.endsWith(".js")) {
return script.replace(".js", "");
}
return undefined;
})
.filter(cmd => !!cmd);
const args = process.argv.slice(2);
const commandIndex = args.findIndex(arg => {
return commands.includes(arg);
});
const commandName = commandIndex === -1 ? args[0] : args[commandIndex];
if (!commandName) {
console.log(`Use plugin-scripts [${commands.join(", ")}]`);
} else if (commands.includes(commandName)) {
// eslint-disable-next-line
const command = require(path.join(commandDir, `${commandName}.js`));
command(args.slice(commandIndex + 1));
} else {
console.log(`Unknown script "${commandName}".`);
console.log("Perhaps you need to update plugin-scripts?");
}

View File

@@ -1,47 +0,0 @@
{
"name": "@scm-manager/ui-scripts",
"version": "2.47.1-SNAPSHOT",
"description": "Build scripts for SCM-Manager",
"main": "src/index.js",
"author": "Sebastian Sdorra <sebastian.sdorra@cloudogu.com>",
"license": "MIT",
"private": false,
"bin": {
"ui-scripts": "./bin/ui-scripts.js"
},
"dependencies": {
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.0",
"file-loader": "^6.2.0",
"mini-css-extract-plugin": "^2.4.3",
"mustache": "^3.1.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"react-refresh": "^0.14.0",
"sass": "^1.43.4",
"sass-loader": "^12.3.0",
"script-loader": "^0.7.2",
"style-loader": "^3.3.1",
"webpack": "^5.60.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0",
"postcss": "^8.4.12",
"postcss-loader": "^6.2.1",
"autoprefixer": "^10.4.4"
},
"devDependencies": {
"@scm-manager/babel-preset": "^2.13.1",
"@scm-manager/eslint-config": "^2.17.0",
"@scm-manager/prettier-config": "^2.10.1",
"webpack-bundle-analyzer": "^4.5.0"
},
"eslintConfig": {
"extends": "@scm-manager/eslint-config",
"rules": {
"no-console": "off"
}
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -1,45 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
const yarn = require("../yarn");
const versions = require("../versions");
module.exports = args => {
if (args.length < 1) {
console.log("usage ui-scripts publish <version>");
process.exit(1);
}
const version = args[0];
const index = version.indexOf("-SNAPSHOT");
if (index > 0) {
const snapshotVersion = `${version.substring(0, index)}-${versions.createSnapshotVersion()}`;
console.log(`publish snapshot release ${snapshotVersion}`);
yarn.version(snapshotVersion);
yarn.publish(snapshotVersion);
yarn.version(version);
} else {
// ?? not sure
yarn.publish(version);
}
};

View File

@@ -1,38 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
const webpack = require("webpack");
const createPluginConfig = require("../createPluginConfig");
module.exports = () => {
const config = createPluginConfig("development");
const compiler = webpack(config);
compiler.watch({}, (err, stats) => {
console.log(
stats.toString({
colors: true
})
);
});
};

View File

@@ -1,104 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
const path = require("path");
const fs = require("fs");
const root = process.cwd();
const packageJsonPath = path.join(root, "package.json");
const packageJSON = JSON.parse(fs.readFileSync(packageJsonPath, { encoding: "UTF-8" }));
let { name } = packageJSON;
const orgaIndex = name.indexOf("/");
if (orgaIndex > 0) {
name = name.substring(orgaIndex + 1);
}
module.exports = function (mode) {
return {
context: root,
entry: {
[name]: [path.resolve(__dirname, "webpack-public-path.js"), packageJSON.main || "src/main/js/index.js"],
},
mode,
stats: "minimal",
devtool: "source-map",
target: "web",
node: {
fs: "empty",
net: "empty",
tls: "empty",
},
externals: [
"react",
"react-dom",
"react-i18next",
"react-router-dom",
"styled-components",
"@scm-manager/ui-types",
"@scm-manager/ui-extensions",
"@scm-manager/ui-components",
"@scm-manager/ui-forms",
"@scm-manager/ui-buttons",
"@scm-manager/ui-overlays",
"classnames",
"query-string",
"redux",
"react-redux",
/^@scm-manager\/scm-.*-plugin$/i,
],
module: {
rules: [
{
test: /\.(js|ts|jsx|tsx)$/i,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@scm-manager/babel-preset"],
},
},
},
{
test: /\.(css|scss|sass)$/i,
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.(png|svg|jpg|gif|woff2?|eot|ttf)$/,
use: ["file-loader"],
},
],
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx", ".css", ".scss", ".json"],
},
output: {
path: path.join(root, "target", `${name}-${packageJSON.version}`, "webapp", "assets"),
filename: "[name].bundle.js",
chunkFilename: `${name}.[name].chunk.js`,
library: name,
libraryTarget: "amd",
},
};
};

View File

@@ -7,7 +7,6 @@
"@scm-manager/ui-components": "2.47.1-SNAPSHOT",
"@scm-manager/ui-api": "2.47.1-SNAPSHOT",
"@scm-manager/ui-extensions": "2.47.1-SNAPSHOT",
"@scm-manager/ui-modules": "2.47.1-SNAPSHOT",
"@scm-manager/ui-syntaxhighlighting": "2.47.1-SNAPSHOT",
"@scm-manager/ui-text": "2.47.1-SNAPSHOT",
"@scm-manager/ui-shortcuts": "2.47.1-SNAPSHOT",
@@ -37,8 +36,8 @@
"scripts": {
"test": "jest",
"lint": "eslint src",
"serve": "ui-scripts serve development",
"build": "webpack-cli --mode=production --config=../ui-scripts/src/webpack.config.js"
"serve": "node ./webpack/serve.js development",
"build": "webpack-cli --mode=production --config=./webpack/webpack.config.js"
},
"devDependencies": {
"@scm-manager/eslint-config": "^2.17.0",
@@ -56,7 +55,26 @@
"@types/systemjs": "^0.20.6",
"@types/ua-parser-js": "^0.7.36",
"fetch-mock": "^7.5.1",
"react-test-renderer": "^17.0.1"
"react-test-renderer": "^17.0.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
"webpack-bundle-analyzer": "^4.5.0",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.0",
"file-loader": "^6.2.0",
"mini-css-extract-plugin": "^2.4.3",
"mustache": "^3.1.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"react-refresh": "^0.14.0",
"sass": "^1.43.4",
"sass-loader": "^12.3.0",
"script-loader": "^0.7.2",
"style-loader": "^3.3.1",
"webpack": "^5.60.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0",
"postcss": "^8.4.12",
"postcss-loader": "^6.2.1",
"autoprefixer": "^10.4.4"
},
"babel": {
"presets": [
@@ -74,3 +92,4 @@
"access": "public"
}
}

View File

@@ -128,28 +128,21 @@ export const define = (name: string, dependencies: string[], fn: (...args: unkno
};
/**
* Asynchronously loads and executes a given resource bundle.
*
* If a module name is supplied, the bundle is expected to contain a single (AMD)[https://github.com/amdjs/amdjs-api/blob/master/AMD.md]
* module matching the provided module name.
*
* The promise will only resolve once the bundle loaded and, if it is a module,
* all dependencies are resolved and the module executed.
* As amd modules are loaded asynchronously using the global {@link define} function,
* we need to register a callback for the loader to notify us when the bundle has been loaded and executed.
* This has to be done **BEFORE** the bundle's javascript is loaded.
*/
export const load = (resource: string, moduleName?: string) =>
new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = resource;
export const registerModuleLoadingCallback = (
moduleName: string,
resolve: (value: unknown) => void,
reject: (reason?: unknown) => void
) => (bundleLoaderPromises[moduleName] = { resolve, reject });
if (moduleName) {
bundleLoaderPromises[moduleName] = { resolve, reject };
} else {
script.onload = resolve;
// This module has a side effect and is required to be imported unconditionally into the application at all times.
declare global {
interface Window {
define: typeof define;
}
}
script.onerror = reject;
const body = document.querySelector("body");
body?.appendChild(script);
body?.removeChild(script);
});
window.define = define;

View File

@@ -21,20 +21,32 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
const webpack = require("webpack");
const createPluginConfig = require("../createPluginConfig");
module.exports = () => {
const config = createPluginConfig("production");
import { registerModuleLoadingCallback } from "./define";
webpack(config, (err, stats) => {
console.log(
stats.toString({
colors: true
})
);
if (err || stats.hasErrors()) {
process.exit(1);
/**
* Asynchronously loads and executes a given resource bundle.
*
* If a module name is supplied, the bundle is expected to contain a single (AMD)[https://github.com/amdjs/amdjs-api/blob/master/AMD.md]
* module matching the provided module name.
*
* The promise will only resolve once the bundle loaded and, if it is a module,
* all dependencies are resolved and the module executed.
*/
export default (resource: string, moduleName?: string) =>
new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = resource;
if (moduleName) {
registerModuleLoadingCallback(moduleName, resolve, reject);
} else {
script.onload = resolve;
}
script.onerror = reject;
const body = document.querySelector("body");
body?.appendChild(script);
body?.removeChild(script);
});
};

View File

@@ -22,7 +22,7 @@
* SOFTWARE.
*/
import { define, defineLazy, defineStatic, load } from "@scm-manager/ui-modules";
import { defineLazy, defineStatic } from "./define";
import * as React from "react";
import * as ReactDOM from "react-dom";
@@ -41,13 +41,7 @@ import * as UIOverlays from "@scm-manager/ui-overlays";
import * as UILayout from "@scm-manager/ui-layout";
import * as UIApi from "@scm-manager/ui-api";
declare global {
interface Window {
define: typeof define;
}
}
window.define = define;
// This module has side effects and is required to be imported unconditionally into the application at all times.
defineStatic("react", React);
defineStatic("react-dom", ReactDOM);
@@ -67,7 +61,5 @@ defineStatic("@scm-manager/ui-layout", UILayout);
defineStatic("@scm-manager/ui-api", UIApi);
// redux is deprecated in favor of ui-api
defineLazy("redux", () => import("@scm-manager/ui-legacy").then(legacy => legacy.Redux));
defineLazy("react-redux", () => import("@scm-manager/ui-legacy").then(legacy => legacy.ReactRedux));
export default load;
defineLazy("redux", () => import("@scm-manager/ui-legacy").then((legacy) => legacy.Redux));
defineLazy("react-redux", () => import("@scm-manager/ui-legacy").then((legacy) => legacy.ReactRedux));

View File

@@ -25,7 +25,7 @@ import React, { ReactNode } from "react";
import classNames from "classnames";
import styled from "styled-components";
import { apiClient, ErrorBoundary, ErrorNotification, Icon, Loading } from "@scm-manager/ui-components";
import loadBundle from "./loadBundle";
import loadBundle from "../_modules/loadBundle";
import { ExtensionPoint } from "@scm-manager/ui-extensions";
const isMainModuleBundle = (bundlePath: string, pluginName: string) => bundlePath.endsWith(`${pluginName}.bundle.js`);

View File

@@ -38,6 +38,9 @@ import "./tokenExpired";
import { ApiProvider } from "@scm-manager/ui-api";
import { ShortcutDocsContextProvider } from "@scm-manager/ui-shortcuts";
// Makes sure that the global `define` function is registered and all provided modules are included in the final bundle at all times
import "./_modules/provided-modules";
binder.bind<extensionPoints.ChangesetDescriptionTokens>("changeset.description.tokens", ChangesetShortLink);
const root = document.getElementById("root");

View File

@@ -24,23 +24,22 @@
const Webpack = require("webpack");
const WebpackDevServer = require("webpack-dev-server");
const webpackConfig = require("../webpack.config");
const webpackConfig = require("./webpack.config");
module.exports = () => {
const compiler = Webpack(webpackConfig);
const devServerConfig = webpackConfig[0].devServer;
const server = new WebpackDevServer(devServerConfig, compiler);
const compiler = Webpack(webpackConfig);
const devServerConfig = webpackConfig[0].devServer;
const server = new WebpackDevServer(devServerConfig, compiler);
server.startCallback(() => {
server.startCallback(() => {
console.log(`Starting server on http://localhost:${devServerConfig.port}`);
});
});
// if we could access the parent id of our current process
// we start watching it, because a changing parent id means
// that the parent process has died.
// On linux our process does not receive any signal if our parent dies,
// e.g.: ctrl+c in gradle
if (process.ppid) {
// if we could access the parent id of our current process
// we start watching it, because a changing parent id means
// that the parent process has died.
// On linux our process does not receive any signal if our parent dies,
// e.g.: ctrl+c in gradle
if (process.ppid) {
const { ppid } = process;
setInterval(() => {
if (ppid !== process.ppid) {
@@ -48,5 +47,4 @@ module.exports = () => {
process.exit();
}
}, 500);
}
};
}

View File

@@ -30,7 +30,7 @@ const createIndexMiddleware = require("./middleware/IndexMiddleware");
const createContextPathMiddleware = require("./middleware/ContextPathMiddleware");
const isDevelopment = process.env.NODE_ENV === "development";
const root = path.resolve(process.cwd(), "..");
const root = path.resolve(__dirname, "..", "..");
const babelPlugins = [];
const webpackPlugins = [];
@@ -67,7 +67,7 @@ const base = {
context: root,
target: "web",
resolveLoader: {
modules: [path.join(__dirname, "..", "node_modules"), "node_modules"],
modules: [path.join(__dirname, "..", "..", "..", "node_modules"), "node_modules"],
extensions: [".js", ".json"],
mainFields: ["loader", "main"],
},
@@ -81,7 +81,7 @@ module.exports = [
path.resolve(__dirname, "webpack-public-path.js"),
// enable async/await
"regenerator-runtime/runtime",
"./ui-webapp/src/index.tsx"
"./ui-webapp/src/index.tsx",
],
},
devtool: "eval-cheap-module-source-map",
@@ -205,6 +205,22 @@ module.exports = [
entry: themes,
module: {
rules: [
{
test: /\.(ttf|eot|svg|png|jpg|gif|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: "file-loader",
},
],
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
},
],
},
{
test: /\.(css|scss|sass)$/i,
use: [
@@ -232,14 +248,4 @@ module.exports = [
filename: "ui-theme-[name].bundle.js",
},
},
{
...base,
entry: {
polyfills: "./ui-polyfill/src/index.js",
},
output: {
path: path.resolve(root, "build", "webapp", "assets"),
filename: "[name].bundle.js",
},
},
];

View File

@@ -39,11 +39,11 @@ const yarn = (args, cwd) => {
}
};
const version = v => {
const version = (v) => {
yarn(["version", "--no-git-tag-version", "--new-version", v]);
};
const publish = v => {
const publish = (v) => {
yarn(["publish", "--new-version", v]);
};
@@ -54,7 +54,7 @@ const findWorkspaces = () => {
const updateDependencies = (workspaces, dependencies, v) => {
if (dependencies) {
Object.keys(dependencies).forEach(dep => {
Object.keys(dependencies).forEach((dep) => {
if (workspaces[dep]) {
dependencies[dep] = v;
}
@@ -62,9 +62,9 @@ const updateDependencies = (workspaces, dependencies, v) => {
}
};
const workspaceVersion = v => {
const workspaceVersion = (v) => {
const workspaces = findWorkspaces();
Object.keys(workspaces).forEach(name => {
Object.keys(workspaces).forEach((name) => {
const workspace = workspaces[name];
const packageJsonPath = path.join(process.cwd(), workspace.location, "package.json");
@@ -79,23 +79,23 @@ const workspaceVersion = v => {
});
};
const forEachModule = fn => {
const forEachModule = (fn) => {
const workspaces = findWorkspaces();
Object.keys(workspaces).forEach(name => {
Object.keys(workspaces).forEach((name) => {
const workspace = workspaces[name];
const cwd = path.join(process.cwd(), workspace.location);
const packageJson = JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), { encoding: "utf8" }));
fn(packageJson, cwd)
fn(packageJson, cwd);
});
};
const workspacePublish = v => {
const workspacePublish = (v) => {
forEachModule((module, cwd) => {
if (!module.private) {
console.log(`publish module ${module.name}`)
yarn(["publish", "--new-version", v], cwd)
console.log(`publish module ${module.name}`);
yarn(["publish", "--new-version", v], cwd);
} else {
console.log(`skip private module ${module.name}`)
console.log(`skip private module ${module.name}`);
}
});
};
@@ -105,5 +105,5 @@ module.exports = {
publish,
yarn,
workspaceVersion,
workspacePublish
workspacePublish,
};

View File

@@ -21,10 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
const yarn = require("../yarn");
const versions = require("../versions");
const yarn = require("./lib/yarn");
const versions = require("./lib/versions");
module.exports = args => {
module.exports = (args) => {
if (args.length < 1) {
console.log("usage ui-scripts publish <version>");
process.exit(1);

View File

@@ -22,6 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// eslint-disable-next-line import/no-extraneous-dependencies
const { generateBinPath } = require("turbo/node-platform");
const { spawn } = require("child_process");

View File

@@ -22,9 +22,9 @@
* SOFTWARE.
*/
const yarn = require("../yarn");
const yarn = require("./lib/yarn");
module.exports = args => {
module.exports = (args) => {
if (args.length < 1) {
console.log("usage ui-scripts version <new-version>");
process.exit(1);

659
yarn.lock

File diff suppressed because it is too large Load Diff