[ReactJS] ist das Javascript-Framework von Facebook. Es ist Open Source.

!!!Webpack
Webpack ist ein sogenannter Transpiler, der Javascript Code parsed und für das Web, dem Browser oder zum Debugging packt.

[ReactJS] kommt mit einer internen Konfiguration von Webpack. Sobald man etwas ändern möchte, braucht man eine "webpack.config.js" im Projekt.

{{{
	module: {
		rules: [{
			test: /\.jsx$/i,
			include: path.resolve(__dirname, "src"),
			use: {
				loader: "babel-loader",
				options: {
					presets: [
						"@babel/preset-env",
						["@babel/preset-react", {"runtime": "automatic"}]
					]
				}
			}
		}, {
			test: /\.ts$/i,
			include: path.resolve(__dirname, "src"),
			use: {
				loader: "babel-loader",
				options: {
					presets: [
						"@babel/preset-env",
						"@babel/typescript"
					]
				}
			}
		}, {
			test: /\.js$/i,
			include: path.resolve(__dirname, "src"),
			use: {
				loader: "babel-loader",
				options: {
					presets: [
						"@babel/preset-env"
					]
				}
			}
		}, {
			test: /\.css$/i,
			include: [
				path.resolve(__dirname, "src"),
				path.resolve(__dirname, "node_modules")
			],
			use: ["style-loader", "css-loader", "postcss-loader"]
		}, {
			test: /\.(png|svg|jpe?g|gif|woff2?|ttf|eot)$/,
			use: "file-loader"
		}]
	},
	resolve: {
		extensions: [".js", ".jsx", ".css", ".ts"]
	}
}}}

!!!Typescript Komponenten .tsx
[ReactJS] kann auch mit Typescript kombiniert werden. Dazu muss in der webpack.config.js folgende Regel für den Babel-Loader konfiguriert werden:

{{{
        {
            test: /\.(jsx|tsx)$/,
            exclude: /node_modules/,
			use: {
				loader: "babel-loader",
				options: {
					presets: [
						"@babel/preset-env",
						["@babel/preset-react", {"runtime": "automatic"}],
                        "@babel/preset-typescript"
					]
				}
			}
        }
}}}

Zusätzlich muss in der TS-Config angegeben werden, dass es sich um Extended Javascript handelt:

{{{
{
	"compilerOptions": {
		"jsx": "react-jsx"
	}
}
}}}

!!!Typescript nur Typen generieren
Der Typescript-Compiler hat eine eigene Konfiguration:

{{{
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve"
  },
  "include": [
    "src"
  ]
}
}}}

!!!Tailwind-Config
Tailwind ist ein Style-Framework, welches versucht ohne Stylesheets auszukommen. Für [ReactJS] wird meist eine Konfiguration benötigt:

{{{
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"],
  theme: {
    extend: {},
  },
  plugins: [],
}
}}}

!!!Typescript mit Decorators
Von Typescript sind sehr viele Varianten mit sogenannten Decorators (Annotationen etc.) im Umlauf. Folgende Konfiguration unterstützt einige davon.

webpack.config.js:
{{{
            use: {
                loader: "babel-loader",
                options: {
                    presets: [
                        "@babel/preset-env",
                        "@babel/preset-typescript",
                        ["@babel/preset-react", {runtime: "automatic"}]
                    ],
                    plugins: [
                        "@babel/syntax-dynamic-import",
                        ["@babel/plugin-proposal-decorators", {version: "2023-05", decoratorAutoAccessors: true}],
                        "@babel/plugin-proposal-object-rest-spread",
                        ["@babel/plugin-transform-class-properties"]
                    ]
                }
}}}

tsconfig.json:

{{{
{
	"compilerOptions": {
		"jsx": "react-jsx",
		"experimentalDecorators": true,
		"emitDecoratorMetadata": true,
		"target": "ESNext",
		"moduleResolution": "node"
	}
}
}}}

__Hinweis:__ Viele Konfigurationen sind inkonsistent. Es ist schwierig herauszufinden, welche Kombinationen dieser Plugins mit welchen Parametern zusammen arbeiten.

!!!LitJS Adapter
Folgender Adapter vereinfacht das Einbinden von LitJS-Komponenten:

{{{
import {createComponent} from "@lit/react";
import React from "react";

export function lit(tag) {
	return createComponent({
		tagName: customElements.getName(tag),
		elementClass: tag,
		react: React
	});
}
export default function Lit({tag, children, ...props}) {
	const Element = lit(tag);
	return <Element {...props}>{children}</Element>;
}
}}}

Oder in Typescript:

{{{
import {ReactWebComponent, createComponent} from "@lit/react";
import React from "react";

declare var customElements: any;

type Constructor<T> = {
    new (): T;
};

type LitProps<I> = {
	tag: Constructor<I>,
	children: React.ReactNode,
	rest: any[]
};

type AnyComponent = (props: any) => React.ReactElement;

export function lit<I extends HTMLElement>(tag: Constructor<I>): ReactWebComponent<I> {
	return createComponent({
		tagName: customElements.getName(tag),
		elementClass: tag,
		react: React
	});
}
export default function Lit<I extends HTMLElement>({tag, children, ...rest}: LitProps<I>): React.ReactElement {
	const Element: AnyComponent = lit(tag) as AnyComponent;
	return <Element {...rest}>{children}</Element>;
}
}}}