Plugins
Plugins sind eine Möglichkeit, den K3 durch Programmierung zu erweitern. Beachten Sie, derzeit sind Plugins als
Plugin im K3 anlegen
Ein Plugin tragen Sie in den Optionen eines Konfigurators unter Plugins ein. Es wird dann beim Start des Konfigurators geladen. Dazu können Sie 2 verschiedene URLs angeben:
- die eigentliche URL muss vom Nutzer des Konfigurators aus erreichbar sein, das Plugin wird von dort geladen.
- die Development URL können Sie nutzen, während Sie das Plugin entwickeln. Sie wird typischerweise auf localhost zeigen, dann wird das Plugin aus Ihrer Umgebung geladen.
Ausserdem müssen Sie ausser Titel und Beschreibung die Felder Name und Modul befüllen. Die Inhalte dieser Felder legen Sie während der Entwicklung fest:
Plugin erzeugen
Ein Plugin ist ein JavaScript/TypeScript-Projekt in Vite:
npm create vite@latest
Folgen Sie den Anweisungen, dann cd
in das neue Verzeichnis.
Der Plugin Mechanismus basiert auf vite-plugin-federation, also wird das installiert:
pnpm install @originjs/vite-plugin-federation --save-dev
Ausserdem im Normalfall:
pnpm install react @react-three/drei @react-three/fiber
Vite Konfiguration
Jetzt kann das Plugin in vite.config.ts
genutzt werden:
export default defineConfig({
plugins: [
...,
federation({
name: 'k3-plugin',
filename: 'remoteEntry.js',
// Modules to expose
exposes: {
'./Plugin': './src/Plugin.tsx',
},
shared: ['react','react-dom', "@react-three/drei", "@react-three/fiber", "three", "three-stdlib"]
})
],
...
});
Hier wird folgendes festgelegt:
- Der name, der beim Anlagen des Plugins im K3 angegeben wird.
- Der filename ist immer
remoteEntry.js
, die Datei wird beim Bauen des Plugins erzeugt. - exposes ist eine Liste von Modulen, die exportiert werden. Ein Modul besteht aus:
- dem Namen, der beim Anlagen des Plugins im K3 angegeben wird.
- dem Namen der Datei, die das Modul implementiert.
- Unter shared wird angegeben, welche Bibliotheken nicht im Plugin deployed, sondern vom K3 genutzt werden sollen.
Plugin Deklaration
Plugin.tsx
kann folgendermaßen aussehen:
import { dynamicModel } from "./DynamicModel";
export default {
dynamicModels: [dynamicModel],
};
Es enthält einen default export, der ein Objekt exportiert. Derzeit wird nur ein Attribute des Objektes berücksichtigt, dynamicModels. Darin wird eine Array von Descriptoren für dynamische Modelle erwartet.
Es werden später weitere Extension Points hinzukommen.
Model-Descriptor
Ein dynamisches Modell wird durch einen solchen Descriptor beschrieben:
export const dynamicModel = {
type: "modelPlugin",
label: "Modell aus dem Plugin",
disabledForAR: false,
component: ExampleModel,
propsDialog: {
basic: { type: "basic" },
radius: {},
segmentCount: {},
jewel: { type: "model", label: "Das Juwelen Model" },
},
defaultProps: {
width: { expression: "1" },
height: { expression: "1" },
depth: { expression: "1" },
radius: { expression: "1" },
segmentCount: { expression: "1" },
jewel: [],
},
materials: ["surface"],
repositionApplicator: null,
screenshot: null,
};
die Einträge bedeuten:
- type: Eindeutige Kennung für dieses Modell
- label: Anzeigetext im Modell-Dialog
- disabledForAR: Bestimmt, ob das Modell bei AR mit exportiert werden soll
- component: Die React-Three-Fiber-Komponente, die das Modell implementiert
- propsDialog: Definiert den Einstellungsdialog für das Modell und seine Properties.
- type:
- basic: fragt die üblichen 3D Properties ab (Position, Rotation, Skalierung)
- model: Eine (Mehrfach-)Auswahl von Modellen
- expression (default): Eine Berechnung mit Markmalwerten
- label: Anzeigename
- type:
- defaultProps: Für jede Property der Default-Wert
- materials: Namen von verwendeten Materialien, die im K3 ersetzt werden können.
- repositionApplicator: derzeit nicht unterstützt
- screenshot: Ein Bild im Modell-Dialog
Model-Komponente
Das eigentliche dynamische Modell ist eine normale React-Three-Fiber Komponente. Sie erhält alle im Descriptor definierten Properties.
const ExampleModel = (props: any) => {
const z = 0; // -4
return (
<group scale={[props.width, props.height, props.depth]}>
{/* <PrimaryJuwel position={[0, 5, z]} />
<SecondaryJuwels position={[0, 5, z]} /> */}
<Ring position={[0, 0, z]} radius={props.radius} />
</group>
);
};
Ein Plugin entwickeln.
Das Plugin muss, um die Module Federation zu erlauben, gebaut werden.
Hot Module Reload ist nicht möglich.
Am bequemsten ist es, das Plugin automatisch bei jeder Änderung bauen zu lassen.
npm run build --watch
Das gebaute Plugin kann man dann am einfachsten über den Vite Development Server ausliefern.
Dazu trägt man das folgende Script in der package.json
ein:
"scripts": {
...,
"serve": "vite preview --port 5001 --strictPort"
},
und ruft es dann so auf:
npm run serve
Das Plugin ist nun unter http://localhost:5001/assets/remoteEntry.js
erreichbar.